@focura/auth-core 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @focura/auth-core
2
2
 
3
- Production-ready authentication core for Express.js backends.
3
+ Production-ready authentication engine for Node.js backends.
4
4
 
5
5
  ## Features
6
6
 
@@ -19,19 +19,19 @@ Production-ready authentication core for Express.js backends.
19
19
  ## Installation
20
20
 
21
21
  ```bash
22
- npm install @focura/auth-core express ioredis
23
- npm install -D @types/express
22
+ npm install @focura/auth-core ioredis
24
23
  ```
25
24
 
26
25
  ## Quick Start
27
26
 
28
27
  ```typescript
29
- import { MiddlewareFactory, AccountLockout, SessionManager } from "@focura/auth-core";
28
+ import { AuthService } from "@focura/auth-core";
30
29
  import Redis from "ioredis";
30
+ import fs from "fs";
31
31
 
32
32
  const redis = new Redis(process.env.REDIS_URL!);
33
33
 
34
- const auth = new MiddlewareFactory({
34
+ const auth = new AuthService({
35
35
  redis,
36
36
  userStore: {
37
37
  findById: (id) => prisma.user.findUnique({ where: { id } }),
@@ -39,34 +39,147 @@ const auth = new MiddlewareFactory({
39
39
  update: (id, data) => prisma.user.update({ where: { id }, data }),
40
40
  updateEmailVerified: (id, date) => prisma.user.update({ where: { id }, data: { emailVerified: date } }),
41
41
  },
42
- hmacSecret: process.env.NEXTAUTH_SECRET!,
42
+ hmacSecret: process.env.AUTH_SECRET!,
43
43
  jwt: {
44
44
  privateKey: fs.readFileSync("keys/private.pem", "utf8"),
45
45
  publicKey: fs.readFileSync("keys/public.pem", "utf8"),
46
46
  },
47
- cache: {
48
- get: (key) => redis.get(key).then(JSON.parse),
49
- set: (key, val, ttl) => redis.setex(key, ttl!, JSON.stringify(val)),
50
- delete: (key) => redis.del(key),
51
- },
52
- auditLogger: {
53
- log: (event, data) => prisma.auditLog.create({ data: { event, ...data } }),
54
- },
55
47
  });
48
+ ```
56
49
 
57
- // Auth routes
58
- app.post("/api/v1/auth/exchange", auth.createExchangeHandler());
59
- app.post("/api/v1/auth/refresh", auth.createRefreshHandler());
60
- app.post("/api/v1/auth/logout", auth.createLogoutHandler());
50
+ ## High-Level API
61
51
 
