Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 6m16s
85 lines
2.4 KiB
TypeScript
85 lines
2.4 KiB
TypeScript
import { z } from "zod";
|
|
import { glowColorSchema } from "./profile-appearance";
|
|
|
|
export const displayNameSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(2, "Use at least 2 characters")
|
|
.max(32, "Use at most 32 characters")
|
|
.refine(
|
|
(value) => !/[\u0000-\u001f\u007f\u202a-\u202e\u2066-\u2069]/u.test(value),
|
|
"Use a single line without hidden control characters",
|
|
);
|
|
export const newPasswordSchema = z
|
|
.string()
|
|
.min(12, "Use at least 12 characters")
|
|
.refine(
|
|
(value) => new TextEncoder().encode(value).length <= 72,
|
|
"Use at most 72 UTF-8 bytes for your password",
|
|
);
|
|
const email = z.string().trim().email().max(254);
|
|
export const authActionSchema = z.discriminatedUnion("action", [
|
|
z
|
|
.object({
|
|
action: z.literal("login"),
|
|
email,
|
|
password: z.string().min(1).max(1024),
|
|
next: z.string().optional(),
|
|
})
|
|
.strict(),
|
|
z
|
|
.object({
|
|
action: z.literal("signup"),
|
|
email,
|
|
password: newPasswordSchema,
|
|
displayName: displayNameSchema,
|
|
next: z.string().optional(),
|
|
})
|
|
.strict(),
|
|
z.object({ action: z.literal("recover"), email }).strict(),
|
|
]);
|
|
export const profileUpdateSchema = z
|
|
.object({
|
|
displayName: displayNameSchema.optional(),
|
|
glowColor: glowColorSchema.optional(),
|
|
avatarPath: z.string().max(128).nullable().optional(),
|
|
})
|
|
.strict()
|
|
.refine(
|
|
(value) =>
|
|
value.displayName !== undefined ||
|
|
value.glowColor !== undefined ||
|
|
value.avatarPath !== undefined,
|
|
"Choose a profile change",
|
|
);
|
|
export const initialPasswordSchema = z
|
|
.object({ password: newPasswordSchema })
|
|
.strict();
|
|
export const passwordUpdateSchema = z
|
|
.object({
|
|
password: newPasswordSchema,
|
|
currentPassword: z.string().min(1).max(1024).optional(),
|
|
nonce: z
|
|
.string()
|
|
.trim()
|
|
.regex(/^[0-9]{6,10}$/)
|
|
.optional(),
|
|
})
|
|
.strict();
|
|
|
|
/** Only supported product destinations can follow an authentication link. */
|
|
export function authDestination(value: string | null | undefined): string {
|
|
if (
|
|
value === "/settings" ||
|
|
value === "/dashboard" ||
|
|
value === "/servers" ||
|
|
value === "/support" ||
|
|
value === "/auth/reset-password"
|
|
)
|
|
return value;
|
|
if (value && /^\/dashboard\/[0-9a-f-]{36}$/i.test(value)) return value;
|
|
if (value && /^\/support\/[0-9a-f-]{36}$/i.test(value)) return value;
|
|
if (value && /^\/pair\?code=[A-F0-9]{8}$/.test(value)) return value;
|
|
return "/dashboard";
|
|
}
|