فهرست منبع

make all emails lowercase closes #89

Milo Schwartz 6 ماه پیش
والد
کامیت
5f92b0bbc1

+ 4 - 2
server/lib/config.ts

@@ -37,7 +37,8 @@ const configSchema = z.object({
         base_domain: hostnameSchema
             .optional()
             .transform(getEnvOrYaml("APP_BASEDOMAIN"))
-            .pipe(hostnameSchema),
+            .pipe(hostnameSchema)
+            .transform((url) => url.toLowerCase()),
         log_level: z.enum(["debug", "info", "warn", "error"]),
         save_logs: z.boolean()
     }),
@@ -123,7 +124,8 @@ const configSchema = z.object({
                 .email()
                 .optional()
                 .transform(getEnvOrYaml("USERS_SERVERADMIN_EMAIL"))
-                .pipe(z.string().email()),
+                .pipe(z.string().email())
+                .transform((v) => v.toLowerCase()),
             password: passwordSchema
                 .optional()
                 .transform(getEnvOrYaml("USERS_SERVERADMIN_PASSWORD"))

+ 4 - 1
server/routers/auth/login.ts

@@ -20,7 +20,10 @@ import { verifySession } from "@server/auth/sessions/verifySession";
 
 export const loginBodySchema = z
     .object({
-        email: z.string().email(),
+        email: z
+            .string()
+            .email()
+            .transform((v) => v.toLowerCase()),
         password: z.string(),
         code: z.string().optional()
     })

+ 5 - 5
server/routers/auth/requestPasswordReset.ts

@@ -20,7 +20,10 @@ import { hashPassword } from "@server/auth/password";
 
 export const requestPasswordResetBody = z
     .object({
-        email: z.string().email()
+        email: z
+            .string()
+            .email()
+            .transform((v) => v.toLowerCase())
     })
     .strict();
 
@@ -63,10 +66,7 @@ export async function requestPasswordReset(
             );
         }
 
-        const token = generateRandomString(
-            8,
-            alphabet("0-9", "A-Z", "a-z")
-        );
+        const token = generateRandomString(8, alphabet("0-9", "A-Z", "a-z"));
         await db.transaction(async (trx) => {
             await trx
                 .delete(passwordResetTokens)

+ 4 - 1
server/routers/auth/resetPassword.ts

@@ -19,7 +19,10 @@ import { passwordSchema } from "@server/auth/passwordSchema";
 
 export const resetPasswordBody = z
     .object({
-        email: z.string().email(),
+        email: z
+            .string()
+            .email()
+            .transform((v) => v.toLowerCase()),
         token: z.string(), // reset secret code
         newPassword: passwordSchema,
         code: z.string().optional() // 2fa code

+ 1 - 1
server/routers/auth/signup.ts

@@ -23,7 +23,7 @@ import { checkValidInvite } from "@server/auth/checkValidInvite";
 import { passwordSchema } from "@server/auth/passwordSchema";
 
 export const signupBodySchema = z.object({
-    email: z.string().email(),
+    email: z.string().email().transform((v) => v.toLowerCase()),
     password: passwordSchema,
     inviteToken: z.string().optional(),
     inviteId: z.string().optional()

+ 4 - 1
server/routers/resource/authWithWhitelist.ts

@@ -24,7 +24,10 @@ import logger from "@server/logger";
 
 const authWithWhitelistBodySchema = z
     .object({
-        email: z.string().email(),
+        email: z
+            .string()
+            .email()
+            .transform((v) => v.toLowerCase()),
         otp: z.string().optional()
     })
     .strict();

+ 4 - 1
server/routers/resource/setResourceWhitelist.ts

@@ -11,7 +11,10 @@ import { and, eq } from "drizzle-orm";
 
 const setResourceWhitelistBodySchema = z
     .object({
-        emails: z.array(z.string().email()).max(50)
+        emails: z
+            .array(z.string().email())
+            .max(50)
+            .transform((v) => v.map((e) => e.toLowerCase()))
     })
     .strict();
 

+ 4 - 1
server/routers/user/inviteUser.ts

@@ -23,7 +23,10 @@ const inviteUserParamsSchema = z
 
 const inviteUserBodySchema = z
     .object({
-        email: z.string().email(),
+        email: z
+            .string()
+            .email()
+            .transform((v) => v.toLowerCase()),
         roleId: z.number(),
         validHours: z.number().gt(0).lte(168),
         sendEmail: z.boolean().optional()

+ 3 - 2
server/setup/migrations.ts

@@ -11,7 +11,7 @@ import m2 from "./scripts/1.0.0-beta2";
 import m3 from "./scripts/1.0.0-beta3";
 import m4 from "./scripts/1.0.0-beta5";
 import m5 from "./scripts/1.0.0-beta6";
-import { existsSync, mkdirSync } from "fs";
+import m6 from "./scripts/1.0.0-beta9";
 
 // THIS CANNOT IMPORT ANYTHING FROM THE SERVER
 // EXCEPT FOR THE DATABASE AND THE SCHEMA
@@ -22,7 +22,8 @@ const migrations = [
     { version: "1.0.0-beta.2", run: m2 },
     { version: "1.0.0-beta.3", run: m3 },
     { version: "1.0.0-beta.5", run: m4 },
-    { version: "1.0.0-beta.6", run: m5 }
+    { version: "1.0.0-beta.6", run: m5 },
+    { version: "1.0.0-beta.9", run: m6 }
     // Add new migrations here as they are created
 ] as const;
 

+ 40 - 0
server/setup/scripts/1.0.0-beta9.ts

@@ -0,0 +1,40 @@
+import db from "@server/db";
+import {
+    emailVerificationCodes,
+    passwordResetTokens,
+    resourceOtp,
+    resourceWhitelist,
+    userInvites,
+    users
+} from "@server/db/schema";
+import { sql } from "drizzle-orm";
+
+export default async function migration() {
+    console.log("Running setup script 1.0.0-beta.9...");
+
+    try {
+        await db.transaction(async (trx) => {
+            await db.transaction(async (trx) => {
+                trx.run(sql`UPDATE ${users} SET email = LOWER(email);`);
+                trx.run(
+                    sql`UPDATE ${emailVerificationCodes} SET email = LOWER(email);`
+                );
+                trx.run(
+                    sql`UPDATE ${passwordResetTokens} SET email = LOWER(email);`
+                );
+                trx.run(sql`UPDATE ${userInvites} SET email = LOWER(email);`);
+                trx.run(
+                    sql`UPDATE ${resourceWhitelist} SET email = LOWER(email);`
+                );
+                trx.run(sql`UPDATE ${resourceOtp} SET email = LOWER(email);`);
+            });
+        });
+    } catch (error) {
+        console.log(
+            "We were unable to make all emails lower case in the database."
+        );
+        console.error(error);
+    }
+
+    console.log("Done.");
+}