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
|
@@ -1,55 +1,117 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { UnauthorizedError } from '@naman_deep_singh/errors-utils'
|
|
2
|
+
import {
|
|
3
|
+
type JwtPayload,
|
|
4
|
+
type Secret,
|
|
5
|
+
type VerifyOptions,
|
|
6
|
+
verify,
|
|
7
|
+
} from 'jsonwebtoken'
|
|
3
8
|
import type { VerificationResult } from './types'
|
|
4
9
|
|
|
5
10
|
/**
|
|
6
|
-
* Verify token (throws if invalid or expired)
|
|
11
|
+
* Verify token (throws UnauthorizedError if invalid or expired)
|
|
7
12
|
*/
|
|
8
13
|
export const verifyToken = (
|
|
9
14
|
token: string,
|
|
10
15
|
secret: Secret,
|
|
11
16
|
): string | JwtPayload => {
|
|
12
|
-
|
|
17
|
+
try {
|
|
18
|
+
return verify(token, secret)
|
|
19
|
+
} catch (error: any) {
|
|
20
|
+
if (error.name === 'TokenExpiredError') {
|
|
21
|
+
throw new UnauthorizedError({ reason: 'Token has expired' }, error)
|
|
22
|
+
}
|
|
23
|
+
if (error.name === 'JsonWebTokenError') {
|
|
24
|
+
throw new UnauthorizedError({ reason: 'Invalid token' }, error)
|
|
25
|
+
}
|
|
26
|
+
throw new UnauthorizedError({ reason: 'Failed to verify token' }, error)
|
|
27
|
+
}
|
|
13
28
|
}
|
|
14
29
|
|
|
15
30
|
/**
|
|
16
|
-
*
|
|
31
|
+
* Verify token with options
|
|
17
32
|
*/
|
|
18
|
-
export const
|
|
33
|
+
export const verifyTokenWithOptions = (
|
|
19
34
|
token: string,
|
|
20
35
|
secret: Secret,
|
|
21
|
-
|
|
36
|
+
options: VerifyOptions = {},
|
|
37
|
+
): string | JwtPayload => {
|
|
22
38
|
try {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
39
|
+
return verify(token, secret, options)
|
|
40
|
+
} catch (error: any) {
|
|
41
|
+
if (error.name === 'TokenExpiredError') {
|
|
42
|
+
throw new UnauthorizedError({ reason: 'Token has expired' }, error)
|
|
43
|
+
}
|
|
44
|
+
if (error.name === 'JsonWebTokenError') {
|
|
45
|
+
throw new UnauthorizedError({ reason: 'Invalid token' }, error)
|
|
46
|
+
}
|
|
47
|
+
throw new UnauthorizedError({ reason: 'Failed to verify token' }, error)
|
|
27
48
|
}
|
|
28
49
|
}
|
|
29
50
|
|
|
30
51
|
/**
|
|
31
|
-
*
|
|
52
|
+
* Safe verify — never throws, returns structured result with UnauthorizedError on failure
|
|
32
53
|
*/
|
|
33
|
-
export const
|
|
54
|
+
export const safeVerifyToken = (
|
|
34
55
|
token: string,
|
|
35
56
|
secret: Secret,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
57
|
+
): VerificationResult => {
|
|
58
|
+
try {
|
|
59
|
+
const decoded = verify(token, secret)
|
|
60
|
+
return { valid: true, payload: decoded }
|
|
61
|
+
} catch (error: any) {
|
|
62
|
+
let wrappedError: UnauthorizedError
|
|
63
|
+
|
|
64
|
+
if (error.name === 'TokenExpiredError') {
|
|
65
|
+
wrappedError = new UnauthorizedError(
|
|
66
|
+
{ reason: 'Token has expired' },
|
|
67
|
+
error,
|
|
68
|
+
)
|
|
69
|
+
} else if (error.name === 'JsonWebTokenError') {
|
|
70
|
+
wrappedError = new UnauthorizedError({ reason: 'Invalid token' }, error)
|
|
71
|
+
} else {
|
|
72
|
+
wrappedError = new UnauthorizedError(
|
|
73
|
+
{ reason: 'Failed to verify token' },
|
|
74
|
+
error,
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { valid: false, error: wrappedError }
|
|
79
|
+
}
|
|
39
80
|
}
|
|
40
81
|
|
|
41
82
|
/**
|
|
42
|
-
* Safe verify with
|
|
83
|
+
* Safe verify with options — never throws, returns structured result with UnauthorizedError on failure
|
|
43
84
|
*/
|
|
44
85
|
export const safeVerifyTokenWithOptions = (
|
|
45
86
|
token: string,
|
|
46
87
|
secret: Secret,
|
|
47
|
-
options:
|
|
88
|
+
options: VerifyOptions = {},
|
|
48
89
|
): VerificationResult => {
|
|
49
90
|
try {
|
|
50
91
|
const decoded = verify(token, secret, options)
|
|
51
92
|
return { valid: true, payload: decoded }
|
|
52
|
-
} catch (error) {
|
|
53
|
-
|
|
93
|
+
} catch (error: any) {
|
|
94
|
+
let wrappedError: UnauthorizedError
|
|
95
|
+
|
|
96
|
+
if (error.name === 'TokenExpiredError') {
|
|
97
|
+
wrappedError = new UnauthorizedError(
|
|
98
|
+
{ reason: 'Token has expired' },
|
|
99
|
+
error instanceof Error ? error : undefined,
|
|
100
|
+
)
|
|
101
|
+
} else if (error.name === 'JsonWebTokenError') {
|
|
102
|
+
wrappedError = new UnauthorizedError(
|
|
103
|
+
{
|
|
104
|
+
reason: 'Invalid token',
|
|
105
|
+
},
|
|
106
|
+
error instanceof Error ? error : undefined,
|
|
107
|
+
)
|
|
108
|
+
} else {
|
|
109
|
+
wrappedError = new UnauthorizedError(
|
|
110
|
+
{ reason: 'Failed to verify token' },
|
|
111
|
+
error instanceof Error ? error : undefined,
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return { valid: false, error: wrappedError }
|
|
54
116
|
}
|
|
55
117
|
}
|
|
@@ -13,8 +13,11 @@ export const hashPassword = async (
|
|
|
13
13
|
ensureValidPassword(password)
|
|
14
14
|
const salt = await bcrypt.genSalt(saltRounds)
|
|
15
15
|
return bcrypt.hash(password, salt)
|
|
16
|
-
} catch (
|
|
17
|
-
throw new InternalServerError(
|
|
16
|
+
} catch (error) {
|
|
17
|
+
throw new InternalServerError(
|
|
18
|
+
{ reason: 'Password hashing failed' },
|
|
19
|
+
error instanceof Error ? error : undefined,
|
|
20
|
+
)
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -30,8 +33,11 @@ export const hashPasswordSync = (password: string, saltRounds = 10): string => {
|
|
|
30
33
|
ensureValidPassword(password)
|
|
31
34
|
const salt = bcrypt.genSaltSync(saltRounds)
|
|
32
35
|
return bcrypt.hashSync(password, salt)
|
|
33
|
-
} catch (
|
|
34
|
-
throw new InternalServerError(
|
|
36
|
+
} catch (error) {
|
|
37
|
+
throw new InternalServerError(
|
|
38
|
+
{ reason: 'Password hashing failed' },
|
|
39
|
+
error instanceof Error ? error : undefined,
|
|
40
|
+
)
|
|
35
41
|
}
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -37,23 +37,18 @@ export class PasswordManager implements IPasswordManager {
|
|
|
37
37
|
async hash(password: string, salt?: string): Promise<HashedPassword> {
|
|
38
38
|
try {
|
|
39
39
|
ensureValidPassword(password)
|
|
40
|
-
|
|
41
|
-
// Validate password meets basic requirements
|
|
42
40
|
this.validate(password)
|
|
43
41
|
|
|
44
42
|
const saltRounds = this.defaultConfig.saltRounds!
|
|
45
|
-
let passwordSalt = salt
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
let finalSalt = salt
|
|
45
|
+
if (!finalSalt) {
|
|
46
|
+
finalSalt = await bcrypt.genSalt(saltRounds)
|
|
49
47
|
}
|
|
50
48
|
|
|
51
|
-
const hash = await bcrypt.hash(password,
|
|
49
|
+
const hash = await bcrypt.hash(password, finalSalt)
|
|
52
50
|
|
|
53
|
-
return {
|
|
54
|
-
hash,
|
|
55
|
-
salt: passwordSalt,
|
|
56
|
-
}
|
|
51
|
+
return { hash, salt: finalSalt }
|
|
57
52
|
} catch (error) {
|
|
58
53
|
if (
|
|
59
54
|
error instanceof BadRequestError ||
|
|
@@ -61,7 +56,10 @@ export class PasswordManager implements IPasswordManager {
|
|
|
61
56
|
) {
|
|
62
57
|
throw error
|
|
63
58
|
}
|
|
64
|
-
throw new BadRequestError(
|
|
59
|
+
throw new BadRequestError(
|
|
60
|
+
{ reason: 'Failed to hash password' },
|
|
61
|
+
error instanceof Error ? error : undefined,
|
|
62
|
+
)
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
65
|
|
|
@@ -70,21 +68,11 @@ export class PasswordManager implements IPasswordManager {
|
|
|
70
68
|
*/
|
|
71
69
|
async verify(password: string, hash: string, salt: string): Promise<boolean> {
|
|
72
70
|
try {
|
|
73
|
-
if (!password || !hash || !salt)
|
|
74
|
-
return false
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// First verify with the provided salt
|
|
78
|
-
const isValid = await bcrypt.compare(password, hash)
|
|
79
|
-
|
|
80
|
-
// If invalid and different salt was used, try regenerating hash with new salt
|
|
81
|
-
if (!isValid && salt !== this.defaultConfig.saltRounds?.toString()) {
|
|
82
|
-
const newHash = await bcrypt.hash(password, salt)
|
|
83
|
-
return newHash === hash
|
|
84
|
-
}
|
|
71
|
+
if (!password || !hash || !salt) return false
|
|
85
72
|
|
|
86
|
-
|
|
87
|
-
|
|
73
|
+
// bcrypt compare works directly with hash
|
|
74
|
+
return await bcrypt.compare(password, hash)
|
|
75
|
+
} catch {
|
|
88
76
|
return false
|
|
89
77
|
}
|
|
90
78
|
}
|
|
@@ -96,37 +84,31 @@ export class PasswordManager implements IPasswordManager {
|
|
|
96
84
|
const config = { ...this.defaultConfig, ...options }
|
|
97
85
|
|
|
98
86
|
if (length < config.minLength! || length > config.maxLength!) {
|
|
99
|
-
throw new ValidationError(
|
|
100
|
-
`Password length must be between ${config.minLength} and ${config.maxLength}`,
|
|
101
|
-
)
|
|
87
|
+
throw new ValidationError({
|
|
88
|
+
reason: `Password length must be between ${config.minLength} and ${config.maxLength}`,
|
|
89
|
+
})
|
|
102
90
|
}
|
|
103
91
|
|
|
104
92
|
let charset = 'abcdefghijklmnopqrstuvwxyz'
|
|
105
|
-
|
|
106
93
|
if (config.requireUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
107
94
|
if (config.requireNumbers) charset += '0123456789'
|
|
108
95
|
if (config.requireSpecialChars) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?'
|
|
109
96
|
|
|
110
|
-
let password = ''
|
|
111
97
|
const randomBytes = crypto.randomBytes(length)
|
|
112
|
-
|
|
98
|
+
let password = ''
|
|
113
99
|
for (let i = 0; i < length; i++) {
|
|
114
100
|
password += charset[randomBytes[i] % charset.length]
|
|
115
101
|
}
|
|
116
102
|
|
|
117
|
-
// Ensure
|
|
118
|
-
if (config.requireUppercase && !/[A-Z]/.test(password))
|
|
103
|
+
// Ensure requirements
|
|
104
|
+
if (config.requireUppercase && !/[A-Z]/.test(password))
|
|
119
105
|
password = password.replace(/[a-z]/, 'A')
|
|
120
|
-
|
|
121
|
-
if (config.requireLowercase && !/[a-z]/.test(password)) {
|
|
106
|
+
if (config.requireLowercase && !/[a-z]/.test(password))
|
|
122
107
|
password = password.replace(/[A-Z]/, 'a')
|
|
123
|
-
|
|
124
|
-
if (config.requireNumbers && !/[0-9]/.test(password)) {
|
|
108
|
+
if (config.requireNumbers && !/[0-9]/.test(password))
|
|
125
109
|
password = password.replace(/[A-Za-z]/, '0')
|
|
126
|
-
|
|
127
|
-
if (config.requireSpecialChars && !/[^A-Za-z0-9]/.test(password)) {
|
|
110
|
+
if (config.requireSpecialChars && !/[^A-Za-z0-9]/.test(password))
|
|
128
111
|
password = password.replace(/[A-Za-z0-9]/, '!')
|
|
129
|
-
}
|
|
130
112
|
|
|
131
113
|
return password
|
|
132
114
|
}
|
|
@@ -141,57 +123,35 @@ export class PasswordManager implements IPasswordManager {
|
|
|
141
123
|
const finalConfig = { ...this.defaultConfig, ...config }
|
|
142
124
|
const errors: string[] = []
|
|
143
125
|
|
|
144
|
-
|
|
145
|
-
if (!password || typeof password !== 'string') {
|
|
126
|
+
if (!password || typeof password !== 'string')
|
|
146
127
|
errors.push('Password must be a non-empty string')
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// Length validation
|
|
150
|
-
if (password.length < finalConfig.minLength!) {
|
|
128
|
+
if (password.length < finalConfig.minLength!)
|
|
151
129
|
errors.push(
|
|
152
|
-
`Password must be at least ${finalConfig.minLength} characters
|
|
130
|
+
`Password must be at least ${finalConfig.minLength} characters`,
|
|
153
131
|
)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (password.length > finalConfig.maxLength!) {
|
|
132
|
+
if (password.length > finalConfig.maxLength!)
|
|
157
133
|
errors.push(
|
|
158
134
|
`Password must not exceed ${finalConfig.maxLength} characters`,
|
|
159
135
|
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// Complexity requirements
|
|
163
|
-
if (finalConfig.requireUppercase && !/[A-Z]/.test(password)) {
|
|
136
|
+
if (finalConfig.requireUppercase && !/[A-Z]/.test(password))
|
|
164
137
|
errors.push('Password must contain at least one uppercase letter')
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (finalConfig.requireLowercase && !/[a-z]/.test(password)) {
|
|
138
|
+
if (finalConfig.requireLowercase && !/[a-z]/.test(password))
|
|
168
139
|
errors.push('Password must contain at least one lowercase letter')
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (finalConfig.requireNumbers && !/[0-9]/.test(password)) {
|
|
140
|
+
if (finalConfig.requireNumbers && !/[0-9]/.test(password))
|
|
172
141
|
errors.push('Password must contain at least one number')
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (finalConfig.requireSpecialChars && !/[^A-Za-z0-9]/.test(password)) {
|
|
142
|
+
if (finalConfig.requireSpecialChars && !/[^A-Za-z0-9]/.test(password))
|
|
176
143
|
errors.push('Password must contain at least one special character')
|
|
177
|
-
}
|
|
178
144
|
|
|
179
|
-
// Custom rules
|
|
180
145
|
if (finalConfig.customRules) {
|
|
181
146
|
finalConfig.customRules.forEach((rule) => {
|
|
182
|
-
if (!rule.test(password))
|
|
183
|
-
errors.push(rule.message)
|
|
184
|
-
}
|
|
147
|
+
if (!rule.test(password)) errors.push(rule.message)
|
|
185
148
|
})
|
|
186
149
|
}
|
|
187
150
|
|
|
188
|
-
const strength = this.checkStrength(password)
|
|
189
|
-
const isValid = errors.length === 0
|
|
190
|
-
|
|
191
151
|
return {
|
|
192
|
-
isValid,
|
|
152
|
+
isValid: errors.length === 0,
|
|
193
153
|
errors,
|
|
194
|
-
strength,
|
|
154
|
+
strength: this.checkStrength(password),
|
|
195
155
|
}
|
|
196
156
|
}
|
|
197
157
|
|
|
@@ -200,60 +160,42 @@ export class PasswordManager implements IPasswordManager {
|
|
|
200
160
|
*/
|
|
201
161
|
checkStrength(password: string): PasswordStrength {
|
|
202
162
|
const entropy = estimatePasswordEntropy(password)
|
|
203
|
-
|
|
204
163
|
let score = 0
|
|
205
164
|
const feedback: string[] = []
|
|
206
165
|
const suggestions: string[] = []
|
|
207
166
|
|
|
208
|
-
/* ---------------- Entropy baseline ---------------- */
|
|
209
|
-
|
|
210
167
|
if (entropy < 28) {
|
|
211
168
|
feedback.push('Password is easy to guess')
|
|
212
169
|
suggestions.push('Use more unique characters and length')
|
|
213
|
-
} else if (entropy < 36)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
score += 2
|
|
217
|
-
} else {
|
|
218
|
-
score += 3
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/* ---------------- Length scoring ---------------- */
|
|
170
|
+
} else if (entropy < 36) score++
|
|
171
|
+
else if (entropy < 60) score += 2
|
|
172
|
+
else score += 3
|
|
222
173
|
|
|
223
174
|
if (password.length >= 12) score++
|
|
224
175
|
if (password.length >= 16) score++
|
|
225
176
|
|
|
226
|
-
/* ---------------- Character variety ---------------- */
|
|
227
|
-
|
|
228
177
|
if (/[a-z]/.test(password)) score++
|
|
229
178
|
if (/[A-Z]/.test(password)) score++
|
|
230
179
|
if (/[0-9]/.test(password)) score++
|
|
231
180
|
if (/[^A-Za-z0-9]/.test(password)) score++
|
|
232
181
|
|
|
233
|
-
/* ---------------- Pattern deductions ---------------- */
|
|
234
|
-
|
|
235
182
|
if (/^[A-Za-z]+$/.test(password)) {
|
|
236
183
|
score--
|
|
237
184
|
feedback.push('Consider adding numbers or symbols')
|
|
238
185
|
}
|
|
239
|
-
|
|
240
186
|
if (/^[0-9]+$/.test(password)) {
|
|
241
187
|
score -= 2
|
|
242
188
|
feedback.push('Avoid using only numbers')
|
|
243
189
|
}
|
|
244
|
-
|
|
245
190
|
if (/([a-zA-Z0-9])\1{2,}/.test(password)) {
|
|
246
191
|
score--
|
|
247
192
|
feedback.push('Avoid repeated characters')
|
|
248
193
|
}
|
|
249
|
-
|
|
250
194
|
if (/(?:012|123|234|345|456|567|678|789)/.test(password)) {
|
|
251
195
|
score--
|
|
252
196
|
feedback.push('Avoid sequential patterns')
|
|
253
197
|
}
|
|
254
198
|
|
|
255
|
-
/* ---------------- Common passwords ---------------- */
|
|
256
|
-
|
|
257
199
|
const commonPasswords = ['password', '123456', 'qwerty', 'admin', 'letmein']
|
|
258
200
|
if (
|
|
259
201
|
commonPasswords.some((common) => password.toLowerCase().includes(common))
|
|
@@ -262,14 +204,9 @@ export class PasswordManager implements IPasswordManager {
|
|
|
262
204
|
feedback.push('Avoid common passwords')
|
|
263
205
|
}
|
|
264
206
|
|
|
265
|
-
/* ---------------- Clamp score ---------------- */
|
|
266
|
-
|
|
267
207
|
score = Math.max(0, Math.min(4, score))
|
|
268
208
|
|
|
269
|
-
/* ---------------- Strength label ---------------- */
|
|
270
|
-
|
|
271
209
|
let label: PasswordStrength['label']
|
|
272
|
-
|
|
273
210
|
switch (score) {
|
|
274
211
|
case 0:
|
|
275
212
|
label = 'very-weak'
|
|
@@ -295,20 +232,13 @@ export class PasswordManager implements IPasswordManager {
|
|
|
295
232
|
label = 'very-weak'
|
|
296
233
|
}
|
|
297
234
|
|
|
298
|
-
return {
|
|
299
|
-
score,
|
|
300
|
-
label,
|
|
301
|
-
feedback,
|
|
302
|
-
suggestions,
|
|
303
|
-
}
|
|
235
|
+
return { score, label, feedback, suggestions }
|
|
304
236
|
}
|
|
305
237
|
|
|
306
238
|
/**
|
|
307
|
-
* Check if password hash needs upgrade (
|
|
239
|
+
* Check if password hash needs upgrade (saltRounds change)
|
|
308
240
|
*/
|
|
309
241
|
needsUpgrade(_hash: string, _currentConfig: PasswordConfig): boolean {
|
|
310
|
-
// Simple heuristic: if the hash doesn't match current salt rounds pattern
|
|
311
|
-
// In practice, you'd need to store the salt rounds with the hash
|
|
312
242
|
return false
|
|
313
243
|
}
|
|
314
244
|
}
|
|
@@ -8,7 +8,8 @@ export const isPasswordStrong = (
|
|
|
8
8
|
password: string,
|
|
9
9
|
options: PasswordStrengthOptions = {},
|
|
10
10
|
): boolean => {
|
|
11
|
-
if (!password)
|
|
11
|
+
if (!password)
|
|
12
|
+
throw new BadRequestError({ reason: 'Invalid password provided' })
|
|
12
13
|
|
|
13
14
|
const {
|
|
14
15
|
minLength = 8,
|
|
@@ -19,17 +20,21 @@ export const isPasswordStrong = (
|
|
|
19
20
|
} = options
|
|
20
21
|
|
|
21
22
|
if (password.length < minLength)
|
|
22
|
-
throw new ValidationError(
|
|
23
|
-
`Password must be at least ${minLength} characters`,
|
|
24
|
-
)
|
|
23
|
+
throw new ValidationError({
|
|
24
|
+
reason: `Password must be at least ${minLength} characters long`,
|
|
25
|
+
})
|
|
25
26
|
if (requireUppercase && !/[A-Z]/.test(password))
|
|
26
|
-
throw new ValidationError(
|
|
27
|
+
throw new ValidationError({
|
|
28
|
+
reason: 'Password must include uppercase letters',
|
|
29
|
+
})
|
|
27
30
|
if (requireLowercase && !/[a-z]/.test(password))
|
|
28
|
-
throw new ValidationError(
|
|
31
|
+
throw new ValidationError({
|
|
32
|
+
reason: 'Password must include lowercase letters',
|
|
33
|
+
})
|
|
29
34
|
if (requireNumbers && !/[0-9]/.test(password))
|
|
30
|
-
throw new ValidationError('Password must include numbers')
|
|
35
|
+
throw new ValidationError({ reason: 'Password must include numbers' })
|
|
31
36
|
if (requireSymbols && !/[^A-Za-z0-9]/.test(password))
|
|
32
|
-
throw new ValidationError('Password must include symbols')
|
|
37
|
+
throw new ValidationError({ reason: 'Password must include symbols' })
|
|
33
38
|
|
|
34
39
|
return true
|
|
35
40
|
}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import crypto from 'crypto'
|
|
2
2
|
import { BadRequestError } from '@naman_deep_singh/errors-utils'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Ensure password is a valid non-empty string
|
|
6
|
+
*/
|
|
7
|
+
export function ensureValidPassword(password: string): void {
|
|
5
8
|
if (!password || typeof password !== 'string') {
|
|
6
|
-
throw new BadRequestError('Invalid password provided')
|
|
9
|
+
throw new BadRequestError({ reason: 'Invalid password provided' })
|
|
7
10
|
}
|
|
8
11
|
}
|
|
9
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Timing-safe comparison between two strings
|
|
15
|
+
*/
|
|
10
16
|
export function safeCompare(a: string, b: string): boolean {
|
|
11
17
|
const bufA = Buffer.from(a)
|
|
12
18
|
const bufB = Buffer.from(b)
|
|
@@ -16,16 +22,26 @@ export function safeCompare(a: string, b: string): boolean {
|
|
|
16
22
|
return crypto.timingSafeEqual(bufA, bufB)
|
|
17
23
|
}
|
|
18
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Estimate password entropy based on character pool
|
|
27
|
+
*/
|
|
19
28
|
export function estimatePasswordEntropy(password: string): number {
|
|
20
29
|
let pool = 0
|
|
30
|
+
|
|
21
31
|
if (/[a-z]/.test(password)) pool += 26
|
|
22
32
|
if (/[A-Z]/.test(password)) pool += 26
|
|
23
33
|
if (/[0-9]/.test(password)) pool += 10
|
|
24
34
|
if (/[^A-Za-z0-9]/.test(password)) pool += 32
|
|
25
35
|
|
|
36
|
+
// If no characters matched, fallback to 1 to avoid log2(0)
|
|
37
|
+
if (pool === 0) pool = 1
|
|
38
|
+
|
|
26
39
|
return password.length * Math.log2(pool)
|
|
27
40
|
}
|
|
28
41
|
|
|
29
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Normalize password string to a consistent form
|
|
44
|
+
*/
|
|
45
|
+
export function normalizePassword(password: string): string {
|
|
30
46
|
return password.normalize('NFKC')
|
|
31
47
|
}
|
|
@@ -10,10 +10,11 @@ export const verifyPassword = async (
|
|
|
10
10
|
): Promise<boolean> => {
|
|
11
11
|
try {
|
|
12
12
|
const result = await bcrypt.compare(password, hash)
|
|
13
|
-
if (!result)
|
|
13
|
+
if (!result)
|
|
14
|
+
throw new UnauthorizedError({ reason: 'Password verification failed' })
|
|
14
15
|
return result
|
|
15
16
|
} catch {
|
|
16
|
-
throw new UnauthorizedError('Password verification failed')
|
|
17
|
+
throw new UnauthorizedError({ reason: 'Password verification failed' })
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -31,10 +32,11 @@ export async function verifyPasswordWithPepper(
|
|
|
31
32
|
export const verifyPasswordSync = (password: string, hash: string): boolean => {
|
|
32
33
|
try {
|
|
33
34
|
const result = bcrypt.compareSync(password, hash)
|
|
34
|
-
if (!result)
|
|
35
|
+
if (!result)
|
|
36
|
+
throw new UnauthorizedError({ reason: 'Password verification failed' })
|
|
35
37
|
return result
|
|
36
38
|
} catch (_error) {
|
|
37
|
-
throw new UnauthorizedError('Password verification failed')
|
|
39
|
+
throw new UnauthorizedError({ reason: 'Password verification failed' })
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @naman_deep_singh/server-utils
|
|
2
2
|
|
|
3
|
-
**Version:** 1.
|
|
3
|
+
**Version:** 1.5.1 (with integrated cache & session support)
|
|
4
4
|
|
|
5
5
|
Extensible server utilities for Express.js microservices with multi-protocol support, integrated caching, session management, and TypeScript.
|
|
6
6
|
|
|
@@ -179,8 +179,8 @@ class ExpressServer {
|
|
|
179
179
|
});
|
|
180
180
|
console.log(`✅ [${serverName}] Cache initialized successfully (adapter: ${cacheConfig.adapter || 'memory'})`);
|
|
181
181
|
}
|
|
182
|
-
catch (
|
|
183
|
-
console.error(`❌ [${serverName}] Failed to initialize cache (fallback to memory if enabled):`,
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error(`❌ [${serverName}] Failed to initialize cache (fallback to memory if enabled):`, error instanceof Error ? error.message : error);
|
|
184
184
|
// Cache initialization error is critical but we continue to allow graceful fallback
|
|
185
185
|
}
|
|
186
186
|
}
|
|
@@ -218,14 +218,14 @@ class ExpressServer {
|
|
|
218
218
|
this.app.use((0, middleware_1.useSession)(cookieName));
|
|
219
219
|
console.log(`✅ [${serverName}] Session middleware enabled (cookie: ${cookieName}, TTL: ${ttl}s)`);
|
|
220
220
|
}
|
|
221
|
-
catch (
|
|
222
|
-
console.error(`❌ [${serverName}] Session middleware not available:`,
|
|
221
|
+
catch (error) {
|
|
222
|
+
console.error(`❌ [${serverName}] Session middleware not available:`, error instanceof Error ? error.message : error);
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
-
catch (
|
|
228
|
-
console.error(`❌ [${serverName}] Error during cache/session setup:`,
|
|
227
|
+
catch (error) {
|
|
228
|
+
console.error(`❌ [${serverName}] Error during cache/session setup:`, error instanceof Error ? error.message : error);
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
setupPeriodicHealthMonitoring() {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { Request, RequestHandler } from '
|
|
1
|
+
import type { Request, RequestHandler } from 'express';
|
|
2
2
|
export interface AuthConfig {
|
|
3
3
|
secret: string;
|
|
4
|
-
unauthorizedMessage?: string;
|
|
5
4
|
tokenExtractor?: (req: Request) => string | null;
|
|
6
5
|
}
|
|
7
6
|
export declare function createAuthMiddleware(config: AuthConfig): RequestHandler;
|
|
@@ -4,7 +4,7 @@ exports.createAuthMiddleware = createAuthMiddleware;
|
|
|
4
4
|
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
5
5
|
const security_1 = require("@naman_deep_singh/security");
|
|
6
6
|
function createAuthMiddleware(config) {
|
|
7
|
-
const { secret,
|
|
7
|
+
const { secret, tokenExtractor = (req) => (0, security_1.extractToken)({
|
|
8
8
|
header: req.headers.authorization || undefined,
|
|
9
9
|
cookies: req.cookies,
|
|
10
10
|
query: req.query,
|
|
@@ -12,30 +12,33 @@ function createAuthMiddleware(config) {
|
|
|
12
12
|
}), } = config;
|
|
13
13
|
return async (req, _res, next) => {
|
|
14
14
|
try {
|
|
15
|
-
// Extract token
|
|
15
|
+
// 1️⃣ Extract token
|
|
16
16
|
const token = tokenExtractor(req);
|
|
17
17
|
if (!token) {
|
|
18
|
-
|
|
18
|
+
// No cause → client mistake
|
|
19
|
+
return next(new errors_utils_1.TokenMalformedError({
|
|
19
20
|
reason: 'No token provided',
|
|
20
|
-
});
|
|
21
|
-
return next(error);
|
|
21
|
+
}));
|
|
22
22
|
}
|
|
23
|
-
//
|
|
23
|
+
// 2️⃣ Verify token
|
|
24
24
|
const result = (0, security_1.safeVerifyToken)(token, secret);
|
|
25
25
|
if (!result.valid) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
26
|
+
// Token expired
|
|
27
|
+
if (result.error?.name === 'TokenExpiredError') {
|
|
28
|
+
return next(new errors_utils_1.TokenExpiredError({ reason: 'Token expired' }, result.error));
|
|
29
|
+
}
|
|
30
|
+
// Token invalid / malformed
|
|
31
|
+
return next(new errors_utils_1.TokenMalformedError({
|
|
32
|
+
reason: 'Invalid token',
|
|
33
|
+
}, result.error));
|
|
31
34
|
}
|
|
32
|
-
// Attach
|
|
35
|
+
// 3️⃣ Attach payload
|
|
33
36
|
req.user = result.payload;
|
|
34
37
|
next();
|
|
35
38
|
}
|
|
36
39
|
catch (error) {
|
|
37
|
-
|
|
38
|
-
return next(
|
|
40
|
+
// Unexpected error → always pass cause
|
|
41
|
+
return next(new errors_utils_1.UnauthorizedError({ reason: 'Authentication failed' }, error instanceof Error ? error : undefined));
|
|
39
42
|
}
|
|
40
43
|
};
|
|
41
44
|
}
|