import type { AuthIdentityType, AuthPublicUser, AuthUser } from "./types.ts"; export function normalizeEmail(value: string): string { return value.trim().toLowerCase(); } export function normalizeUsername(value: string): string { return value.trim().toLowerCase(); } export function normalizePhone(value: string): string { const trimmed = value.trim(); const prefix = trimmed.startsWith("+") ? "+" : ""; return prefix + trimmed.replace(/\D/g, ""); } export function normalizeIdentity(type: AuthIdentityType, value: string): string { if (type === "email") return normalizeEmail(value); if (type === "phone") return normalizePhone(value); return normalizeUsername(value); } export function inferIdentityType(value: string): AuthIdentityType { const input = value.trim(); if (input.includes("@")) return "email"; if (/^\+?[0-9 ()-]{7,}$/.test(input)) return "phone"; return "username"; } export function publicUser(user: AuthUser): AuthPublicUser { return { id: user.id, username: user.username, displayName: user.displayName, avatarUrl: user.avatarUrl, status: user.status, roles: [...user.roles], emailVerified: user.emailVerified, phoneVerified: user.phoneVerified, mfaEnabled: user.mfaEnabled, }; } /** Return a same-origin path for post-authentication navigation. */ export function safeAuthReturnTo(value: string | undefined, origin: string): string | undefined { if (!value) return undefined; try { const base = new URL(origin); const target = new URL(value, base); if (target.origin !== base.origin) return undefined; return `${target.pathname}${target.search}${target.hash}`; } catch { return undefined; } }