SPB Git forge

spb/polyllm

Public
15commits 1branches 0releases
2.2 MBsize
maindefault branch
13 days agolast push
TypeScript 97.4% SQL 1% JavaScript 0.9% CSS 0.6%
3.0 KB · 66 lines typescript
Raw Blame History
1/** Shape of the error object returned by the Better Auth client (`{ data, error }`). */2export interface AuthClientError {3  code?: string;4  message?: string;5  status?: number;6  statusText?: string;7}89export const GENERIC_ERROR = "Something went wrong on our side. Please try again in a moment.";1011/** Map Better Auth error codes to short, human, provider-agnostic messages. Never leaks raw server text. */12export function humanAuthError(error: AuthClientError | null | undefined, context: "login" | "signup" | "reset" | "forgot" | "verify" = "login"): string {13  if (!error) return GENERIC_ERROR;14  if (error.status === 429) return "Too many attempts. Please wait a minute and try again.";15  switch (error.code) {16    case "INVALID_EMAIL_OR_PASSWORD":17    case "INVALID_PASSWORD":18    case "USER_NOT_FOUND":19      return context === "login" ? "That email and password don't match." : "We couldn't find an account for that email.";20    case "INVALID_EMAIL":21      return "That doesn't look like a valid email address.";22    case "EMAIL_NOT_VERIFIED":23      return "Please verify your email before signing in.";24    case "USER_ALREADY_EXISTS":25    case "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL":26      return "An account with this email already exists. Try signing in instead.";27    case "PASSWORD_TOO_SHORT":28      return "Your password must be at least 10 characters.";29    case "PASSWORD_TOO_LONG":30      return "Your password must be 128 characters or fewer.";31    case "INVALID_TOKEN":32      return context === "verify" ? "This verification link is invalid or has already been used." : "This reset link is invalid or has already been used. Request a new one.";33    case "TOKEN_EXPIRED":34      return context === "verify" ? "This verification link has expired. Request a new one below." : "This reset link has expired. Request a new one.";35    case "FAILED_TO_CREATE_USER":36    case "FAILED_TO_CREATE_SESSION":37    case "FAILED_TO_UPDATE_USER":38      return GENERIC_ERROR;39    default:40      if (error.status && error.status >= 500) return GENERIC_ERROR;41      if (error.status === 0 || error.status === undefined) return "We couldn't reach the server. Check your connection and try again.";42      return GENERIC_ERROR;43  }44}4546export function isValidEmail(email: string): boolean {47  return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email.trim());48}4950export const PASSWORD_MIN = 10;51export const PASSWORD_MAX = 128;5253export function passwordLengthError(pw: string): string | null {54  if (pw.length < PASSWORD_MIN) return `Use at least ${PASSWORD_MIN} characters.`;55  if (pw.length > PASSWORD_MAX) return `Use at most ${PASSWORD_MAX} characters.`;56  return null;57}5859/** Only allow same-origin relative paths for post-login redirects. */60export function safeNext(next: string | string[] | undefined): string {61  const v = Array.isArray(next) ? next[0] : next;62  if (!v || !v.startsWith("/") || v.startsWith("//") || v.startsWith("/\\")) return "/app/chat";63  if (v.startsWith("/login") || v.startsWith("/signup")) return "/app/chat";64  return v;65}66