62
- // Protected routes
63
- app.get("/api/v1/profile", auth.createAuthenticateMiddleware(), (req, res) => {
64
- res.json({ user: req.user });
52
+ ### Token Exchange
53
+
54
+ Exchange a HMAC-signed proof for JWT tokens:
55
+
56
+ ```typescript
57
+ const tokens = await auth.exchange({
58
+ userId: user.id,
59
+ email: user.email,
60
+ role: user.role,
61
+ sessionId: crypto.randomUUID(),
62
+ timestamp: Date.now(),
63
+ signature: hmacSignature,
65
64
  });
66
65
 
67
- app.get("/api/v1/admin", auth.createAuthenticateMiddleware(), auth.createAuthorizeMiddleware("ADMIN"), (req, res) => {
68
- res.json({ admin: true });
66
+ // tokens.accessToken, tokens.refreshToken, tokens.sseToken, tokens.sessionId
67
+ ```
68
+
69
+ ### Verify Token
70
+
71
+ Verify an access token and load the user:
72
+
73
+ ```typescript
74
+ const { user, payload } = await auth.verifyToken({
75
+ token: accessToken,
76
+ ipAddress: "192.168.1.1",
77
+ userAgent: "Mozilla/5.0...",
69
78
  });
79
+
80
+ // payload.id, payload.email, payload.role, payload.jti, payload.sessionId
81
+ ```
82
+
83
+ ### Refresh Tokens
84
+
85
+ Rotate refresh tokens atomically:
86
+
87
+ ```typescript
88
+ const newTokens = await auth.refresh({
89
+ refreshToken: currentRefreshToken,
90
+ });
91
+
92
+ // newTokens.accessToken, newTokens.refreshToken, newTokens.sseToken
93
+ ```
94
+
95
+ ### Logout
96
+
97
+ ```typescript
98
+ // Single session
99
+ await auth.logout({
100
+ userId: user.id,
101
+ sessionId: sessionId,
102
+ accessTokenJti: jti,
103
+ accessToken: token,
104
+ });
105
+
106
+ // All sessions
107
+ await auth.logout({
108
+ userId: user.id,
109
+ sessionId: sessionId,
110
+ logoutAll: true,
111
+ });
112
+ ```
113
+
114
+ ### Two-Factor Authentication
115
+
116
+ ```typescript
117
+ // Setup — generate secret + URI for QR code
118
+ const { secret, uri } = auth.generateTwoFactor();
119
+ // Display uri as QR code to user, store secret in database
120
+
121
+ // Verify TOTP code
122
+ const valid = await auth.verifyTwoFactor({ token: "123456", secret });
123
+ ```
124
+
125
+ ### Session Management
126
+
127
+ ```typescript
128
+ // List active sessions
129
+ const sessions = await auth.getActiveSessions(userId);
130
+
131
+ // Revoke a specific session
132
+ await auth.revokeSession(userId, sessionId);
133
+ ```
134
+
135
+ ### Account Lockout
136
+
137
+ ```typescript
138
+ // Record failed login attempt
139
+ const result = await auth.recordLoginFailure(email);
140
+ if (result.locked) {
141
+ console.log(`Account locked until ${result.unlocksAt}`);
142
+ }
143
+
144
+ // Clear failures on successful login
145
+ await auth.clearLoginFailures(email);
146
+
147
+ // Check if account is locked
148
+ const status = await auth.isAccountLocked(email);
149
+ ```
150
+
151
+ ### Audit Logging
152
+
153
+ ```typescript
154
+ auth.log("WORKSPACE_CREATED", { userId, workspaceId });
155
+ ```
156
+
157
+ ## Express Integration
158
+
159
+ For Express.js applications, use `MiddlewareFactory` for HTTP middleware:
160
+
161
+ ```typescript
162
+ import { MiddlewareFactory } from "@focura/auth-core";
163
+
164
+ const factory = new MiddlewareFactory(config);
165
+
166
+ // Auth routes
167
+ app.post("/api/v1/auth/exchange", factory.createExchangeHandler());
168
+ app.post("/api/v1/auth/refresh", factory.createRefreshHandler());
169
+ app.post("/api/v1/auth/logout", factory.createLogoutHandler());
170
+
171
+ // Protected routes
172
+ app.get("/api/v1/profile",
173
+ factory.createAuthenticateMiddleware(),
174
+ (req, res) => { res.json({ user: req.user }); }
175
+ );
176
+
177
+ // Role-based access
178
+ app.get("/api/v1/admin",
179
+ factory.createAuthenticateMiddleware(),
180
+ factory.createAuthorizeMiddleware("ADMIN"),
181
+ (req, res) => { res.json({ admin: true }); }
182
+ );
70
183
  ```
71
184
 
72
185
  ## Adapters
@@ -79,8 +192,7 @@ Works with ioredis or any compatible client:
79
192
  import Redis from "ioredis";
80
193
  const redis = new Redis(process.env.REDIS_URL);
81
194
 
82
- // Pass directly ioredis satisfies the RedisAdapter interface
83
- const auth = new MiddlewareFactory({ redis, ... });
195
+ const auth = new AuthService({ redis, ... });
84
196
  ```
85
197
 
86
198
  ### UserStore
@@ -133,6 +245,34 @@ openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
133
245
  openssl rsa -in private.pem -pubout -out public.pem
134
246
  ```
135
247
 
248
+ ## API Hierarchy
249
+
250
+ ### Primary API (Recommended)
251
+
252
+ ```typescript
253
+ import { AuthService } from "@focura/auth-core";
254
+ ```
255
+
256
+ The `AuthService` class provides high-level, framework-agnostic authentication operations.
257
+
258
+ ### Extension API
259
+
260
+ Interfaces for integrating your infrastructure:
261
+
262
+ ```typescript
263
+ import type { UserStore, RedisAdapter, CacheAdapter, AuditLogger } from "@focura/auth-core";
264
+ ```
265
+
266
+ ### Advanced API
267
+
268
+ Low-level classes for custom integrations:
269
+
270
+ ```typescript
271
+ import { TokenManager, SessionManager, TotpManager, AccountLockout } from "@focura/auth-core";
272
+ ```
273
+
274
+ These are available but not required for normal application development.
275
+
136
276
  ## License
137
277
 
138
278
  MIT
package/dist/index.d.ts CHANGED
@@ -165,6 +165,54 @@ interface SessionMetadata {
165
165
  type AuditEventType = "LOGIN_SUCCESS" | "LOGIN_FAILED" | "LOGIN_BLOCKED" | "LOGOUT" | "LOGOUT_ALL_DEVICES" | "TOKEN_REFRESHED" | "TOKEN_REVOKED" | "TOKEN_EXPIRED" | "TOKEN_VERSION_MISMATCH" | "TOKEN_REPLAY_DETECTED" | "EXCHANGE_SUCCESS" | "EXCHANGE_FAILED" | "SSE_CONNECTED" | "SSE_DISCONNECTED" | "ACCOUNT_LOCKED" | "TOTP_VERIFIED" | "TOTP_FAILED" | "PERMISSION_DENIED" | "EMAIL_NOT_VERIFIED" | "SESSION_BOUND" | "SESSION_REBOUND" | "SESSION_HIJACK_DETECTED" | "SESSION_TIMEOUT" | "SESSION_REVOKED" | "SESSIONS_REVOKED" | "MAX_SESSIONS_REACHED" | "DEVICE_MISMATCH" | "SUSPICIOUS_IP_CHANGE" | "CSRF_VALIDATION_FAILED" | "UNAUTHORIZED_ACCESS" | "RATE_LIMIT_EXCEEDED" | "MALWARE_DETECTED" | "SUSPICIOUS_ACTIVITY" | "DATA_EXPORT" | "DATA_DELETION" | "SENSITIVE_DATA_ACCESS" | "WORKSPACE_CREATED" | "WORKSPACE_DELETED" | "MEMBER_ADDED" | "MEMBER_REMOVED" | "ROLE_CHANGED" | "SUBSCRIPTION_CREATED" | "SUBSCRIPTION_CANCELLED" | "PAYMENT_FAILED";
166
166
  type AuditSeverity = "info" | "warn" | "critical";
167
167
 
168
+ declare const DEFAULTS: {
169
+ readonly keyPrefix: "focura:";
170
+ readonly issuer: "focura-app";
171
+ readonly audience: "focura-backend";
172
+ readonly accessTokenExpiry: "15m";
173
+ readonly refreshTokenExpiry: "7d";
174
+ readonly sseTokenExpiry: "30s";
175
+ readonly currentVersion: 1;
176
+ readonly maxConcurrentSessions: 5;
177
+ readonly sessionMetadataTtl: number;
178
+ readonly lockoutMaxFailures: 10;
179
+ readonly lockoutSeconds: number;
180
+ readonly lockoutWindowSeconds: number;
181
+ readonly refreshLockTtlSeconds: 45;
182
+ readonly refreshDedupeTtlSeconds: 30;
183
+ readonly revokedSessionTtl: number;
184
+ readonly inactivityTimeout: number;
185
+ readonly absoluteTimeout: number;
186
+ };
187
+ declare function resolveConfig(raw: AuthCoreConfig): {
188
+ keyPrefix: string;
189
+ issuer: string;
190
+ audience: string;
191
+ accessTokenExpiry: string;
192
+ refreshTokenExpiry: string;
193
+ sseTokenExpiry: string;
194
+ currentVersion: number;
195
+ maxConcurrentSessions: number;
196
+ sessionMetadataTtl: number;
197
+ lockoutMaxFailures: number;
198
+ lockoutSeconds: number;
199
+ lockoutWindowSeconds: number;
200
+ inactivityTimeout: number;
201
+ absoluteTimeout: number;
202
+ redis: RedisAdapter;
203
+ userStore: UserStore;
204
+ hmacSecret: string;
205
+ jwt: TokenConfig;
206
+ cache?: CacheAdapter;
207
+ auditLogger?: AuditLogger;
208
+ observability?: ObservabilitySink;
209
+ errors?: ErrorFactory;
210
+ lockout?: LockoutConfig;
211
+ session?: SessionConfig;
212
+ };
213
+ type ResolvedConfig = ReturnType<typeof resolveConfig>;
214
+ declare const AUDIT_SEVERITY: Record<AuditEventType, AuditSeverity>;
215
+
168
216
  declare class TokenManager {
169
217
  private readonly privateKey;
170
218
  private readonly publicKey;
@@ -228,16 +276,6 @@ declare class TokenRevocation {
228
276
  isSessionRevoked(sessionId: string): Promise<boolean>;
229
277
  }
230
278
 
231
- declare class RefreshLock {
232
- private readonly redis;
233
- private readonly prefix;
234
- constructor(redis: RedisAdapter, prefix?: string);
235
- private lockKey;
236
- acquire(sessionId: string): Promise<boolean>;
237
- release(sessionId: string): Promise<void>;
238
- isLocked(sessionId: string): Promise<boolean>;
239
- }
240
-
241
279
  declare class SessionManager {
242
280
  private readonly redis;
243
281
  private readonly tokenRevocation;
@@ -261,40 +299,6 @@ declare class SessionManager {
261
299
  }>>;
262
300
  }
263
301
 
264
- declare function looksLikeServerToServerUA(userAgent: string): boolean;
265
- declare function looksLikeServerToServerRequest(req: {
266
- headers: Record<string, string | string[] | undefined>;
267
- }): boolean;
268
- declare function normalizeUserAgent(userAgent: string): string;
269
- declare function generateDeviceFingerprint(req: {
270
- headers: Record<string, string | string[] | undefined>;
271
- }): string;
272
- declare function getClientIp(req: {
273
- ip?: string;
274
- headers: Record<string, string | string[] | undefined>;
275
- socket?: {
276
- remoteAddress?: string;
277
- };
278
- }): string;
279
- declare function createSessionMetadata(req: {
280
- ip?: string;
281
- headers: Record<string, string | string[] | undefined>;
282
- socket?: {
283
- remoteAddress?: string;
284
- };
285
- }): SessionMetadata;
286
- declare function isPrivateIp(ip: string): boolean;
287
- declare function validateSessionBinding(req: {
288
- headers: Record<string, string | string[] | undefined>;
289
- ip?: string;
290
- socket?: {
291
- remoteAddress?: string;
292
- };
293
- }, storedMetadata: SessionMetadata): {
294
- valid: boolean;
295
- reason?: string;
296
- };
297
-
298
302
  declare class AccountLockout {
299
303
  private readonly redis;
300
304
  private readonly maxFailures;
@@ -333,6 +337,139 @@ declare class TotpManager {
333
337
  verify(token: string, secret: string): Promise<boolean>;
334
338
  }
335
339
 
340
+ interface ExchangeInput {
341
+ userId: string;
342
+ email: string;
343
+ role: string;
344
+ sessionId?: string;
345
+ timestamp: number;
346
+ signature: string;
347
+ }
348
+ interface ExchangeResult extends TokenPair {
349
+ sseToken: string;
350
+ sessionId: string;
351
+ }
352
+ interface VerifyTokenInput {
353
+ token: string;
354
+ ipAddress?: string;
355
+ userAgent?: string;
356
+ }
357
+ interface VerifyTokenResult {
358
+ user: User;
359
+ payload: {
360
+ id: string;
361
+ email: string;
362
+ role: string;
363
+ jti: string;
364
+ sessionId?: string;
365
+ };
366
+ }
367
+ interface RefreshInput {
368
+ refreshToken: string;
369
+ }
370
+ interface RefreshResult extends TokenPair {
371
+ sseToken: string;
372
+ }
373
+ interface LogoutInput {
374
+ accessToken?: string;
375
+ accessTokenJti?: string;
376
+ userId?: string;
377
+ sessionId?: string;
378
+ logoutAll?: boolean;
379
+ }
380
+ interface TwoFactorSetupResult {
381
+ secret: string;
382
+ uri: string;
383
+ }
384
+ interface TwoFactorVerifyInput {
385
+ token: string;
386
+ secret: string;
387
+ }
388
+ declare class AuthService {
389
+ readonly tokenManager: TokenManager;
390
+ readonly tokenRevocation: TokenRevocation;
391
+ readonly sessionManager: SessionManager;
392
+ readonly accountLockout: AccountLockout;
393
+ readonly totpManager: TotpManager;
394
+ readonly audit: AuditLog;
395
+ readonly errors: ErrorFactory;
396
+ private readonly config;
397
+ private readonly userStore;
398
+ constructor(rawConfig: AuthCoreConfig);
399
+ getConfig(): ResolvedConfig;
400
+ getRedis(): AuthCoreConfig["redis"];
401
+ exchange(input: ExchangeInput): Promise<ExchangeResult>;
402
+ verifyToken(input: VerifyTokenInput): Promise<VerifyTokenResult>;
403
+ refresh(input: RefreshInput): Promise<RefreshResult>;
404
+ logout(input: LogoutInput): Promise<void>;
405
+ getActiveSessions(userId: string): Promise<{
406
+ sessionId: string;
407
+ deviceInfo: string;
408
+ ipAddress?: string;
409
+ lastActivity: string;
410
+ createdAt: string;
411
+ }[]>;
412
+ revokeSession(userId: string, sessionId: string): Promise<void>;
413
+ generateTwoFactor(): TwoFactorSetupResult;
414
+ createTwoFactorUri(secret: string, email: string): string;
415
+ verifyTwoFactor(input: TwoFactorVerifyInput): Promise<boolean>;
416
+ recordLoginFailure(email: string): Promise<{
417
+ locked: boolean;
418
+ unlocksAt?: Date;
419
+ attempts: number;
420
+ }>;
421
+ clearLoginFailures(email: string): Promise<void>;
422
+ isAccountLocked(email: string): Promise<{
423
+ locked: boolean;
424
+ unlocksAt?: Date;
425
+ }>;
426
+ log(event: AuditEventType, data: Record<string, unknown>): void;
427
+ }
428
+
429
+ declare class RefreshLock {
430
+ private readonly redis;
431
+ private readonly prefix;
432
+ constructor(redis: RedisAdapter, prefix?: string);
433
+ private lockKey;
434
+ acquire(sessionId: string): Promise<boolean>;
435
+ release(sessionId: string): Promise<void>;
436
+ isLocked(sessionId: string): Promise<boolean>;
437
+ }
438
+
439
+ declare function looksLikeServerToServerUA(userAgent: string): boolean;
440
+ declare function looksLikeServerToServerRequest(req: {
441
+ headers: Record<string, string | string[] | undefined>;
442
+ }): boolean;
443
+ declare function normalizeUserAgent(userAgent: string): string;
444
+ declare function generateDeviceFingerprint(req: {
445
+ headers: Record<string, string | string[] | undefined>;
446
+ }): string;
447
+ declare function getClientIp(req: {
448
+ ip?: string;
449
+ headers: Record<string, string | string[] | undefined>;
450
+ socket?: {
451
+ remoteAddress?: string;
452
+ };
453
+ }): string;
454
+ declare function createSessionMetadata(req: {
455
+ ip?: string;
456
+ headers: Record<string, string | string[] | undefined>;
457
+ socket?: {
458
+ remoteAddress?: string;
459
+ };
460
+ }): SessionMetadata;
461
+ declare function isPrivateIp(ip: string): boolean;
462
+ declare function validateSessionBinding(req: {
463
+ headers: Record<string, string | string[] | undefined>;
464
+ ip?: string;
465
+ socket?: {
466
+ remoteAddress?: string;
467
+ };
468
+ }, storedMetadata: SessionMetadata): {
469
+ valid: boolean;
470
+ reason?: string;
471
+ };
472
+
336
473
  declare class SessionTimeoutManager implements SessionLifecycle {
337
474
  private readonly redis;
338
475
  private readonly inactivityTimeout;
@@ -352,54 +489,6 @@ declare class SessionTimeoutManager implements SessionLifecycle {
352
489
  updateActivity(sessionId: string): Promise<boolean>;
353
490
  }
354
491
 
355
- declare const DEFAULTS: {
356
- readonly keyPrefix: "focura:";
357
- readonly issuer: "focura-app";
358
- readonly audience: "focura-backend";
359
- readonly accessTokenExpiry: "15m";
360
- readonly refreshTokenExpiry: "7d";
361
- readonly sseTokenExpiry: "30s";
362
- readonly currentVersion: 1;
363
- readonly maxConcurrentSessions: 5;
364
- readonly sessionMetadataTtl: number;
365
- readonly lockoutMaxFailures: 10;
366
- readonly lockoutSeconds: number;
367
- readonly lockoutWindowSeconds: number;
368
- readonly refreshLockTtlSeconds: 45;
369
- readonly refreshDedupeTtlSeconds: 30;
370
- readonly revokedSessionTtl: number;
371
- readonly inactivityTimeout: number;
372
- readonly absoluteTimeout: number;
373
- };
374
- declare function resolveConfig(raw: AuthCoreConfig): {
375
- keyPrefix: string;
376
- issuer: string;
377
- audience: string;
378
- accessTokenExpiry: string;
379
- refreshTokenExpiry: string;
380
- sseTokenExpiry: string;
381
- currentVersion: number;
382
- maxConcurrentSessions: number;
383
- sessionMetadataTtl: number;
384
- lockoutMaxFailures: number;
385
- lockoutSeconds: number;
386
- lockoutWindowSeconds: number;
387
- inactivityTimeout: number;
388
- absoluteTimeout: number;
389
- redis: RedisAdapter;
390
- userStore: UserStore;
391
- hmacSecret: string;
392
- jwt: TokenConfig;
393
- cache?: CacheAdapter;
394
- auditLogger?: AuditLogger;
395
- observability?: ObservabilitySink;
396
- errors?: ErrorFactory;
397
- lockout?: LockoutConfig;
398
- session?: SessionConfig;
399
- };
400
- type ResolvedConfig = ReturnType<typeof resolveConfig>;
401
- declare const AUDIT_SEVERITY: Record<AuditEventType, AuditSeverity>;
402
-
403
492
  interface AuthRequest {
404
493
  user?: {
405
494
  id: string;
@@ -590,4 +679,4 @@ declare class ValidationError extends Error {
590
679
 
591
680
  declare const defaultErrors: ErrorFactory;
592
681
 
593
- export { AUDIT_SEVERITY, AccountBannedError, AccountLockout, type AuditEventType, AuditLog, type AuditLogger, type AuditSeverity, type AuthCoreConfig, type AuthRequest, BadRequestError, type CacheAdapter, DEFAULTS, type DeviceFingerprint, EmailNotVerifiedError, type ErrorFactory, ForbiddenError, InvalidTokenError, type LockoutConfig, MiddlewareFactory, type ObservabilitySink, type RateLimiterFactory, type RedisAdapter, type RedisPipeline, RefreshLock, type ResolvedConfig, type SessionConfig, SessionHijackError, type SessionLifecycle, SessionManager, type SessionMetadata, SessionTimeoutManager, type TokenConfig, TokenExpiredError, TokenManager, type TokenPair, type TokenPayload, TokenRevocation, TokenRevokedError, TotpManager, UnauthorizedError, type User, type UserStore, ValidationError, type ZodSchema, createSessionMetadata, defaultErrors, exchangeSchema, generateDeviceFingerprint, getClientIp, isPrivateIp, logoutSchema, looksLikeServerToServerRequest, looksLikeServerToServerUA, normalizeUserAgent, refreshSchema, resolveConfig, validateSessionBinding };
682
+ export { AUDIT_SEVERITY, AccountBannedError, AccountLockout, type AuditEventType, AuditLog, type AuditLogger, type AuditSeverity, type AuthCoreConfig, type RefreshResult as AuthRefreshResult, type AuthRequest, AuthService, BadRequestError, type CacheAdapter, DEFAULTS, type DeviceFingerprint, EmailNotVerifiedError, type ErrorFactory, type ExchangeInput, type ExchangeResult, ForbiddenError, InvalidTokenError, type LockoutConfig, type LogoutInput, MiddlewareFactory, type ObservabilitySink, type RateLimiterFactory, type RedisAdapter, type RedisPipeline, type RefreshInput, RefreshLock, type ResolvedConfig, type SessionConfig, SessionHijackError, type SessionLifecycle, SessionManager, type SessionMetadata, SessionTimeoutManager, type TokenConfig, TokenExpiredError, TokenManager, type TokenPair, type TokenPayload, TokenRevocation, TokenRevokedError, TotpManager, type TwoFactorSetupResult, type TwoFactorVerifyInput, UnauthorizedError, type User, type UserStore, ValidationError, type VerifyTokenInput, type VerifyTokenResult, type ZodSchema, createSessionMetadata, defaultErrors, exchangeSchema, generateDeviceFingerprint, getClientIp, isPrivateIp, logoutSchema, looksLikeServerToServerRequest, looksLikeServerToServerUA, normalizeUserAgent, refreshSchema, resolveConfig, validateSessionBinding };