瀏覽代碼

Merge pull request #125 from fosrl/dev

Hotfix Various Bugs
Milo Schwartz 5 月之前
父節點
當前提交
722b877ea5

+ 1 - 1
server/auth/passwordSchema.ts

@@ -4,7 +4,7 @@ export const passwordSchema = z
     .string()
     .min(8, { message: "Password must be at least 8 characters long" })
     .max(64, { message: "Password must be at most 64 characters long" })
-    .regex(/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).*$/, {
+    .regex(/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[,#?!@$%^&*-]).*$/, {
         message: `Your password must meet the following conditions:
 at least one uppercase English letter,
 at least one lowercase English letter,

+ 51 - 26
server/routers/traefik/getTraefikConfig.ts

@@ -118,14 +118,6 @@ export async function traefikConfigProvider(
                     continue;
                 }
 
-                if (
-                    targets.filter(
-                        (target: Target) => target.internalPort != null
-                    ).length == 0
-                ) {
-                    continue;
-                }
-
                 // add routers and services empty objects if they don't exist
                 if (!config_output.http.routers) {
                     config_output.http.routers = {};
@@ -156,7 +148,8 @@ export async function traefikConfigProvider(
                         : {})
                 };
 
-                const additionalMiddlewares = config.getRawConfig().traefik.additional_middlewares || [];
+                const additionalMiddlewares =
+                    config.getRawConfig().traefik.additional_middlewares || [];
 
                 config_output.http.routers![routerName] = {
                     entryPoints: [
@@ -164,7 +157,10 @@ export async function traefikConfigProvider(
                             ? config.getRawConfig().traefik.https_entrypoint
                             : config.getRawConfig().traefik.http_entrypoint
                     ],
-                    middlewares: [badgerMiddlewareName, ...additionalMiddlewares],
+                    middlewares: [
+                        badgerMiddlewareName,
+                        ...additionalMiddlewares
+                    ],
                     service: serviceName,
                     rule: `Host(\`${fullDomain}\`)`,
                     ...(resource.ssl ? { tls } : {})
@@ -184,9 +180,31 @@ export async function traefikConfigProvider(
                 config_output.http.services![serviceName] = {
                     loadBalancer: {
                         servers: targets
-                            .filter(
-                                (target: Target) => target.internalPort != null
-                            )
+                            .filter((target: Target) => {
+                                if (!target.enabled) {
+                                    return false;
+                                }
+                                if (
+                                    site.type === "local" ||
+                                    site.type === "wireguard"
+                                ) {
+                                    if (
+                                        !target.ip ||
+                                        !target.port ||
+                                        !target.method
+                                    ) {
+                                        return false;
+                                    }
+                                } else if (site.type === "newt") {
+                                    if (
+                                        !target.internalPort ||
+                                        !target.method
+                                    ) {
+                                        return false;
+                                    }
+                                }
+                                return true;
+                            })
                             .map((target: Target) => {
                                 if (
                                     site.type === "local" ||
@@ -213,14 +231,6 @@ export async function traefikConfigProvider(
                     continue;
                 }
 
-                if (
-                    targets.filter(
-                        (target: Target) => target.internalPort != null
-                    ).length == 0
-                ) {
-                    continue;
-                }
-
                 if (!config_output[protocol]) {
                     config_output[protocol] = {
                         routers: {},
@@ -237,9 +247,24 @@ export async function traefikConfigProvider(
                 config_output[protocol].services[serviceName] = {
                     loadBalancer: {
                         servers: targets
-                            .filter(
-                                (target: Target) => target.internalPort != null
-                            )
+                            .filter((target: Target) => {
+                                if (!target.enabled) {
+                                    return false;
+                                }
+                                if (
+                                    site.type === "local" ||
+                                    site.type === "wireguard"
+                                ) {
+                                    if (!target.ip || !target.port) {
+                                        return false;
+                                    }
+                                } else if (site.type === "newt") {
+                                    if (!target.internalPort) {
+                                        return false;
+                                    }
+                                }
+                                return true;
+                            })
                             .map((target: Target) => {
                                 if (
                                     site.type === "local" ||
@@ -261,9 +286,9 @@ export async function traefikConfigProvider(
         }
         return res.status(HttpCode.OK).json(config_output);
     } catch (e) {
-        logger.error(`Failed to build traefik config: ${e}`);
+        logger.error(`Failed to build Traefik config: ${e}`);
         return res.status(HttpCode.INTERNAL_SERVER_ERROR).json({
-            error: "Failed to build traefik config"
+            error: "Failed to build Traefik config"
         });
     }
 }

+ 32 - 22
server/setup/migrations.ts

@@ -3,9 +3,9 @@ import db, { exists } from "@server/db";
 import path from "path";
 import semver from "semver";
 import { versionMigrations } from "@server/db/schema";
-import { desc } from "drizzle-orm";
 import { __DIRNAME } from "@server/lib/consts";
 import { loadAppVersion } from "@server/lib/loadAppVersion";
+import { SqliteError } from "better-sqlite3";
 import m1 from "./scripts/1.0.0-beta1";
 import m2 from "./scripts/1.0.0-beta2";
 import m3 from "./scripts/1.0.0-beta3";
@@ -53,38 +53,44 @@ export async function runMigrations() {
             }
 
             await db
-            .insert(versionMigrations)
-            .values({
-                version: appVersion,
-                executedAt: Date.now()
-            })
-            .execute();
+                .insert(versionMigrations)
+                .values({
+                    version: appVersion,
+                    executedAt: Date.now()
+                })
+                .execute();
         }
     } catch (e) {
         console.error("Error running migrations:", e);
-        await new Promise((resolve) => setTimeout(resolve, 1000 * 60 * 60 * 24 * 1));
+        await new Promise((resolve) =>
+            setTimeout(resolve, 1000 * 60 * 60 * 24 * 1)
+        );
     }
 }
 
 async function executeScripts() {
     try {
         // Get the last executed version from the database
-        const lastExecuted = await db
-            .select()
-            .from(versionMigrations)
-            .orderBy(desc(versionMigrations.version))
-            .limit(1);
+        const lastExecuted = await db.select().from(versionMigrations);
 
-        const startVersion = lastExecuted[0]?.version ?? "0.0.0";
+        // Filter and sort migrations
+        const pendingMigrations = lastExecuted
+            .map((m) => m)
+            .sort((a, b) => semver.compare(b.version, a.version));
+        const startVersion = pendingMigrations[0]?.version ?? "0.0.0";
         console.log(`Starting migrations from version ${startVersion}`);
 
-        // Filter and sort migrations
-        const pendingMigrations = migrations
-            .filter((migration) => semver.gt(migration.version, startVersion))
-            .sort((a, b) => semver.compare(a.version, b.version));
+        const migrationsToRun = migrations.filter((migration) =>
+            semver.gt(migration.version, startVersion)
+        );
+
+        console.log(
+            "Migrations to run:",
+            migrationsToRun.map((m) => m.version).join(", ")
+        );
 
         // Run migrations in order
-        for (const migration of pendingMigrations) {
+        for (const migration of migrationsToRun) {
             console.log(`Running migration ${migration.version}`);
 
             try {
@@ -102,12 +108,16 @@ async function executeScripts() {
                 console.log(
                     `Successfully completed migration ${migration.version}`
                 );
-            } catch (error) {
+            } catch (e) {
+                if (e instanceof SqliteError && e.code === "SQLITE_CONSTRAINT_UNIQUE") {
+                    console.error("Migration has already run! Skipping...");
+                    continue;
+                }
                 console.error(
                     `Failed to run migration ${migration.version}:`,
-                    error
+                    e
                 );
-                throw error; // Re-throw to stop migration process
+                throw e; // Re-throw to stop migration process
             }
         }
 

+ 3 - 5
src/app/[orgId]/settings/resources/CreateResourceForm.tsx

@@ -164,8 +164,6 @@ export default function CreateResourceForm({
     }, [open]);
 
     async function onSubmit(data: CreateResourceFormValues) {
-        console.log(data);
-
         const res = await api
             .put<AxiosResponse<Resource>>(
                 `/org/${orgId}/site/${data.siteId}/resource/`,
@@ -194,16 +192,16 @@ export default function CreateResourceForm({
             setResourceId(id);
 
             if (data.http) {
-                goToResource();
+                goToResource(id);
             } else {
                 setShowSnippets(true);
             }
         }
     }
 
-    function goToResource() {
+    function goToResource(id?: number) {
         // navigate to the resource page
-        router.push(`/${orgId}/settings/resources/${resourceId}`);
+        router.push(`/${orgId}/settings/resources/${id || resourceId}`);
     }
 
     return (