Files
web-app-launcher/src/lib/server/utils/userAgent.ts
T
alexei.dolgolyov b9f3a2ca0b feat(auth): Session model + remember-me
Replace the single `user.refreshToken` column with a proper Session
table so users can have multiple concurrent sessions (phone, laptop,
etc.), each with their own refresh token, expiry, label, and
remember-me flag.

- Add Session model (id, userId, tokenHash, label, userAgent,
  ipAddress, rememberMe, lastUsedAt, expiresAt).
- Drop `User.refreshToken` and `User.refreshTokenExpiresAt`.
- authService: new createSession/validateSession/rotateSession/
  revokeSession/listUserSessions helpers; remove refresh-token-on-user
  functions.
- sessionCookies helper now issues a session_id cookie alongside
  access_token and refresh_token; rotateSessionCookies keeps the same
  session id on refresh.
- Login form adds a "Keep me signed in for 30 days" checkbox;
  TTL is 7d by default, 30d with remember-me.
- User-Agent parsed into a friendly label ("Chrome on Windows") for
  the upcoming sessions page.
- hooks.server.ts, refresh endpoint, logout, register, oauth callback,
  and onboarding all switched to the new session API.
2026-04-16 03:41:52 +03:00

29 lines
1.0 KiB
TypeScript

/**
* Parse a User-Agent header into a short, human-readable label like
* "Chrome on Windows" or "Safari on iOS". Intentionally heuristic — not
* a replacement for a full UA parser.
*/
export function parseUserAgentLabel(userAgent: string | null | undefined): string {
if (!userAgent) return 'Unknown device';
const ua = userAgent;
let browser = 'Browser';
if (/Edg\//.test(ua)) browser = 'Edge';
else if (/OPR\//.test(ua) || /Opera/.test(ua)) browser = 'Opera';
else if (/Firefox\//.test(ua)) browser = 'Firefox';
else if (/Chrome\//.test(ua)) browser = 'Chrome';
else if (/Safari\//.test(ua)) browser = 'Safari';
else if (/curl\//i.test(ua)) browser = 'curl';
else if (/PostmanRuntime/.test(ua)) browser = 'Postman';
let os = 'Unknown OS';
if (/Windows NT/.test(ua)) os = 'Windows';
else if (/Mac OS X|Macintosh/.test(ua)) os = 'macOS';
else if (/Android/.test(ua)) os = 'Android';
else if (/iPhone|iPad|iPod/.test(ua)) os = 'iOS';
else if (/Linux/.test(ua)) os = 'Linux';
return `${browser} on ${os}`;
}