diff --git a/install/Makefile b/install/Makefile index 9bde02cf..644e4a35 100644 --- a/install/Makefile +++ b/install/Makefile @@ -21,4 +21,4 @@ update-versions: echo "Updated main.go with latest versions" put-back: - mv main.go.bak main.go \ No newline at end of file + mv main.go.bak main.go diff --git a/install/config/config.yml b/install/config/config.yml index 8665b07f..db6b2b87 100644 --- a/install/config/config.yml +++ b/install/config/config.yml @@ -4,7 +4,6 @@ app: dashboard_url: "https://{{.DashboardDomain}}" log_level: "info" - save_logs: false domains: domain1: @@ -12,40 +11,17 @@ domains: cert_resolver: "letsencrypt" server: - external_port: 3000 - internal_port: 3001 - next_port: 3002 - internal_hostname: "pangolin" - session_cookie_name: "p_session_token" - resource_access_token_param: "p_token" - resource_access_token_headers: - id: "P-Access-Token-Id" - token: "P-Access-Token" - resource_session_request_param: "p_session_request" - secret: {{.Secret}} + secret: "{{.Secret}}" cors: origins: ["https://{{.DashboardDomain}}"] methods: ["GET", "POST", "PUT", "DELETE", "PATCH"] allowed_headers: ["X-CSRF-Token", "Content-Type"] credentials: false -traefik: - cert_resolver: "letsencrypt" - http_entrypoint: "web" - https_entrypoint: "websecure" - gerbil: start_port: 51820 base_endpoint: "{{.DashboardDomain}}" - use_subdomain: false - block_size: 24 - site_block_size: 30 - subnet_group: 100.89.137.0/20 -rate_limits: - global: - window_minutes: 1 - max_requests: 500 {{if .EnableEmail}} email: smtp_host: "{{.EmailSMTPHost}}" @@ -57,7 +33,7 @@ email: flags: require_email_verification: {{.EnableEmail}} - disable_signup_without_invite: {{.DisableSignupWithoutInvite}} - disable_user_create_org: {{.DisableUserCreateOrg}} + disable_signup_without_invite: true + disable_user_create_org: false allow_raw_resources: true allow_base_domain_resources: true diff --git a/install/main.go b/install/main.go index 5af3cbf7..f4ce8704 100644 --- a/install/main.go +++ b/install/main.go @@ -24,9 +24,9 @@ import ( // DO NOT EDIT THIS FUNCTION; IT MATCHED BY REGEX IN CICD func loadVersions(config *Config) { - config.PangolinVersion = "replaceme" - config.GerbilVersion = "replaceme" - config.BadgerVersion = "replaceme" + config.PangolinVersion = "1.5.1" + config.GerbilVersion = "1.0.0" + config.BadgerVersion = "v1.2.0" } //go:embed config/* @@ -39,8 +39,6 @@ type Config struct { BaseDomain string DashboardDomain string LetsEncryptEmail string - DisableSignupWithoutInvite bool - DisableUserCreateOrg bool EnableEmail bool EmailSMTPHost string EmailSMTPPort int @@ -72,15 +70,15 @@ func main() { } var config Config - + // check if there is already a config file if _, err := os.Stat("config/config.yml"); err != nil { config = collectUserInput(reader) - + loadVersions(&config) config.DoCrowdsecInstall = false config.Secret = generateRandomSecretKey() - + if err := createConfigFiles(config); err != nil { fmt.Printf("Error creating config files: %v\n", err) os.Exit(1) @@ -234,14 +232,9 @@ func collectUserInput(reader *bufio.Reader) Config { config.LetsEncryptEmail = readString(reader, "Enter email for Let's Encrypt certificates", "") config.InstallGerbil = readBool(reader, "Do you want to use Gerbil to allow tunneled connections", true) - // Security settings - fmt.Println("\n=== Security Settings ===") - config.DisableSignupWithoutInvite = readBool(reader, "Disable signup without invite", true) - config.DisableUserCreateOrg = readBool(reader, "Disable users from creating organizations", false) - // Email configuration fmt.Println("\n=== Email Configuration ===") - config.EnableEmail = readBool(reader, "Enable email functionality", false) + config.EnableEmail = readBool(reader, "Enable email functionality (SMTP)", false) if config.EnableEmail { config.EmailSMTPHost = readString(reader, "Enter SMTP host", "") @@ -353,7 +346,7 @@ func installDocker() error { return fmt.Errorf("failed to detect Linux distribution: %v", err) } osRelease := string(output) - + // Detect system architecture archCmd := exec.Command("uname", "-m") archOutput, err := archCmd.Output() @@ -361,7 +354,7 @@ func installDocker() error { return fmt.Errorf("failed to detect system architecture: %v", err) } arch := strings.TrimSpace(string(archOutput)) - + // Map architecture to Docker's architecture naming var dockerArch string switch arch { @@ -403,7 +396,7 @@ func installDocker() error { fedoraVersion = v } } - + // Use appropriate DNF syntax based on version var repoCmd string if fedoraVersion >= 41 { @@ -413,7 +406,7 @@ func installDocker() error { // DNF 4 syntax for Fedora < 41 repoCmd = "dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo" } - + installCmd = exec.Command("bash", "-c", fmt.Sprintf(` dnf -y install dnf-plugins-core && %s && @@ -442,7 +435,7 @@ func installDocker() error { default: return fmt.Errorf("unsupported Linux distribution") } - + installCmd.Stdout = os.Stdout installCmd.Stderr = os.Stderr return installCmd.Run() @@ -527,7 +520,7 @@ func executeDockerComposeCommandWithArgs(args ...string) error { return fmt.Errorf("neither 'docker compose' nor 'docker-compose' command is available") } } - + if useNewStyle { cmd = exec.Command("docker", append([]string{"compose"}, args...)...) } else { @@ -563,7 +556,7 @@ func startContainers() error { // stopContainers stops the containers using the appropriate command. func stopContainers() error { fmt.Println("Stopping containers...") - + if err := executeDockerComposeCommandWithArgs("-f", "docker-compose.yml", "down"); err != nil { return fmt.Errorf("failed to stop containers: %v", err) } @@ -574,7 +567,7 @@ func stopContainers() error { // restartContainer restarts a specific container using the appropriate command. func restartContainer(container string) error { fmt.Println("Restarting containers...") - + if err := executeDockerComposeCommandWithArgs("-f", "docker-compose.yml", "restart", container); err != nil { return fmt.Errorf("failed to stop the container \"%s\": %v", container, err) } diff --git a/server/db/pg/driver.ts b/server/db/pg/driver.ts index 6208e4d1..116e4610 100644 --- a/server/db/pg/driver.ts +++ b/server/db/pg/driver.ts @@ -5,6 +5,12 @@ import { withReplicas } from "drizzle-orm/pg-core"; function createDb() { const config = readConfigFile(); + if (!config.postgres) { + throw new Error( + "Postgres configuration is missing in the configuration file." + ); + } + const connectionString = config.postgres?.connection_string; const replicaConnections = config.postgres?.replicas || []; diff --git a/server/db/sqlite/driver.ts b/server/db/sqlite/driver.ts index a83ca7dd..9a12b43d 100644 --- a/server/db/sqlite/driver.ts +++ b/server/db/sqlite/driver.ts @@ -5,7 +5,6 @@ import path from "path"; import fs from "fs/promises"; import { APP_PATH } from "@server/lib/consts"; import { existsSync, mkdirSync } from "fs"; -import { readConfigFile } from "@server/lib/readConfigFile"; export const location = path.join(APP_PATH, "db", "db.sqlite"); export const exists = await checkFileExists(location); @@ -13,8 +12,6 @@ export const exists = await checkFileExists(location); bootstrapVolume(); function createDb() { - const config = readConfigFile(); - const sqlite = new Database(location); return DrizzleSqlite(sqlite, { schema }); } diff --git a/server/lib/config.ts b/server/lib/config.ts index d83bb5b2..cec59488 100644 --- a/server/lib/config.ts +++ b/server/lib/config.ts @@ -5,6 +5,7 @@ import { SupporterKey, supporterKey } from "@server/db"; import { eq } from "drizzle-orm"; import { license } from "@server/license/license"; import { configSchema, readConfigFile } from "./readConfigFile"; +import { fromError } from "zod-validation-error"; export class Config { private rawConfig!: z.infer; @@ -20,7 +21,29 @@ export class Config { } public load() { - const parsedConfig = readConfigFile(); + const environment = readConfigFile(); + + const { + data: parsedConfig, + success, + error + } = configSchema.safeParse(environment); + + if (!success) { + const errors = fromError(error); + throw new Error(`Invalid configuration file: ${errors}`); + } + + if (process.env.APP_BASE_DOMAIN) { + console.log( + "You're using deprecated environment variables. Transition to the configuration file. https://docs.fossorial.io/" + ); + } + + // @ts-ignore + if (parsedConfig.users) { + console.log("You're admin credentials are still in the config file. This method of setting admin credentials is deprecated. It is recommended to remove them from the config file."); + } process.env.APP_VERSION = APP_VERSION; diff --git a/server/lib/consts.ts b/server/lib/consts.ts index 1dc46d2b..843ce54f 100644 --- a/server/lib/consts.ts +++ b/server/lib/consts.ts @@ -2,7 +2,7 @@ import path from "path"; import { fileURLToPath } from "url"; // This is a placeholder value replaced by the build process -export const APP_VERSION = "1.5.1"; +export const APP_VERSION = "1.6.0"; export const __FILENAME = fileURLToPath(import.meta.url); export const __DIRNAME = path.dirname(__FILENAME); diff --git a/server/lib/readConfigFile.ts b/server/lib/readConfigFile.ts index a82eac75..0058127f 100644 --- a/server/lib/readConfigFile.ts +++ b/server/lib/readConfigFile.ts @@ -233,24 +233,11 @@ export function readConfigFile() { environment = loadConfig(configFilePath2); } - if (process.env.APP_BASE_DOMAIN) { - console.log( - "You're using deprecated environment variables. Transition to the configuration file. https://docs.fossorial.io/" - ); - } - if (!environment) { throw new Error( "No configuration file found. Please create one. https://docs.fossorial.io/" ); } - const parsedConfig = configSchema.safeParse(environment); - - if (!parsedConfig.success) { - const errors = fromError(parsedConfig.error); - throw new Error(`Invalid configuration file: ${errors}`); - } - - return parsedConfig.data; + return environment; } diff --git a/src/app/page.tsx b/src/app/page.tsx index 2d2d6894..14738ac7 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -33,7 +33,6 @@ export default async function Page(props: { >(`/auth/initial-setup-complete`, await authCookieHeader()); const complete = setupRes.data.data.complete; if (!complete) { - console.log("compelte", complete); redirect("/auth/initial-setup"); }