ts-packages 2.0.0 → 3.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.
- package/package.json +1 -1
- package/packages/cache/README.md +105 -9
- package/packages/cache/dist/cjs/adapters/memcache/MemcacheCache.d.ts +1 -54
- package/packages/cache/dist/cjs/adapters/memcache/MemcacheCache.js +75 -281
- package/packages/cache/dist/cjs/adapters/memory/MemoryCache.js +76 -22
- package/packages/cache/dist/cjs/adapters/redis/RedisCache.js +84 -26
- package/packages/cache/dist/cjs/core/BaseCache.js +13 -4
- package/packages/cache/dist/cjs/core/factory.js +26 -4
- package/packages/cache/dist/cjs/errors/CacheError.d.ts +10 -7
- package/packages/cache/dist/cjs/errors/CacheError.js +6 -11
- package/packages/cache/dist/cjs/errors/cacheErrorCodes.d.ts +22 -0
- package/packages/cache/dist/cjs/errors/cacheErrorCodes.js +24 -0
- package/packages/cache/dist/cjs/errors/index.js +3 -0
- package/packages/cache/dist/cjs/middleware/express/cacheMiddleware.js +8 -8
- package/packages/cache/dist/cjs/session/SessionStore.js +84 -28
- package/packages/cache/dist/esm/adapters/memcache/MemcacheCache.d.ts +1 -54
- package/packages/cache/dist/esm/adapters/memcache/MemcacheCache.js +75 -281
- package/packages/cache/dist/esm/adapters/memory/MemoryCache.js +76 -22
- package/packages/cache/dist/esm/adapters/redis/RedisCache.js +84 -26
- package/packages/cache/dist/esm/core/BaseCache.js +13 -4
- package/packages/cache/dist/esm/core/factory.js +26 -4
- package/packages/cache/dist/esm/errors/CacheError.d.ts +10 -7
- package/packages/cache/dist/esm/errors/CacheError.js +6 -11
- package/packages/cache/dist/esm/errors/cacheErrorCodes.d.ts +22 -0
- package/packages/cache/dist/esm/errors/cacheErrorCodes.js +21 -0
- package/packages/cache/dist/esm/errors/index.js +3 -0
- package/packages/cache/dist/esm/middleware/express/cacheMiddleware.js +8 -8
- package/packages/cache/dist/esm/session/SessionStore.js +84 -28
- package/packages/cache/dist/types/adapters/memcache/MemcacheCache.d.ts +1 -54
- package/packages/cache/dist/types/errors/CacheError.d.ts +10 -7
- package/packages/cache/dist/types/errors/cacheErrorCodes.d.ts +22 -0
- package/packages/cache/package.json +8 -6
- package/packages/cache/src/adapters/memcache/MemcacheCache.ts +79 -352
- package/packages/cache/src/adapters/memory/MemoryCache.ts +76 -77
- package/packages/cache/src/adapters/redis/RedisCache.ts +84 -86
- package/packages/cache/src/core/BaseCache.ts +13 -14
- package/packages/cache/src/core/factory.ts +27 -16
- package/packages/cache/src/errors/CacheError.ts +16 -17
- package/packages/cache/src/errors/cacheErrorCodes.ts +24 -0
- package/packages/cache/src/errors/index.ts +5 -0
- package/packages/cache/src/middleware/express/cacheMiddleware.ts +8 -8
- package/packages/cache/src/session/SessionStore.ts +84 -84
- package/packages/errors-utils/README.md +54 -57
- package/packages/errors-utils/dist/cjs/constants/errorCodes.d.ts +28 -23
- package/packages/errors-utils/dist/cjs/constants/errorCodes.js +57 -22
- package/packages/errors-utils/dist/cjs/constants/errorMessages.d.ts +8 -1
- package/packages/errors-utils/dist/cjs/constants/errorMessages.js +72 -29
- package/packages/errors-utils/dist/cjs/error/AppError.d.ts +2 -2
- package/packages/errors-utils/dist/cjs/error/AppError.js +2 -2
- package/packages/errors-utils/dist/cjs/error/ServiceUnavailableError.d.ts +4 -0
- package/packages/errors-utils/dist/cjs/error/ServiceUnavailableError.js +11 -0
- package/packages/errors-utils/dist/cjs/error/TokenExpiredError.d.ts +2 -2
- package/packages/errors-utils/dist/cjs/error/TokenExpiredError.js +2 -2
- package/packages/errors-utils/dist/cjs/error/TokenMalformedError.d.ts +2 -2
- package/packages/errors-utils/dist/cjs/error/TokenMalformedError.js +2 -2
- package/packages/errors-utils/dist/cjs/error/UnauthorizedError.d.ts +1 -2
- package/packages/errors-utils/dist/cjs/error/UnauthorizedError.js +2 -2
- package/packages/errors-utils/dist/cjs/error/index.d.ts +14 -0
- package/packages/errors-utils/dist/cjs/error/index.js +39 -0
- package/packages/errors-utils/dist/cjs/errorRegistry/errorRegistry.d.ts +19 -0
- package/packages/errors-utils/dist/cjs/errorRegistry/errorRegistry.js +63 -0
- package/packages/errors-utils/dist/cjs/errorRegistry/index.d.ts +3 -0
- package/packages/errors-utils/dist/cjs/errorRegistry/index.js +6 -0
- package/packages/errors-utils/dist/cjs/index.d.ts +3 -9
- package/packages/errors-utils/dist/cjs/index.js +12 -9
- package/packages/errors-utils/dist/cjs/middleware/express/{errorHandler.js → errorHandler.middleware.js} +4 -4
- package/packages/errors-utils/dist/cjs/middleware/express/index.d.ts +2 -2
- package/packages/errors-utils/dist/cjs/middleware/express/index.js +2 -2
- package/packages/errors-utils/dist/esm/constants/errorCodes.d.ts +28 -23
- package/packages/errors-utils/dist/esm/constants/errorCodes.js +57 -22
- package/packages/errors-utils/dist/esm/constants/errorMessages.d.ts +8 -1
- package/packages/errors-utils/dist/esm/constants/errorMessages.js +72 -29
- package/packages/errors-utils/dist/esm/error/AppError.d.ts +2 -2
- package/packages/errors-utils/dist/esm/error/AppError.js +2 -2
- package/packages/errors-utils/dist/esm/error/ServiceUnavailableError.d.ts +4 -0
- package/packages/errors-utils/dist/esm/error/ServiceUnavailableError.js +7 -0
- package/packages/errors-utils/dist/esm/error/TokenExpiredError.d.ts +2 -2
- package/packages/errors-utils/dist/esm/error/TokenExpiredError.js +2 -2
- package/packages/errors-utils/dist/esm/error/TokenMalformedError.d.ts +2 -2
- package/packages/errors-utils/dist/esm/error/TokenMalformedError.js +2 -2
- package/packages/errors-utils/dist/esm/error/UnauthorizedError.d.ts +1 -2
- package/packages/errors-utils/dist/esm/error/UnauthorizedError.js +2 -2
- package/packages/errors-utils/dist/esm/error/index.d.ts +14 -0
- package/packages/errors-utils/dist/esm/error/index.js +23 -0
- package/packages/errors-utils/dist/esm/errorRegistry/errorRegistry.d.ts +19 -0
- package/packages/errors-utils/dist/esm/errorRegistry/errorRegistry.js +59 -0
- package/packages/errors-utils/dist/esm/errorRegistry/index.d.ts +3 -0
- package/packages/errors-utils/dist/esm/errorRegistry/index.js +3 -0
- package/packages/errors-utils/dist/esm/index.d.ts +3 -9
- package/packages/errors-utils/dist/esm/index.js +12 -9
- package/packages/errors-utils/dist/esm/middleware/express/{errorHandler.js → errorHandler.middleware.js} +5 -5
- package/packages/errors-utils/dist/esm/middleware/express/index.d.ts +2 -2
- package/packages/errors-utils/dist/esm/middleware/express/index.js +2 -2
- package/packages/errors-utils/dist/types/constants/errorCodes.d.ts +28 -23
- package/packages/errors-utils/dist/types/constants/errorMessages.d.ts +8 -1
- package/packages/errors-utils/dist/types/error/AppError.d.ts +2 -2
- package/packages/errors-utils/dist/types/error/ServiceUnavailableError.d.ts +4 -0
- package/packages/errors-utils/dist/types/error/TokenExpiredError.d.ts +2 -2
- package/packages/errors-utils/dist/types/error/TokenMalformedError.d.ts +2 -2
- package/packages/errors-utils/dist/types/error/UnauthorizedError.d.ts +1 -2
- package/packages/errors-utils/dist/types/error/index.d.ts +14 -0
- package/packages/errors-utils/dist/types/errorRegistry/errorRegistry.d.ts +19 -0
- package/packages/errors-utils/dist/types/errorRegistry/index.d.ts +3 -0
- package/packages/errors-utils/dist/types/index.d.ts +3 -9
- package/packages/errors-utils/dist/types/middleware/express/index.d.ts +2 -2
- package/packages/errors-utils/package.json +4 -4
- package/packages/errors-utils/src/constants/errorCodes.ts +64 -23
- package/packages/errors-utils/src/constants/errorMessages.ts +91 -34
- package/packages/errors-utils/src/error/AppError.ts +3 -2
- package/packages/errors-utils/src/error/ServiceUnavailableError.ts +8 -0
- package/packages/errors-utils/src/error/TokenExpiredError.ts +2 -2
- package/packages/errors-utils/src/error/TokenMalformedError.ts +2 -2
- package/packages/errors-utils/src/error/UnauthorizedError.ts +8 -8
- package/packages/errors-utils/src/error/index.ts +26 -0
- package/packages/errors-utils/src/errorRegistry/errorRegistry.ts +74 -0
- package/packages/errors-utils/src/errorRegistry/index.ts +4 -0
- package/packages/errors-utils/src/index.ts +12 -10
- package/packages/errors-utils/src/middleware/express/{errorHandler.ts → errorHandler.middleware.ts} +5 -5
- package/packages/errors-utils/src/middleware/express/index.ts +2 -2
- package/packages/js-extensions/README.md +174 -425
- package/packages/js-extensions/dist/cjs/array/array-extensions.js +84 -50
- package/packages/js-extensions/dist/cjs/core/performance.d.ts +1 -0
- package/packages/js-extensions/dist/cjs/core/performance.js +6 -0
- package/packages/js-extensions/dist/cjs/core/version.d.ts +1 -0
- package/packages/js-extensions/dist/cjs/core/version.js +9 -0
- package/packages/js-extensions/dist/cjs/index.d.ts +1 -0
- package/packages/js-extensions/dist/cjs/index.js +1 -0
- package/packages/js-extensions/dist/cjs/number/number-extensions.js +85 -97
- package/packages/js-extensions/dist/cjs/object/object-extensions.js +102 -103
- package/packages/js-extensions/dist/cjs/string/string-extensions.js +66 -43
- package/packages/js-extensions/dist/cjs/types/global-augmentations.d.ts +1 -0
- package/packages/js-extensions/dist/cjs/utils/defineExtension.d.ts +1 -0
- package/packages/js-extensions/dist/cjs/utils/defineExtension.js +13 -0
- package/packages/js-extensions/dist/cjs/utils/index.d.ts +1 -0
- package/packages/js-extensions/dist/cjs/utils/index.js +1 -0
- package/packages/js-extensions/dist/esm/array/array-extensions.js +84 -50
- package/packages/js-extensions/dist/esm/core/performance.d.ts +1 -0
- package/packages/js-extensions/dist/esm/core/performance.js +5 -0
- package/packages/js-extensions/dist/esm/core/version.d.ts +1 -0
- package/packages/js-extensions/dist/esm/core/version.js +5 -0
- package/packages/js-extensions/dist/esm/index.d.ts +1 -0
- package/packages/js-extensions/dist/esm/index.js +1 -0
- package/packages/js-extensions/dist/esm/number/number-extensions.js +86 -98
- package/packages/js-extensions/dist/esm/object/object-extensions.js +102 -103
- package/packages/js-extensions/dist/esm/string/string-extensions.js +66 -43
- package/packages/js-extensions/dist/esm/types/global-augmentations.d.ts +1 -0
- package/packages/js-extensions/dist/esm/utils/defineExtension.d.ts +1 -0
- package/packages/js-extensions/dist/esm/utils/defineExtension.js +10 -0
- package/packages/js-extensions/dist/esm/utils/index.d.ts +1 -0
- package/packages/js-extensions/dist/esm/utils/index.js +1 -0
- package/packages/js-extensions/dist/types/core/performance.d.ts +1 -0
- package/packages/js-extensions/dist/types/core/version.d.ts +1 -0
- package/packages/js-extensions/dist/types/index.d.ts +1 -0
- package/packages/js-extensions/dist/types/types/global-augmentations.d.ts +1 -0
- package/packages/js-extensions/dist/types/utils/defineExtension.d.ts +1 -0
- package/packages/js-extensions/dist/types/utils/index.d.ts +1 -0
- package/packages/js-extensions/package.json +8 -4
- package/packages/js-extensions/src/array/array-extensions.ts +268 -150
- package/packages/js-extensions/src/core/performance.ts +11 -0
- package/packages/js-extensions/src/core/version.ts +7 -0
- package/packages/js-extensions/src/index.ts +2 -0
- package/packages/js-extensions/src/number/number-extensions.ts +90 -123
- package/packages/js-extensions/src/object/object-extensions.ts +102 -130
- package/packages/js-extensions/src/string/string-extensions.ts +80 -76
- package/packages/js-extensions/src/types/global-augmentations.ts +2 -1
- package/packages/js-extensions/src/utils/defineExtension.ts +14 -0
- package/packages/js-extensions/src/utils/index.ts +1 -0
- package/packages/response-utils/README.md +156 -198
- package/packages/response-utils/dist/cjs/core/BaseResponder.js +20 -4
- package/packages/response-utils/dist/cjs/index.d.ts +0 -1
- package/packages/response-utils/dist/cjs/index.js +1 -25
- package/packages/response-utils/dist/esm/core/BaseResponder.js +20 -4
- package/packages/response-utils/dist/esm/index.d.ts +0 -1
- package/packages/response-utils/dist/esm/index.js +0 -2
- package/packages/response-utils/dist/types/index.d.ts +0 -1
- package/packages/response-utils/package.json +1 -1
- package/packages/response-utils/src/core/BaseResponder.ts +25 -4
- package/packages/response-utils/src/index.ts +0 -3
- package/packages/response-utils/src/middleware/express/expressMiddleware.ts +1 -1
- package/packages/security/README.md +153 -355
- package/packages/security/dist/cjs/core/crypto/cryptoManager.js +34 -17
- package/packages/security/dist/cjs/core/jwt/decode.js +4 -1
- package/packages/security/dist/cjs/core/jwt/generateTokens.js +4 -1
- package/packages/security/dist/cjs/core/jwt/jwtManager.d.ts +19 -43
- package/packages/security/dist/cjs/core/jwt/jwtManager.js +84 -199
- package/packages/security/dist/cjs/core/jwt/parseDuration.js +3 -2
- package/packages/security/dist/cjs/core/jwt/signToken.js +2 -1
- package/packages/security/dist/cjs/core/jwt/validateToken.d.ts +10 -7
- package/packages/security/dist/cjs/core/jwt/validateToken.js +19 -10
- package/packages/security/dist/cjs/core/jwt/verify.d.ts +8 -9
- package/packages/security/dist/cjs/core/jwt/verify.js +59 -14
- package/packages/security/dist/cjs/core/password/hash.js +4 -4
- package/packages/security/dist/cjs/core/password/passwordManager.d.ts +1 -1
- package/packages/security/dist/cjs/core/password/passwordManager.js +36 -80
- package/packages/security/dist/cjs/core/password/strength.js +12 -6
- package/packages/security/dist/cjs/core/password/utils.d.ts +12 -0
- package/packages/security/dist/cjs/core/password/utils.js +16 -1
- package/packages/security/dist/cjs/core/password/verify.js +4 -4
- package/packages/security/dist/cjs/index.d.ts +2 -7
- package/packages/security/dist/esm/core/crypto/cryptoManager.js +34 -17
- package/packages/security/dist/esm/core/jwt/decode.js +4 -1
- package/packages/security/dist/esm/core/jwt/generateTokens.js +4 -1
- package/packages/security/dist/esm/core/jwt/jwtManager.d.ts +19 -43
- package/packages/security/dist/esm/core/jwt/jwtManager.js +85 -200
- package/packages/security/dist/esm/core/jwt/parseDuration.js +3 -2
- package/packages/security/dist/esm/core/jwt/signToken.js +2 -1
- package/packages/security/dist/esm/core/jwt/validateToken.d.ts +10 -7
- package/packages/security/dist/esm/core/jwt/validateToken.js +19 -10
- package/packages/security/dist/esm/core/jwt/verify.d.ts +8 -9
- package/packages/security/dist/esm/core/jwt/verify.js +58 -13
- package/packages/security/dist/esm/core/password/hash.js +4 -4
- package/packages/security/dist/esm/core/password/passwordManager.d.ts +1 -1
- package/packages/security/dist/esm/core/password/passwordManager.js +36 -80
- package/packages/security/dist/esm/core/password/strength.js +12 -6
- package/packages/security/dist/esm/core/password/utils.d.ts +12 -0
- package/packages/security/dist/esm/core/password/utils.js +16 -1
- package/packages/security/dist/esm/core/password/verify.js +4 -4
- package/packages/security/dist/esm/index.d.ts +2 -7
- package/packages/security/dist/types/core/jwt/jwtManager.d.ts +19 -43
- package/packages/security/dist/types/core/jwt/validateToken.d.ts +10 -7
- package/packages/security/dist/types/core/jwt/verify.d.ts +8 -9
- package/packages/security/dist/types/core/password/passwordManager.d.ts +1 -1
- package/packages/security/dist/types/core/password/utils.d.ts +12 -0
- package/packages/security/dist/types/index.d.ts +2 -7
- package/packages/security/package.json +3 -3
- package/packages/security/src/core/crypto/cryptoManager.ts +53 -21
- package/packages/security/src/core/jwt/decode.ts +4 -1
- package/packages/security/src/core/jwt/generateTokens.ts +4 -1
- package/packages/security/src/core/jwt/jwtManager.ts +105 -257
- package/packages/security/src/core/jwt/parseDuration.ts +4 -2
- package/packages/security/src/core/jwt/signToken.ts +2 -1
- package/packages/security/src/core/jwt/validateToken.ts +21 -13
- package/packages/security/src/core/jwt/verify.ts +82 -20
- package/packages/security/src/core/password/hash.ts +10 -4
- package/packages/security/src/core/password/passwordManager.ts +38 -108
- package/packages/security/src/core/password/strength.ts +13 -8
- package/packages/security/src/core/password/utils.ts +19 -3
- package/packages/security/src/core/password/verify.ts +6 -4
- package/packages/server-utils/README.md +1 -1
- package/packages/server-utils/dist/cjs/core/server.js +6 -6
- package/packages/server-utils/dist/cjs/middleware/auth.middleware.d.ts +1 -2
- package/packages/server-utils/dist/cjs/middleware/auth.middleware.js +17 -14
- package/packages/server-utils/dist/cjs/middleware/cache.middleware.js +2 -2
- package/packages/server-utils/dist/cjs/middleware/errorHandler.middleware.d.ts +1 -1
- package/packages/server-utils/dist/cjs/middleware/errorHandler.middleware.js +34 -17
- package/packages/server-utils/dist/cjs/middleware/session.middleware.js +8 -8
- package/packages/server-utils/dist/cjs/middleware/validation.middleware.js +2 -2
- package/packages/server-utils/dist/esm/core/server.js +6 -6
- package/packages/server-utils/dist/esm/middleware/auth.middleware.d.ts +1 -2
- package/packages/server-utils/dist/esm/middleware/auth.middleware.js +18 -15
- package/packages/server-utils/dist/esm/middleware/cache.middleware.js +2 -2
- package/packages/server-utils/dist/esm/middleware/errorHandler.middleware.d.ts +1 -1
- package/packages/server-utils/dist/esm/middleware/errorHandler.middleware.js +34 -17
- package/packages/server-utils/dist/esm/middleware/session.middleware.js +8 -8
- package/packages/server-utils/dist/esm/middleware/validation.middleware.js +2 -2
- package/packages/server-utils/dist/types/middleware/auth.middleware.d.ts +1 -2
- package/packages/server-utils/dist/types/middleware/errorHandler.middleware.d.ts +1 -1
- package/packages/server-utils/package.json +4 -4
- package/packages/server-utils/src/core/server.ts +6 -6
- package/packages/server-utils/src/middleware/auth.middleware.ts +40 -27
- package/packages/server-utils/src/middleware/cache.middleware.ts +2 -2
- package/packages/server-utils/src/middleware/errorHandler.middleware.ts +39 -24
- package/packages/server-utils/src/middleware/session.middleware.ts +11 -8
- package/packages/server-utils/src/middleware/validation.middleware.ts +2 -3
- package/packages/errors-utils/dist/cjs/error/RateLimitError.d.ts +0 -4
- package/packages/errors-utils/dist/cjs/error/RateLimitError.js +0 -11
- package/packages/errors-utils/dist/cjs/utils/mapAppErrorToResponder.d.ts +0 -3
- package/packages/errors-utils/dist/cjs/utils/mapAppErrorToResponder.js +0 -27
- package/packages/errors-utils/dist/esm/error/RateLimitError.d.ts +0 -4
- package/packages/errors-utils/dist/esm/error/RateLimitError.js +0 -7
- package/packages/errors-utils/dist/esm/utils/mapAppErrorToResponder.d.ts +0 -3
- package/packages/errors-utils/dist/esm/utils/mapAppErrorToResponder.js +0 -24
- package/packages/errors-utils/dist/types/error/RateLimitError.d.ts +0 -4
- package/packages/errors-utils/dist/types/utils/mapAppErrorToResponder.d.ts +0 -3
- package/packages/errors-utils/src/error/RateLimitError.ts +0 -8
- package/packages/errors-utils/src/utils/mapAppErrorToResponder.ts +0 -38
- package/packages/response-utils/src/legacy.ts +0 -30
- /package/packages/errors-utils/dist/cjs/middleware/express/{errorConverter.d.ts → errorConverter.middleware.d.ts} +0 -0
- /package/packages/errors-utils/dist/cjs/middleware/express/{errorConverter.js → errorConverter.middleware.js} +0 -0
- /package/packages/errors-utils/dist/cjs/middleware/express/{errorHandler.d.ts → errorHandler.middleware.d.ts} +0 -0
- /package/packages/errors-utils/dist/esm/middleware/express/{errorConverter.d.ts → errorConverter.middleware.d.ts} +0 -0
- /package/packages/errors-utils/dist/esm/middleware/express/{errorConverter.js → errorConverter.middleware.js} +0 -0
- /package/packages/errors-utils/dist/esm/middleware/express/{errorHandler.d.ts → errorHandler.middleware.d.ts} +0 -0
- /package/packages/errors-utils/dist/types/middleware/express/{errorConverter.d.ts → errorConverter.middleware.d.ts} +0 -0
- /package/packages/errors-utils/dist/types/middleware/express/{errorHandler.d.ts → errorHandler.middleware.d.ts} +0 -0
- /package/packages/errors-utils/src/middleware/express/{errorConverter.ts → errorConverter.middleware.ts} +0 -0
|
@@ -6,10 +6,9 @@ import type {
|
|
|
6
6
|
JWTConfig,
|
|
7
7
|
RefreshToken,
|
|
8
8
|
TokenPair,
|
|
9
|
-
TokenValidationOptions,
|
|
10
9
|
} from '../../interfaces/jwt.interface'
|
|
11
10
|
import { signToken } from './signToken'
|
|
12
|
-
import { safeVerifyToken
|
|
11
|
+
import { safeVerifyToken } from './verify'
|
|
13
12
|
|
|
14
13
|
import {
|
|
15
14
|
BadRequestError,
|
|
@@ -25,7 +24,7 @@ export class JWTManager implements ITokenManager {
|
|
|
25
24
|
private refreshExpiry: string | number
|
|
26
25
|
private cache?: LRUCache<
|
|
27
26
|
string,
|
|
28
|
-
{ valid: boolean; payload: JwtPayload
|
|
27
|
+
{ valid: boolean; payload: JwtPayload; timestamp: number }
|
|
29
28
|
>
|
|
30
29
|
private cacheTTL: number
|
|
31
30
|
|
|
@@ -34,16 +33,14 @@ export class JWTManager implements ITokenManager {
|
|
|
34
33
|
this.refreshSecret = config.refreshSecret
|
|
35
34
|
this.accessExpiry = config.accessExpiry || '15m'
|
|
36
35
|
this.refreshExpiry = config.refreshExpiry || '7d'
|
|
37
|
-
this.cacheTTL = 5 * 60 * 1000 // 5 minutes
|
|
36
|
+
this.cacheTTL = 5 * 60 * 1000 // 5 minutes
|
|
38
37
|
|
|
39
38
|
if (config.enableCaching) {
|
|
40
39
|
this.cache = new LRUCache(config.maxCacheSize || 100)
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
/**
|
|
45
|
-
* Generate both access and refresh tokens
|
|
46
|
-
*/
|
|
43
|
+
/** Generate both access and refresh tokens */
|
|
47
44
|
async generateTokens(payload: Record<string, unknown>): Promise<TokenPair> {
|
|
48
45
|
try {
|
|
49
46
|
this.validatePayload(payload)
|
|
@@ -51,335 +48,186 @@ export class JWTManager implements ITokenManager {
|
|
|
51
48
|
const accessToken = await this.generateAccessToken(payload)
|
|
52
49
|
const refreshToken = await this.generateRefreshToken(payload)
|
|
53
50
|
|
|
54
|
-
return {
|
|
55
|
-
accessToken,
|
|
56
|
-
refreshToken,
|
|
57
|
-
}
|
|
51
|
+
return { accessToken, refreshToken }
|
|
58
52
|
} catch (error) {
|
|
59
|
-
if (
|
|
60
|
-
error instanceof BadRequestError ||
|
|
61
|
-
error instanceof ValidationError
|
|
62
|
-
) {
|
|
53
|
+
if (error instanceof BadRequestError || error instanceof ValidationError)
|
|
63
54
|
throw error
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
throw new BadRequestError(
|
|
56
|
+
{ reason: 'Failed to generate tokens' },
|
|
57
|
+
error instanceof Error ? error : undefined,
|
|
58
|
+
)
|
|
66
59
|
}
|
|
67
60
|
}
|
|
68
61
|
|
|
69
|
-
/**
|
|
70
|
-
* Generate access token
|
|
71
|
-
*/
|
|
62
|
+
/** Generate access token */
|
|
72
63
|
async generateAccessToken(
|
|
73
64
|
payload: Record<string, unknown>,
|
|
74
65
|
): Promise<AccessToken> {
|
|
75
66
|
try {
|
|
76
67
|
this.validatePayload(payload)
|
|
77
|
-
|
|
78
68
|
const token = signToken(payload, this.accessSecret, this.accessExpiry, {
|
|
79
69
|
algorithm: 'HS256',
|
|
80
70
|
})
|
|
81
|
-
|
|
82
71
|
return token as unknown as AccessToken
|
|
83
72
|
} catch (error) {
|
|
84
|
-
if (
|
|
85
|
-
error instanceof BadRequestError ||
|
|
86
|
-
error instanceof ValidationError
|
|
87
|
-
) {
|
|
73
|
+
if (error instanceof BadRequestError || error instanceof ValidationError)
|
|
88
74
|
throw error
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
throw new BadRequestError(
|
|
76
|
+
{ reason: 'Failed to generate access token' },
|
|
77
|
+
error instanceof Error ? error : undefined,
|
|
78
|
+
)
|
|
91
79
|
}
|
|
92
80
|
}
|
|
93
81
|
|
|
94
|
-
/**
|
|
95
|
-
* Generate refresh token
|
|
96
|
-
*/
|
|
82
|
+
/** Generate refresh token */
|
|
97
83
|
async generateRefreshToken(
|
|
98
84
|
payload: Record<string, unknown>,
|
|
99
85
|
): Promise<RefreshToken> {
|
|
100
86
|
try {
|
|
101
87
|
this.validatePayload(payload)
|
|
102
|
-
|
|
103
88
|
const token = signToken(payload, this.refreshSecret, this.refreshExpiry, {
|
|
104
89
|
algorithm: 'HS256',
|
|
105
90
|
})
|
|
106
|
-
|
|
107
91
|
return token as unknown as RefreshToken
|
|
108
92
|
} catch (error) {
|
|
109
|
-
if (
|
|
110
|
-
error instanceof BadRequestError ||
|
|
111
|
-
error instanceof ValidationError
|
|
112
|
-
) {
|
|
93
|
+
if (error instanceof BadRequestError || error instanceof ValidationError)
|
|
113
94
|
throw error
|
|
114
|
-
|
|
115
|
-
|
|
95
|
+
throw new BadRequestError(
|
|
96
|
+
{ reason: 'Failed to generate refresh token' },
|
|
97
|
+
error instanceof Error ? error : undefined,
|
|
98
|
+
)
|
|
116
99
|
}
|
|
117
100
|
}
|
|
118
101
|
|
|
119
|
-
/**
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
async verifyAccessToken(token: string): Promise<JwtPayload | string> {
|
|
123
|
-
try {
|
|
124
|
-
if (!token || typeof token !== 'string') {
|
|
125
|
-
throw new ValidationError('Access token must be a non-empty string')
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const cacheKey = `access_${token}`
|
|
129
|
-
if (this.cache) {
|
|
130
|
-
const cached = this.cache.get(cacheKey)
|
|
131
|
-
if (cached && Date.now() - cached.timestamp <= this.cacheTTL) {
|
|
132
|
-
if (!cached.valid) {
|
|
133
|
-
throw new UnauthorizedError('Access token is invalid or expired')
|
|
134
|
-
}
|
|
135
|
-
return cached.payload
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const decoded = verifyToken(token, this.accessSecret)
|
|
140
|
-
|
|
141
|
-
if (this.cache) {
|
|
142
|
-
this.cache.set(cacheKey, {
|
|
143
|
-
valid: true,
|
|
144
|
-
payload: decoded,
|
|
145
|
-
timestamp: Date.now(),
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return decoded
|
|
150
|
-
} catch (error) {
|
|
151
|
-
if (
|
|
152
|
-
error instanceof ValidationError ||
|
|
153
|
-
error instanceof UnauthorizedError
|
|
154
|
-
) {
|
|
155
|
-
throw error
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (error instanceof Error && error.name === 'TokenExpiredError') {
|
|
159
|
-
throw new UnauthorizedError('Access token has expired')
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (error instanceof Error && error.name === 'JsonWebTokenError') {
|
|
163
|
-
throw new UnauthorizedError('Access token is invalid')
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
throw new UnauthorizedError('Failed to verify access token')
|
|
167
|
-
}
|
|
102
|
+
/** Verify access token */
|
|
103
|
+
async verifyAccessToken(token: string): Promise<JwtPayload> {
|
|
104
|
+
return this.verifyTokenWithCache(token, this.accessSecret, 'access')
|
|
168
105
|
}
|
|
169
106
|
|
|
170
|
-
/**
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
async verifyRefreshToken(token: string): Promise<JwtPayload | string> {
|
|
174
|
-
try {
|
|
175
|
-
if (!token || typeof token !== 'string') {
|
|
176
|
-
throw new ValidationError('Refresh token must be a non-empty string')
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const cacheKey = `refresh_${token}`
|
|
180
|
-
if (this.cache) {
|
|
181
|
-
const cached = this.cache.get(cacheKey)
|
|
182
|
-
if (cached) {
|
|
183
|
-
if (!cached.valid) {
|
|
184
|
-
throw new UnauthorizedError('Refresh token is invalid or expired')
|
|
185
|
-
}
|
|
186
|
-
return cached.payload
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const decoded = verifyToken(token, this.refreshSecret)
|
|
191
|
-
|
|
192
|
-
if (this.cache) {
|
|
193
|
-
this.cache.set(cacheKey, {
|
|
194
|
-
valid: true,
|
|
195
|
-
payload: decoded,
|
|
196
|
-
timestamp: Date.now(),
|
|
197
|
-
})
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return decoded
|
|
201
|
-
} catch (error) {
|
|
202
|
-
if (
|
|
203
|
-
error instanceof ValidationError ||
|
|
204
|
-
error instanceof UnauthorizedError
|
|
205
|
-
) {
|
|
206
|
-
throw error
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (error instanceof Error && error.name === 'TokenExpiredError') {
|
|
210
|
-
throw new UnauthorizedError('Refresh token has expired')
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (error instanceof Error && error.name === 'JsonWebTokenError') {
|
|
214
|
-
throw new UnauthorizedError('Refresh token is invalid')
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
throw new UnauthorizedError('Failed to verify refresh token')
|
|
218
|
-
}
|
|
107
|
+
/** Verify refresh token */
|
|
108
|
+
async verifyRefreshToken(token: string): Promise<JwtPayload> {
|
|
109
|
+
return this.verifyTokenWithCache(token, this.refreshSecret, 'refresh')
|
|
219
110
|
}
|
|
220
111
|
|
|
221
|
-
/**
|
|
222
|
-
* Decode token without verification
|
|
223
|
-
*/
|
|
112
|
+
/** Decode token without verification */
|
|
224
113
|
decodeToken(token: string, complete = false): JwtPayload | string | null {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
throw new ValidationError('Token must be a non-empty string')
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return jwt.decode(token, { complete }) as JwtPayload | string | null
|
|
231
|
-
} catch (error) {
|
|
232
|
-
if (error instanceof ValidationError) {
|
|
233
|
-
throw error
|
|
234
|
-
}
|
|
235
|
-
return null
|
|
236
|
-
}
|
|
114
|
+
if (!token || typeof token !== 'string') return null
|
|
115
|
+
return jwt.decode(token, { complete }) as JwtPayload | string | null
|
|
237
116
|
}
|
|
238
117
|
|
|
239
|
-
/**
|
|
240
|
-
* Extract token from Authorization header
|
|
241
|
-
*/
|
|
118
|
+
/** Extract token from Authorization header */
|
|
242
119
|
extractTokenFromHeader(authHeader: string): string | null {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const parts = authHeader.split(' ')
|
|
249
|
-
if (parts.length !== 2 || parts[0] !== 'Bearer') {
|
|
250
|
-
return null
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return parts[1]
|
|
254
|
-
} catch {
|
|
255
|
-
return null
|
|
256
|
-
}
|
|
120
|
+
if (!authHeader || typeof authHeader !== 'string') return null
|
|
121
|
+
const parts = authHeader.split(' ')
|
|
122
|
+
if (parts.length !== 2 || parts[0] !== 'Bearer') return null
|
|
123
|
+
return parts[1]
|
|
257
124
|
}
|
|
258
125
|
|
|
259
|
-
/**
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
token: string,
|
|
264
|
-
secret: Secret,
|
|
265
|
-
_options: TokenValidationOptions = {},
|
|
266
|
-
): boolean {
|
|
267
|
-
try {
|
|
268
|
-
if (!token || typeof token !== 'string') {
|
|
269
|
-
return false
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const result = safeVerifyToken(token, secret)
|
|
273
|
-
return result.valid
|
|
274
|
-
} catch {
|
|
275
|
-
return false
|
|
276
|
-
}
|
|
126
|
+
/** Validate token without throwing exceptions */
|
|
127
|
+
validateToken(token: string, secret: Secret): boolean {
|
|
128
|
+
if (!token || typeof token !== 'string') return false
|
|
129
|
+
return safeVerifyToken(token, secret).valid
|
|
277
130
|
}
|
|
278
131
|
|
|
279
|
-
/**
|
|
280
|
-
* Rotate refresh token
|
|
281
|
-
*/
|
|
132
|
+
/** Rotate refresh token */
|
|
282
133
|
async rotateRefreshToken(oldToken: string): Promise<RefreshToken> {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
const decoded = await this.verifyRefreshToken(oldToken)
|
|
291
|
-
|
|
292
|
-
if (typeof decoded === 'string') {
|
|
293
|
-
throw new ValidationError(
|
|
294
|
-
'Invalid token payload — expected JWT payload object',
|
|
295
|
-
)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Create new payload without issued/expired timestamps
|
|
299
|
-
const payload: JwtPayload = { ...decoded }
|
|
300
|
-
delete payload.iat
|
|
301
|
-
delete payload.exp
|
|
134
|
+
if (!oldToken || typeof oldToken !== 'string') {
|
|
135
|
+
throw new ValidationError({
|
|
136
|
+
reason: 'Old refresh token must be a non-empty string',
|
|
137
|
+
})
|
|
138
|
+
}
|
|
302
139
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
this.refreshExpiry,
|
|
308
|
-
)
|
|
140
|
+
const decoded = await this.verifyRefreshToken(oldToken)
|
|
141
|
+
const payload: JwtPayload = { ...decoded }
|
|
142
|
+
delete payload.iat
|
|
143
|
+
delete payload.exp
|
|
309
144
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (
|
|
313
|
-
error instanceof ValidationError ||
|
|
314
|
-
error instanceof UnauthorizedError
|
|
315
|
-
) {
|
|
316
|
-
throw error
|
|
317
|
-
}
|
|
318
|
-
throw new BadRequestError('Failed to rotate refresh token')
|
|
319
|
-
}
|
|
145
|
+
const newToken = signToken(payload, this.refreshSecret, this.refreshExpiry)
|
|
146
|
+
return newToken as unknown as RefreshToken
|
|
320
147
|
}
|
|
321
148
|
|
|
322
|
-
/**
|
|
323
|
-
* Check if token is expired
|
|
324
|
-
*/
|
|
149
|
+
/** Check if token is expired */
|
|
325
150
|
isTokenExpired(token: string): boolean {
|
|
326
151
|
try {
|
|
327
152
|
const decoded = this.decodeToken(token) as JwtPayload | null
|
|
328
|
-
if (!decoded || !decoded.exp)
|
|
329
|
-
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const currentTime = Math.floor(Date.now() / 1000)
|
|
333
|
-
return decoded.exp < currentTime
|
|
153
|
+
if (!decoded || !decoded.exp) return true
|
|
154
|
+
return decoded.exp < Math.floor(Date.now() / 1000)
|
|
334
155
|
} catch {
|
|
335
156
|
return true
|
|
336
157
|
}
|
|
337
158
|
}
|
|
338
159
|
|
|
339
|
-
/**
|
|
340
|
-
* Get token expiration date
|
|
341
|
-
*/
|
|
160
|
+
/** Get token expiration date */
|
|
342
161
|
getTokenExpiration(token: string): Date | null {
|
|
343
162
|
try {
|
|
344
163
|
const decoded = this.decodeToken(token) as JwtPayload | null
|
|
345
|
-
if (!decoded || !decoded.exp)
|
|
346
|
-
return null
|
|
347
|
-
}
|
|
348
|
-
|
|
164
|
+
if (!decoded || !decoded.exp) return null
|
|
349
165
|
return new Date(decoded.exp * 1000)
|
|
350
166
|
} catch {
|
|
351
167
|
return null
|
|
352
168
|
}
|
|
353
169
|
}
|
|
354
170
|
|
|
355
|
-
/**
|
|
356
|
-
* Clear token cache
|
|
357
|
-
*/
|
|
171
|
+
/** Clear token cache */
|
|
358
172
|
clearCache(): void {
|
|
359
173
|
this.cache?.clear()
|
|
360
174
|
}
|
|
361
175
|
|
|
362
|
-
/**
|
|
363
|
-
* Get cache statistics
|
|
364
|
-
*/
|
|
176
|
+
/** Get cache statistics */
|
|
365
177
|
getCacheStats(): { size: number; maxSize: number } | null {
|
|
366
178
|
if (!this.cache) return null
|
|
367
|
-
|
|
368
|
-
// Note: LRUCache doesn't expose internal size, so we return maxSize only
|
|
369
|
-
return {
|
|
370
|
-
size: -1, // Size not available from LRUCache
|
|
371
|
-
maxSize: (this.cache as any).maxSize,
|
|
372
|
-
}
|
|
179
|
+
return { size: -1, maxSize: (this.cache as any).maxSize }
|
|
373
180
|
}
|
|
374
181
|
|
|
375
|
-
|
|
182
|
+
/** Private helper methods */
|
|
376
183
|
private validatePayload(payload: Record<string, unknown>): void {
|
|
377
184
|
if (!payload || typeof payload !== 'object') {
|
|
378
|
-
throw new ValidationError(
|
|
185
|
+
throw new ValidationError({
|
|
186
|
+
reason: 'Payload must be a non-null object',
|
|
187
|
+
})
|
|
379
188
|
}
|
|
380
|
-
|
|
381
189
|
if (Object.keys(payload).length === 0) {
|
|
382
|
-
throw new ValidationError('Payload cannot be empty')
|
|
190
|
+
throw new ValidationError({ reason: 'Payload cannot be empty' })
|
|
383
191
|
}
|
|
384
192
|
}
|
|
193
|
+
|
|
194
|
+
private async verifyTokenWithCache(
|
|
195
|
+
token: string,
|
|
196
|
+
secret: Secret,
|
|
197
|
+
type: 'access' | 'refresh',
|
|
198
|
+
): Promise<JwtPayload> {
|
|
199
|
+
if (!token || typeof token !== 'string') {
|
|
200
|
+
throw new ValidationError({
|
|
201
|
+
reason: `${type} token must be a non-empty string`,
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const cacheKey = `${type}_${token}`
|
|
206
|
+
if (this.cache) {
|
|
207
|
+
const cached = this.cache.get(cacheKey)
|
|
208
|
+
if (cached && Date.now() - cached.timestamp <= this.cacheTTL) {
|
|
209
|
+
if (!cached.valid)
|
|
210
|
+
throw new UnauthorizedError({
|
|
211
|
+
reason: `${type} token is invalid or expired`,
|
|
212
|
+
})
|
|
213
|
+
return cached.payload
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const { valid, payload, error } = safeVerifyToken(token, secret)
|
|
218
|
+
if (!valid || !payload || typeof payload === 'string') {
|
|
219
|
+
this.cache?.set(cacheKey, {
|
|
220
|
+
valid: false,
|
|
221
|
+
payload: {} as JwtPayload,
|
|
222
|
+
timestamp: Date.now(),
|
|
223
|
+
})
|
|
224
|
+
throw new UnauthorizedError({
|
|
225
|
+
reason: `${type} token is invalid or expired`,
|
|
226
|
+
cause: error,
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
this.cache?.set(cacheKey, { valid: true, payload, timestamp: Date.now() })
|
|
231
|
+
return payload
|
|
232
|
+
}
|
|
385
233
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ValidationError } from '@naman_deep_singh/errors-utils'
|
|
2
|
+
|
|
1
3
|
const TIME_UNITS: Record<string, number> = {
|
|
2
4
|
s: 1,
|
|
3
5
|
m: 60,
|
|
@@ -18,14 +20,14 @@ export function parseDuration(input: string | number): number {
|
|
|
18
20
|
const unit = match[2].toLowerCase()
|
|
19
21
|
|
|
20
22
|
if (!TIME_UNITS[unit]) {
|
|
21
|
-
throw new
|
|
23
|
+
throw new ValidationError({ reason: `Invalid time unit: ${unit}` })
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
totalSeconds += value * TIME_UNITS[unit]
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
if (totalSeconds === 0) {
|
|
28
|
-
throw new
|
|
30
|
+
throw new ValidationError({ reason: `Invalid expiry format: "${input}"` })
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
return totalSeconds
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ValidationError } from '@naman_deep_singh/errors-utils'
|
|
1
2
|
import { type Secret, type SignOptions, sign } from 'jsonwebtoken'
|
|
2
3
|
import { parseDuration } from './parseDuration'
|
|
3
4
|
|
|
@@ -14,7 +15,7 @@ export const signToken = (
|
|
|
14
15
|
const seconds = parseDuration(expiresIn)
|
|
15
16
|
|
|
16
17
|
if (!seconds || seconds < 10) {
|
|
17
|
-
throw new
|
|
18
|
+
throw new ValidationError({ reason: 'Token expiry too small' })
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
const tokenPayload = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ValidationError } from '@naman_deep_singh/errors-utils'
|
|
2
|
+
import type { JwtPayload } from 'jsonwebtoken'
|
|
2
3
|
|
|
3
4
|
export interface TokenRequirements {
|
|
4
5
|
requiredFields?: string[]
|
|
@@ -6,12 +7,14 @@ export interface TokenRequirements {
|
|
|
6
7
|
validateTypes?: Record<string, 'string' | 'number' | 'boolean'>
|
|
7
8
|
}
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Validates a JWT payload according to the provided rules.
|
|
12
|
+
* Throws ValidationError if validation fails.
|
|
13
|
+
*/
|
|
9
14
|
export function validateTokenPayload(
|
|
10
15
|
payload: Record<string, unknown>,
|
|
11
|
-
rules: TokenRequirements = {
|
|
12
|
-
|
|
13
|
-
},
|
|
14
|
-
): { valid: true } | { valid: false; error: string } {
|
|
16
|
+
rules: TokenRequirements = { requiredFields: ['exp', 'iat'] },
|
|
17
|
+
): void {
|
|
15
18
|
const {
|
|
16
19
|
requiredFields = [],
|
|
17
20
|
forbiddenFields = [],
|
|
@@ -21,14 +24,18 @@ export function validateTokenPayload(
|
|
|
21
24
|
// 1. Required fields
|
|
22
25
|
for (const field of requiredFields) {
|
|
23
26
|
if (!(field in payload)) {
|
|
24
|
-
|
|
27
|
+
throw new ValidationError({
|
|
28
|
+
reason: `Missing required field: ${field}`,
|
|
29
|
+
})
|
|
25
30
|
}
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
// 2. Forbidden fields
|
|
29
34
|
for (const field of forbiddenFields) {
|
|
30
35
|
if (field in payload) {
|
|
31
|
-
|
|
36
|
+
throw new ValidationError({
|
|
37
|
+
reason: `Forbidden field in token: ${field}`,
|
|
38
|
+
})
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
41
|
|
|
@@ -36,16 +43,17 @@ export function validateTokenPayload(
|
|
|
36
43
|
for (const key in validateTypes) {
|
|
37
44
|
const expectedType = validateTypes[key]
|
|
38
45
|
if (key in payload && typeof payload[key] !== expectedType) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
46
|
+
throw new ValidationError({
|
|
47
|
+
reason: `Invalid type for ${key}. Expected ${expectedType}, got ${typeof payload[key]}`,
|
|
48
|
+
})
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
|
-
|
|
46
|
-
return { valid: true }
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Checks if a JWT payload is expired.
|
|
55
|
+
* Returns true if expired or missing 'exp'.
|
|
56
|
+
*/
|
|
49
57
|
export function isTokenExpired(payload: JwtPayload): boolean {
|
|
50
58
|
if (!payload.exp) return true
|
|
51
59
|
return Date.now() >= payload.exp * 1000
|