@focura/auth-core 1.0.0 → 1.1.1
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 +407 -25
- package/dist/index.d.ts +182 -93
- package/dist/index.js +410 -131
- package/dist/index.js.map +1 -1
- package/package.json +23 -5
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 };
|