@xbg.solutions/utils-token-handler 1.0.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.
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * Generic Token Handler
4
+ * Platform-agnostic token handling with configurable auth providers
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.TokenHandler = void 0;
8
+ exports.createTokenHandler = createTokenHandler;
9
+ const token_types_1 = require("./token-types");
10
+ const token_blacklist_manager_1 = require("./token-blacklist-manager");
11
+ class TokenHandler {
12
+ constructor(config, adapter) {
13
+ this.config = config;
14
+ this.adapter = adapter;
15
+ this.blacklistManager = new token_blacklist_manager_1.TokenBlacklistManager(this.config.database, this.config.blacklist);
16
+ }
17
+ /**
18
+ * Verify and unpack raw token string
19
+ * Returns normalized token if valid, or error details if invalid
20
+ */
21
+ async verifyAndUnpack(rawToken, logger) {
22
+ logger.debug('TokenHandler: Starting token verification');
23
+ try {
24
+ // Step 1: Verify token with auth provider
25
+ const providerToken = await this.adapter.verifyToken(rawToken, logger);
26
+ logger.debug('TokenHandler: Token verified by provider', {
27
+ authUID: this.extractAuthUID(providerToken)
28
+ });
29
+ // Step 2: Check if token is individually blacklisted
30
+ const tokenIdentifier = await this.adapter.getTokenIdentifier(rawToken);
31
+ const isIndividuallyBlacklisted = await this.blacklistManager.isBlacklisted(tokenIdentifier, logger);
32
+ if (isIndividuallyBlacklisted) {
33
+ logger.warn('TokenHandler: Token is individually blacklisted', {
34
+ authUID: this.extractAuthUID(providerToken)
35
+ });
36
+ return {
37
+ isValid: false,
38
+ isBlacklisted: true,
39
+ token: null,
40
+ error: token_types_1.TokenVerificationError.BLACKLISTED
41
+ };
42
+ }
43
+ // Step 3: Check if user has global token revocation
44
+ const authUID = this.extractAuthUID(providerToken);
45
+ const revocationTime = await this.blacklistManager.getUserTokenRevocationTime(authUID, logger);
46
+ if (revocationTime) {
47
+ const tokenIssuedAt = this.extractIssuedAt(providerToken);
48
+ const tokenIssuedDate = new Date(tokenIssuedAt * 1000);
49
+ if (tokenIssuedDate < revocationTime) {
50
+ logger.warn('TokenHandler: Token issued before global revocation', {
51
+ authUID,
52
+ tokenIssuedAt: tokenIssuedDate,
53
+ // Don't log revocation time for privacy
54
+ });
55
+ return {
56
+ isValid: false,
57
+ isBlacklisted: true,
58
+ token: null,
59
+ error: token_types_1.TokenVerificationError.BLACKLISTED
60
+ };
61
+ }
62
+ }
63
+ // Step 4: Normalize token to platform-agnostic structure
64
+ const normalizedToken = this.adapter.normalizeToken(providerToken, this.config.customClaims);
65
+ logger.debug('TokenHandler: Token verified and normalized', {
66
+ authUID: normalizedToken.authUID,
67
+ userUID: normalizedToken.userUID,
68
+ issuer: normalizedToken.issuer
69
+ });
70
+ return {
71
+ isValid: true,
72
+ isBlacklisted: false,
73
+ token: normalizedToken,
74
+ error: null
75
+ };
76
+ }
77
+ catch (error) {
78
+ logger.warn('TokenHandler: Token verification failed', {
79
+ error: error.message
80
+ });
81
+ // Map provider errors to our error types
82
+ const verificationError = this.adapter.mapProviderError(error);
83
+ return {
84
+ isValid: false,
85
+ isBlacklisted: false,
86
+ token: null,
87
+ error: verificationError
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Generate token identifier for blacklist lookup
93
+ */
94
+ async getTokenIdentifier(rawToken) {
95
+ return this.adapter.getTokenIdentifier(rawToken);
96
+ }
97
+ /**
98
+ * Sync custom claims to auth provider
99
+ */
100
+ async syncCustomClaims(authUID, claims, logger) {
101
+ logger.debug('TokenHandler: Syncing custom claims', {
102
+ authUID,
103
+ provider: this.config.provider.type
104
+ });
105
+ await this.adapter.syncCustomClaims(authUID, claims, logger);
106
+ }
107
+ /**
108
+ * Revoke all tokens for a user at provider level
109
+ */
110
+ async revokeUserTokens(authUID, logger) {
111
+ logger.info('TokenHandler: Revoking user tokens at provider level', {
112
+ authUID,
113
+ provider: this.config.provider.type
114
+ });
115
+ return this.adapter.revokeUserTokens(authUID, logger);
116
+ }
117
+ /**
118
+ * Blacklist individual token
119
+ */
120
+ async blacklistToken(tokenIdentifier, authUID, reason, tokenExpiresAt, blacklistedBy, logger) {
121
+ return this.blacklistManager.blacklistToken(tokenIdentifier, authUID, reason, tokenExpiresAt, blacklistedBy, logger);
122
+ }
123
+ /**
124
+ * Blacklist all tokens for a user (global revocation)
125
+ */
126
+ async blacklistAllUserTokens(authUID, reason, blacklistedBy, logger) {
127
+ return this.blacklistManager.blacklistAllUserTokens(authUID, reason, blacklistedBy, logger);
128
+ }
129
+ /**
130
+ * Check if token is blacklisted
131
+ */
132
+ async isTokenBlacklisted(tokenIdentifier, logger) {
133
+ return this.blacklistManager.isBlacklisted(tokenIdentifier, logger);
134
+ }
135
+ /**
136
+ * Get user's token revocation timestamp
137
+ */
138
+ async getUserTokenRevocationTime(authUID, logger) {
139
+ return this.blacklistManager.getUserTokenRevocationTime(authUID, logger);
140
+ }
141
+ /**
142
+ * Cleanup expired blacklist entries
143
+ */
144
+ async cleanupExpiredEntries(logger) {
145
+ return this.blacklistManager.cleanupExpiredEntries(logger);
146
+ }
147
+ /**
148
+ * Get token handler configuration
149
+ */
150
+ getConfig() {
151
+ return Object.assign({}, this.config);
152
+ }
153
+ /**
154
+ * Extract authUID from provider token
155
+ * Different providers may structure this differently
156
+ */
157
+ extractAuthUID(providerToken) {
158
+ // Common patterns for different providers
159
+ return providerToken.uid || providerToken.sub || providerToken.user_id || '';
160
+ }
161
+ /**
162
+ * Extract issued-at timestamp from provider token
163
+ * Different providers may structure this differently
164
+ */
165
+ extractIssuedAt(providerToken) {
166
+ return providerToken.iat || providerToken.issued_at || Math.floor(Date.now() / 1000);
167
+ }
168
+ }
169
+ exports.TokenHandler = TokenHandler;
170
+ /**
171
+ * Factory function to create token handler with type safety
172
+ */
173
+ function createTokenHandler(config, adapter) {
174
+ return new TokenHandler(config, adapter);
175
+ }
176
+ //# sourceMappingURL=generic-token-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic-token-handler.js","sourceRoot":"","sources":["../src/generic-token-handler.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Token Handler Utility - Barrel Export
3
+ * Portable, configurable token handling with auth provider abstraction
4
+ */
5
+ export * from './token-types';
6
+ export * from './generic-token-handler';
7
+ export * from './token-blacklist-manager';
8
+ export * from './firebase-adapter';
9
+ export * from './firestore-database-adapter';
10
+ export { createTokenHandler } from './generic-token-handler';
11
+ export { createTokenBlacklistManager } from './token-blacklist-manager';
12
+ export { createFirebaseAuthAdapter } from './firebase-adapter';
13
+ export { createFirestoreTokenDatabase } from './firestore-database-adapter';
14
+ /**
15
+ * Quick-start factory for Firebase-based token handling
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const handler = createFirebaseTokenHandler({
20
+ * customClaims: {
21
+ * extract: (token) => ({ userID: token.userID }),
22
+ * defaults: { userID: null }
23
+ * },
24
+ * blacklist: {
25
+ * storage: { database: 'main', collection: 'blacklist' },
26
+ * retention: { cleanupRetentionDays: 30, globalRevocationRetentionDays: 30 },
27
+ * reasons: ['LOGOUT', 'PASSWORD_CHANGE']
28
+ * },
29
+ * database: firestoreInstance
30
+ * });
31
+ * ```
32
+ */
33
+ export declare function createFirebaseTokenHandler<TCustomClaims = Record<string, any>>(config: {
34
+ customClaims: {
35
+ extract: (token: any) => TCustomClaims;
36
+ validate?: (claims: TCustomClaims) => boolean;
37
+ defaults: Partial<TCustomClaims>;
38
+ };
39
+ blacklist: {
40
+ storage: {
41
+ database: string;
42
+ collection: string;
43
+ };
44
+ retention: {
45
+ cleanupRetentionDays: number;
46
+ globalRevocationRetentionDays: number;
47
+ };
48
+ reasons: string[];
49
+ };
50
+ database: any;
51
+ }): any;
52
+ /**
53
+ * Quick-start factory for Auth0-based token handling
54
+ * Future implementation when Auth0 adapter is available
55
+ */
56
+ export declare function createAuth0TokenHandler<_TCustomClaims = Record<string, any>>(_config: any): void;
57
+ /**
58
+ * Quick-start factory for Clerk-based token handling
59
+ * Future implementation when Clerk adapter is available
60
+ */
61
+ export declare function createClerkTokenHandler<_TCustomClaims = Record<string, any>>(_config: any): void;
62
+ /**
63
+ * Version and metadata
64
+ */
65
+ export declare const TOKEN_HANDLER_VERSION = "2.0.0";
66
+ export declare const SUPPORTED_PROVIDERS: readonly ["firebase"];
67
+ /**
68
+ * Utility function to validate token handler configuration
69
+ */
70
+ export declare function validateTokenHandlerConfig(config: any): boolean;
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,eAAe,CAAC;AAG9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAG1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAG7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAE5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE;IACtF,YAAY,EAAE;QACZ,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,aAAa,CAAC;QACvC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC;QAC9C,QAAQ,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;KAClC,CAAC;IACF,SAAS,EAAE;QACT,OAAO,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC;QAClD,SAAS,EAAE;YAAE,oBAAoB,EAAE,MAAM,CAAC;YAAC,6BAA6B,EAAE,MAAM,CAAA;SAAE,CAAC;QACnF,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,QAAQ,EAAE,GAAG,CAAC;CACf,OAuBA;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,QAEzF;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,QAEzF;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,UAAU,CAAC;AAC7C,eAAO,MAAM,mBAAmB,uBAAwB,CAAC;AAEzD;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,GAAG,GACV,OAAO,CAST"}
package/lib/index.js ADDED
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ /**
3
+ * Token Handler Utility - Barrel Export
4
+ * Portable, configurable token handling with auth provider abstraction
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.SUPPORTED_PROVIDERS = exports.TOKEN_HANDLER_VERSION = exports.createFirestoreTokenDatabase = exports.createFirebaseAuthAdapter = exports.createTokenBlacklistManager = exports.createTokenHandler = void 0;
22
+ exports.createFirebaseTokenHandler = createFirebaseTokenHandler;
23
+ exports.createAuth0TokenHandler = createAuth0TokenHandler;
24
+ exports.createClerkTokenHandler = createClerkTokenHandler;
25
+ exports.validateTokenHandlerConfig = validateTokenHandlerConfig;
26
+ // Core types and interfaces
27
+ __exportStar(require("./token-types"), exports);
28
+ // Generic implementations
29
+ __exportStar(require("./generic-token-handler"), exports);
30
+ __exportStar(require("./token-blacklist-manager"), exports);
31
+ // Adapters
32
+ __exportStar(require("./firebase-adapter"), exports);
33
+ __exportStar(require("./firestore-database-adapter"), exports);
34
+ // Factory functions for common configurations
35
+ var generic_token_handler_1 = require("./generic-token-handler");
36
+ Object.defineProperty(exports, "createTokenHandler", { enumerable: true, get: function () { return generic_token_handler_1.createTokenHandler; } });
37
+ var token_blacklist_manager_1 = require("./token-blacklist-manager");
38
+ Object.defineProperty(exports, "createTokenBlacklistManager", { enumerable: true, get: function () { return token_blacklist_manager_1.createTokenBlacklistManager; } });
39
+ var firebase_adapter_1 = require("./firebase-adapter");
40
+ Object.defineProperty(exports, "createFirebaseAuthAdapter", { enumerable: true, get: function () { return firebase_adapter_1.createFirebaseAuthAdapter; } });
41
+ var firestore_database_adapter_1 = require("./firestore-database-adapter");
42
+ Object.defineProperty(exports, "createFirestoreTokenDatabase", { enumerable: true, get: function () { return firestore_database_adapter_1.createFirestoreTokenDatabase; } });
43
+ /**
44
+ * Quick-start factory for Firebase-based token handling
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const handler = createFirebaseTokenHandler({
49
+ * customClaims: {
50
+ * extract: (token) => ({ userID: token.userID }),
51
+ * defaults: { userID: null }
52
+ * },
53
+ * blacklist: {
54
+ * storage: { database: 'main', collection: 'blacklist' },
55
+ * retention: { cleanupRetentionDays: 30, globalRevocationRetentionDays: 30 },
56
+ * reasons: ['LOGOUT', 'PASSWORD_CHANGE']
57
+ * },
58
+ * database: firestoreInstance
59
+ * });
60
+ * ```
61
+ */
62
+ function createFirebaseTokenHandler(config) {
63
+ const { createTokenHandler } = require('./generic-token-handler');
64
+ const { createFirebaseAuthAdapter } = require('./adapters/firebase-auth-adapter');
65
+ const { createFirestoreTokenDatabase } = require('./adapters/firestore-database-adapter');
66
+ // Create database adapter
67
+ const tokenDatabase = createFirestoreTokenDatabase(config.database, config.blacklist.storage.collection);
68
+ // Create auth adapter
69
+ const authAdapter = createFirebaseAuthAdapter();
70
+ // Build complete configuration
71
+ const handlerConfig = {
72
+ customClaims: config.customClaims,
73
+ blacklist: config.blacklist,
74
+ provider: { type: 'firebase' },
75
+ database: tokenDatabase
76
+ };
77
+ return createTokenHandler(handlerConfig, authAdapter);
78
+ }
79
+ /**
80
+ * Quick-start factory for Auth0-based token handling
81
+ * Future implementation when Auth0 adapter is available
82
+ */
83
+ function createAuth0TokenHandler(_config) {
84
+ throw new Error('Auth0 adapter not yet implemented. Use createFirebaseTokenHandler for now.');
85
+ }
86
+ /**
87
+ * Quick-start factory for Clerk-based token handling
88
+ * Future implementation when Clerk adapter is available
89
+ */
90
+ function createClerkTokenHandler(_config) {
91
+ throw new Error('Clerk adapter not yet implemented. Use createFirebaseTokenHandler for now.');
92
+ }
93
+ /**
94
+ * Version and metadata
95
+ */
96
+ exports.TOKEN_HANDLER_VERSION = '2.0.0';
97
+ exports.SUPPORTED_PROVIDERS = ['firebase'];
98
+ /**
99
+ * Utility function to validate token handler configuration
100
+ */
101
+ function validateTokenHandlerConfig(config) {
102
+ return (config &&
103
+ typeof config === 'object' &&
104
+ config.customClaims &&
105
+ config.blacklist &&
106
+ config.provider &&
107
+ config.database);
108
+ }
109
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;AAsCH,gEAmCC;AAMD,0DAEC;AAMD,0DAEC;AAWD,gEAWC;AA7GD,4BAA4B;AAC5B,gDAA8B;AAE9B,0BAA0B;AAC1B,0DAAwC;AACxC,4DAA0C;AAE1C,WAAW;AACX,qDAAmC;AACnC,+DAA6C;AAE7C,8CAA8C;AAC9C,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAC3B,qEAAwE;AAA/D,sIAAA,2BAA2B,OAAA;AACpC,uDAA+D;AAAtD,6HAAA,yBAAyB,OAAA;AAClC,2EAA4E;AAAnE,0IAAA,4BAA4B,OAAA;AAErC;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,0BAA0B,CAAsC,MAY/E;IACC,MAAM,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAClE,MAAM,EAAE,yBAAyB,EAAE,GAAG,OAAO,CAAC,kCAAkC,CAAC,CAAC;IAClF,MAAM,EAAE,4BAA4B,EAAE,GAAG,OAAO,CAAC,uCAAuC,CAAC,CAAC;IAE1F,0BAA0B;IAC1B,MAAM,aAAa,GAAG,4BAA4B,CAChD,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,UAAU,CACpC,CAAC;IAEF,sBAAsB;IACtB,MAAM,WAAW,GAAG,yBAAyB,EAAE,CAAC;IAEhD,+BAA+B;IAC/B,MAAM,aAAa,GAAG;QACpB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAmB,EAAE;QACvC,QAAQ,EAAE,aAAa;KACxB,CAAC;IAEF,OAAO,kBAAkB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CAAuC,OAAY;IACxF,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;AAChG,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CAAuC,OAAY;IACxF,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;AAChG,CAAC;AAED;;GAEG;AACU,QAAA,qBAAqB,GAAG,OAAO,CAAC;AAChC,QAAA,mBAAmB,GAAG,CAAC,UAAU,CAAU,CAAC;AAEzD;;GAEG;AACH,SAAgB,0BAA0B,CACxC,MAAW;IAEX,OAAO,CACL,MAAM;QACN,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,SAAS;QAChB,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,QAAQ,CAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Token Blacklist Manager
3
+ * Generic token blacklist implementation with configurable database backend
4
+ */
5
+ import { Logger } from '@xbg/utils-logger';
6
+ import { TokenBlacklistEntry, ITokenDatabase, BlacklistConfig } from './token-types';
7
+ export declare class TokenBlacklistManager {
8
+ private database;
9
+ private config;
10
+ constructor(database: ITokenDatabase, config: BlacklistConfig);
11
+ /**
12
+ * Add token to blacklist
13
+ *
14
+ * @param tokenIdentifier - Token JTI or hash
15
+ * @param authUID - User who owned this token
16
+ * @param reason - Reason for blacklisting (must be in configured reasons)
17
+ * @param tokenExpiresAt - When token would naturally expire
18
+ * @param blacklistedBy - Optional userUID who triggered blacklist
19
+ * @param logger - Logger instance
20
+ */
21
+ blacklistToken(tokenIdentifier: string, authUID: string, reason: string, tokenExpiresAt: Date, blacklistedBy: string | null, logger: Logger): Promise<TokenBlacklistEntry>;
22
+ /**
23
+ * Check if token is blacklisted
24
+ *
25
+ * @param tokenIdentifier - Token JTI or hash
26
+ * @param logger - Logger instance
27
+ * @returns true if blacklisted, false otherwise
28
+ */
29
+ isBlacklisted(tokenIdentifier: string, logger: Logger): Promise<boolean>;
30
+ /**
31
+ * Blacklist all tokens for a user (global revocation)
32
+ * Used when user logs out all sessions, changes password, or account deleted
33
+ *
34
+ * This creates a revocation timestamp. Token verification checks:
35
+ * is token issued before this timestamp?
36
+ *
37
+ * @param authUID - User's auth UID
38
+ * @param reason - Reason for blacklisting (must be in configured reasons)
39
+ * @param blacklistedBy - Optional userUID who triggered blacklist
40
+ * @param logger - Logger instance
41
+ */
42
+ blacklistAllUserTokens(authUID: string, reason: string, blacklistedBy: string | null, logger: Logger): Promise<void>;
43
+ /**
44
+ * Check if user has a global token revocation
45
+ * Returns the timestamp of revocation if exists
46
+ *
47
+ * @param authUID - User's auth UID
48
+ * @param logger - Logger instance
49
+ * @returns Date of revocation, or null if no global revocation
50
+ */
51
+ getUserTokenRevocationTime(authUID: string, logger: Logger): Promise<Date | null>;
52
+ /**
53
+ * Cleanup expired blacklist entries
54
+ * Run via CRON job periodically
55
+ *
56
+ * @param logger - Logger instance
57
+ * @returns Number of entries deleted
58
+ */
59
+ cleanupExpiredEntries(logger: Logger): Promise<number>;
60
+ /**
61
+ * Get blacklist configuration
62
+ */
63
+ getConfig(): BlacklistConfig;
64
+ /**
65
+ * Validate that reason is allowed by configuration
66
+ */
67
+ private validateReason;
68
+ /**
69
+ * Mask token identifier for logging (security)
70
+ * Shows first 10 characters + ...
71
+ */
72
+ private maskTokenIdentifier;
73
+ }
74
+ /**
75
+ * Factory function to create blacklist manager
76
+ */
77
+ export declare function createTokenBlacklistManager(database: ITokenDatabase, config: BlacklistConfig): TokenBlacklistManager;
78
+ //# sourceMappingURL=token-blacklist-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-blacklist-manager.d.ts","sourceRoot":"","sources":["../src/token-blacklist-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,eAAe,EAChB,MAAM,eAAe,CAAC;AAGvB,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;gBADN,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,eAAe;IAGjC;;;;;;;;;OASG;IACG,cAAc,CAClB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,IAAI,EACpB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC;IAiC/B;;;;;;OAMG;IACG,aAAa,CACjB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;IAenB;;;;;;;;;;;OAWG;IACG,sBAAsB,CAC1B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAsBhB;;;;;;;OAOG;IACG,0BAA0B,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAgBvB;;;;;;OAMG;IACG,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB5D;;OAEG;IACH,SAAS,IAAI,eAAe;IAI5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;;OAGG;IACH,OAAO,CAAC,mBAAmB;CAM5B;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,eAAe,GACtB,qBAAqB,CAEvB"}
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ /**
3
+ * Token Blacklist Manager
4
+ * Generic token blacklist implementation with configurable database backend
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.TokenBlacklistManager = void 0;
8
+ exports.createTokenBlacklistManager = createTokenBlacklistManager;
9
+ const uuid_1 = require("uuid");
10
+ class TokenBlacklistManager {
11
+ constructor(database, config) {
12
+ this.database = database;
13
+ this.config = config;
14
+ }
15
+ /**
16
+ * Add token to blacklist
17
+ *
18
+ * @param tokenIdentifier - Token JTI or hash
19
+ * @param authUID - User who owned this token
20
+ * @param reason - Reason for blacklisting (must be in configured reasons)
21
+ * @param tokenExpiresAt - When token would naturally expire
22
+ * @param blacklistedBy - Optional userUID who triggered blacklist
23
+ * @param logger - Logger instance
24
+ */
25
+ async blacklistToken(tokenIdentifier, authUID, reason, tokenExpiresAt, blacklistedBy, logger) {
26
+ // Validate reason against configured reasons
27
+ this.validateReason(reason, logger);
28
+ logger.debug('TokenBlacklistManager: Adding token to blacklist', {
29
+ tokenIdentifier: this.maskTokenIdentifier(tokenIdentifier),
30
+ authUID,
31
+ reason,
32
+ database: this.config.storage.database,
33
+ collection: this.config.storage.collection
34
+ });
35
+ const entry = {
36
+ blacklistEntryUID: (0, uuid_1.v4)(),
37
+ tokenJTI: tokenIdentifier,
38
+ authUID,
39
+ blacklistedAt: new Date(),
40
+ blacklistedBy,
41
+ reason,
42
+ expiresAt: tokenExpiresAt
43
+ };
44
+ await this.database.addBlacklistEntry(entry);
45
+ logger.info('TokenBlacklistManager: Token blacklisted successfully', {
46
+ blacklistEntryUID: entry.blacklistEntryUID,
47
+ authUID,
48
+ reason
49
+ });
50
+ return entry;
51
+ }
52
+ /**
53
+ * Check if token is blacklisted
54
+ *
55
+ * @param tokenIdentifier - Token JTI or hash
56
+ * @param logger - Logger instance
57
+ * @returns true if blacklisted, false otherwise
58
+ */
59
+ async isBlacklisted(tokenIdentifier, logger) {
60
+ logger.debug('TokenBlacklistManager: Checking if token is blacklisted', {
61
+ tokenIdentifier: this.maskTokenIdentifier(tokenIdentifier)
62
+ });
63
+ const isBlacklisted = await this.database.isTokenBlacklisted(tokenIdentifier);
64
+ logger.debug('TokenBlacklistManager: Blacklist check result', {
65
+ tokenIdentifier: this.maskTokenIdentifier(tokenIdentifier),
66
+ isBlacklisted
67
+ });
68
+ return isBlacklisted;
69
+ }
70
+ /**
71
+ * Blacklist all tokens for a user (global revocation)
72
+ * Used when user logs out all sessions, changes password, or account deleted
73
+ *
74
+ * This creates a revocation timestamp. Token verification checks:
75
+ * is token issued before this timestamp?
76
+ *
77
+ * @param authUID - User's auth UID
78
+ * @param reason - Reason for blacklisting (must be in configured reasons)
79
+ * @param blacklistedBy - Optional userUID who triggered blacklist
80
+ * @param logger - Logger instance
81
+ */
82
+ async blacklistAllUserTokens(authUID, reason, blacklistedBy, logger) {
83
+ // Validate reason against configured reasons
84
+ this.validateReason(reason, logger);
85
+ logger.info('TokenBlacklistManager: Blacklisting all tokens for user', {
86
+ authUID,
87
+ reason
88
+ });
89
+ const expiresAt = new Date(Date.now() + this.config.retention.globalRevocationRetentionDays * 24 * 60 * 60 * 1000);
90
+ await this.database.addUserRevocation(authUID, reason, blacklistedBy, expiresAt);
91
+ logger.info('TokenBlacklistManager: All user tokens blacklisted', {
92
+ authUID,
93
+ reason,
94
+ expiresAt
95
+ });
96
+ }
97
+ /**
98
+ * Check if user has a global token revocation
99
+ * Returns the timestamp of revocation if exists
100
+ *
101
+ * @param authUID - User's auth UID
102
+ * @param logger - Logger instance
103
+ * @returns Date of revocation, or null if no global revocation
104
+ */
105
+ async getUserTokenRevocationTime(authUID, logger) {
106
+ logger.debug('TokenBlacklistManager: Checking user token revocation', {
107
+ authUID
108
+ });
109
+ const revocationTime = await this.database.getUserRevocationTime(authUID);
110
+ logger.debug('TokenBlacklistManager: User revocation check result', {
111
+ authUID,
112
+ hasRevocation: revocationTime !== null,
113
+ // Don't log the actual timestamp for privacy
114
+ });
115
+ return revocationTime;
116
+ }
117
+ /**
118
+ * Cleanup expired blacklist entries
119
+ * Run via CRON job periodically
120
+ *
121
+ * @param logger - Logger instance
122
+ * @returns Number of entries deleted
123
+ */
124
+ async cleanupExpiredEntries(logger) {
125
+ logger.info('TokenBlacklistManager: Starting cleanup of expired entries', {
126
+ database: this.config.storage.database,
127
+ collection: this.config.storage.collection
128
+ });
129
+ const deletedCount = await this.database.cleanupExpiredEntries();
130
+ logger.info('TokenBlacklistManager: Cleanup completed', {
131
+ deletedCount,
132
+ database: this.config.storage.database,
133
+ collection: this.config.storage.collection
134
+ });
135
+ return deletedCount;
136
+ }
137
+ /**
138
+ * Get blacklist configuration
139
+ */
140
+ getConfig() {
141
+ return Object.assign({}, this.config);
142
+ }
143
+ /**
144
+ * Validate that reason is allowed by configuration
145
+ */
146
+ validateReason(reason, logger) {
147
+ if (!this.config.reasons.includes(reason)) {
148
+ const error = new Error(`Invalid blacklist reason: ${reason}. Allowed reasons: ${this.config.reasons.join(', ')}`);
149
+ logger.error('TokenBlacklistManager: Invalid blacklist reason', error, {
150
+ providedReason: reason,
151
+ allowedReasons: this.config.reasons
152
+ });
153
+ throw error;
154
+ }
155
+ }
156
+ /**
157
+ * Mask token identifier for logging (security)
158
+ * Shows first 10 characters + ...
159
+ */
160
+ maskTokenIdentifier(tokenIdentifier) {
161
+ if (tokenIdentifier.length <= 10) {
162
+ return tokenIdentifier;
163
+ }
164
+ return tokenIdentifier.substring(0, 10) + '...';
165
+ }
166
+ }
167
+ exports.TokenBlacklistManager = TokenBlacklistManager;
168
+ /**
169
+ * Factory function to create blacklist manager
170
+ */
171
+ function createTokenBlacklistManager(database, config) {
172
+ return new TokenBlacklistManager(database, config);
173
+ }
174
+ //# sourceMappingURL=token-blacklist-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-blacklist-manager.js","sourceRoot":"","sources":["../src/token-blacklist-manager.ts"],"names":[],"mappings":"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"}