Files
MineGeo/shared/account.ts
pavel444-byte 50b27cf498
All checks were successful
Deploy MineGeo to Dokploy / deploy (push) Successful in 3m27s
Add moderator bots and editable MineGeo usernames
2026-10-29 16:32:55 +05:00

90 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 usernameSchema = z.string().trim().toLowerCase().regex(/^[a-z0-9_]{3,32}$/, "Use 3–32 letters, numbers or underscores.");
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(),
username: usernameSchema.optional(),
glowColor: glowColorSchema.optional(),
avatarPath: z.string().max(128).nullable().optional(),
})
.strict()
.refine(
(value) =>
value.displayName !== undefined ||
value.username !== 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 && /^\/tournaments\?map=[0-9a-f-]{36}$/i.test(value)) return value;
if (value && /^\/pair\?code=[A-F0-9]{8}$/.test(value)) return value;
if (value && /^\/moderator-application\/[a-f0-9]{64}$/.test(value)) return value;
return "/dashboard";
}