(value: unknown)
| 241 | } |
| 242 | |
| 243 | function sanitizeSession(value: unknown): PersistedServerAuthSession | null { |
| 244 | if (!value || typeof value !== "object") { |
| 245 | return null; |
| 246 | } |
| 247 | |
| 248 | const record = value as Record<string, unknown>; |
| 249 | |
| 250 | const id = normalizeOptionalString(record.id); |
| 251 | const tokenHash = normalizeOptionalString(record.tokenHash); |
| 252 | |
| 253 | const createdAtMs = |
| 254 | typeof record.createdAtMs === "number" && Number.isFinite(record.createdAtMs) |
| 255 | ? record.createdAtMs |
| 256 | : null; |
| 257 | const lastUsedAtMs = |
| 258 | typeof record.lastUsedAtMs === "number" && Number.isFinite(record.lastUsedAtMs) |
| 259 | ? record.lastUsedAtMs |
| 260 | : null; |
| 261 | |
| 262 | if (!id || !tokenHash || createdAtMs == null || lastUsedAtMs == null) { |
| 263 | return null; |
| 264 | } |
| 265 | |
| 266 | return { |
| 267 | id, |
| 268 | tokenHash, |
| 269 | createdAtMs, |
| 270 | lastUsedAtMs, |
| 271 | userAgent: normalizeOptionalString(record.userAgent), |
| 272 | ipAddress: normalizeOptionalString(record.ipAddress), |
| 273 | label: normalizeOptionalString(record.label), |
| 274 | }; |
| 275 | } |
| 276 | |
| 277 | export class ServerAuthService { |
| 278 | private readonly sessionsFilePath: string; |
no test coverage detected