@naman_deep_singh/security 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +153 -355
- package/dist/cjs/core/crypto/cryptoManager.d.ts +5 -5
- package/dist/cjs/core/crypto/cryptoManager.js +42 -25
- package/dist/cjs/core/jwt/decode.js +4 -1
- package/dist/cjs/core/jwt/generateTokens.d.ts +1 -1
- package/dist/cjs/core/jwt/generateTokens.js +7 -4
- package/dist/cjs/core/jwt/jwtManager.d.ts +19 -43
- package/dist/cjs/core/jwt/jwtManager.js +72 -202
- package/dist/cjs/core/jwt/parseDuration.js +3 -2
- package/dist/cjs/core/jwt/signToken.js +2 -1
- package/dist/cjs/core/jwt/validateToken.d.ts +10 -7
- package/dist/cjs/core/jwt/validateToken.js +14 -11
- package/dist/cjs/core/jwt/verify.d.ts +9 -10
- package/dist/cjs/core/jwt/verify.js +57 -14
- package/dist/cjs/core/password/hash.js +4 -4
- package/dist/cjs/core/password/passwordManager.d.ts +2 -2
- package/dist/cjs/core/password/passwordManager.js +43 -82
- package/dist/cjs/core/password/strength.js +5 -5
- package/dist/cjs/core/password/utils.d.ts +12 -0
- package/dist/cjs/core/password/utils.js +16 -1
- package/dist/cjs/core/password/verify.js +5 -5
- package/dist/cjs/index.d.ts +2 -7
- package/dist/esm/core/crypto/cryptoManager.d.ts +5 -5
- package/dist/esm/core/crypto/cryptoManager.js +42 -25
- package/dist/esm/core/jwt/decode.js +4 -1
- package/dist/esm/core/jwt/generateTokens.d.ts +1 -1
- package/dist/esm/core/jwt/generateTokens.js +7 -4
- package/dist/esm/core/jwt/jwtManager.d.ts +19 -43
- package/dist/esm/core/jwt/jwtManager.js +73 -203
- package/dist/esm/core/jwt/parseDuration.js +3 -2
- package/dist/esm/core/jwt/signToken.js +2 -1
- package/dist/esm/core/jwt/validateToken.d.ts +10 -7
- package/dist/esm/core/jwt/validateToken.js +14 -11
- package/dist/esm/core/jwt/verify.d.ts +9 -10
- package/dist/esm/core/jwt/verify.js +55 -12
- package/dist/esm/core/password/hash.js +4 -4
- package/dist/esm/core/password/passwordManager.d.ts +2 -2
- package/dist/esm/core/password/passwordManager.js +43 -82
- package/dist/esm/core/password/strength.js +5 -5
- package/dist/esm/core/password/utils.d.ts +12 -0
- package/dist/esm/core/password/utils.js +16 -1
- package/dist/esm/core/password/verify.js +5 -5
- package/dist/esm/index.d.ts +2 -7
- package/dist/types/core/crypto/cryptoManager.d.ts +5 -5
- package/dist/types/core/jwt/generateTokens.d.ts +1 -1
- package/dist/types/core/jwt/jwtManager.d.ts +19 -43
- package/dist/types/core/jwt/validateToken.d.ts +10 -7
- package/dist/types/core/jwt/verify.d.ts +9 -10
- package/dist/types/core/password/passwordManager.d.ts +2 -2
- package/dist/types/core/password/utils.d.ts +12 -0
- package/dist/types/index.d.ts +2 -7
- package/package.json +2 -2
|
@@ -24,7 +24,7 @@ export declare class CryptoManager {
|
|
|
24
24
|
/**
|
|
25
25
|
* Encrypt data using the default or specified algorithm
|
|
26
26
|
*/
|
|
27
|
-
encrypt(plaintext: string, key: string,
|
|
27
|
+
encrypt(plaintext: string, key: string, _options?: {
|
|
28
28
|
algorithm?: string;
|
|
29
29
|
encoding?: BufferEncoding;
|
|
30
30
|
iv?: string;
|
|
@@ -32,7 +32,7 @@ export declare class CryptoManager {
|
|
|
32
32
|
/**
|
|
33
33
|
* Decrypt data using the default or specified algorithm
|
|
34
34
|
*/
|
|
35
|
-
decrypt(encryptedData: string, key: string,
|
|
35
|
+
decrypt(encryptedData: string, key: string, _options?: {
|
|
36
36
|
algorithm?: string;
|
|
37
37
|
encoding?: BufferEncoding;
|
|
38
38
|
iv?: string;
|
|
@@ -40,18 +40,18 @@ export declare class CryptoManager {
|
|
|
40
40
|
/**
|
|
41
41
|
* Generate HMAC signature
|
|
42
42
|
*/
|
|
43
|
-
generateHmac(data: string, secret: string,
|
|
43
|
+
generateHmac(data: string, secret: string, _options?: {
|
|
44
44
|
algorithm?: string;
|
|
45
45
|
encoding?: BufferEncoding;
|
|
46
46
|
}): string;
|
|
47
47
|
/**
|
|
48
48
|
* Generate cryptographically secure random bytes
|
|
49
49
|
*/
|
|
50
|
-
generateSecureRandom(length: number,
|
|
50
|
+
generateSecureRandom(length: number, _encoding?: BufferEncoding): string;
|
|
51
51
|
/**
|
|
52
52
|
* Verify HMAC signature
|
|
53
53
|
*/
|
|
54
|
-
verifyHmac(data: string, secret: string, signature: string,
|
|
54
|
+
verifyHmac(data: string, secret: string, signature: string, _options?: {
|
|
55
55
|
algorithm?: string;
|
|
56
56
|
encoding?: BufferEncoding;
|
|
57
57
|
}): boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.cryptoManager = exports.createCryptoManager = exports.CryptoManager = void 0;
|
|
4
|
+
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
4
5
|
const index_1 = require("./index");
|
|
5
6
|
/**
|
|
6
7
|
* Default configuration
|
|
@@ -33,23 +34,33 @@ class CryptoManager {
|
|
|
33
34
|
/**
|
|
34
35
|
* Encrypt data using the default or specified algorithm
|
|
35
36
|
*/
|
|
36
|
-
encrypt(plaintext, key,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
encrypt(plaintext, key, _options) {
|
|
38
|
+
try {
|
|
39
|
+
return (0, index_1.encrypt)(plaintext, key);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw new errors_utils_1.InternalServerError(undefined, {
|
|
43
|
+
message: 'Encryption failed',
|
|
44
|
+
}, err instanceof Error ? err : undefined);
|
|
45
|
+
}
|
|
40
46
|
}
|
|
41
47
|
/**
|
|
42
48
|
* Decrypt data using the default or specified algorithm
|
|
43
49
|
*/
|
|
44
|
-
decrypt(encryptedData, key,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
50
|
+
decrypt(encryptedData, key, _options) {
|
|
51
|
+
try {
|
|
52
|
+
return (0, index_1.decrypt)(encryptedData, key);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
throw new errors_utils_1.InternalServerError(undefined, {
|
|
56
|
+
message: 'Decryption failed',
|
|
57
|
+
}, err instanceof Error ? err : undefined);
|
|
58
|
+
}
|
|
48
59
|
}
|
|
49
60
|
/**
|
|
50
61
|
* Generate HMAC signature
|
|
51
62
|
*/
|
|
52
|
-
generateHmac(data, secret,
|
|
63
|
+
generateHmac(data, secret, _options) {
|
|
53
64
|
// Use the basic HMAC sign function for now
|
|
54
65
|
// TODO: Add support for different algorithms
|
|
55
66
|
return (0, index_1.hmacSign)(data, secret);
|
|
@@ -57,14 +68,14 @@ class CryptoManager {
|
|
|
57
68
|
/**
|
|
58
69
|
* Generate cryptographically secure random bytes
|
|
59
70
|
*/
|
|
60
|
-
generateSecureRandom(length,
|
|
71
|
+
generateSecureRandom(length, _encoding = 'hex') {
|
|
61
72
|
// Use the basic random token function
|
|
62
73
|
return (0, index_1.randomToken)(length);
|
|
63
74
|
}
|
|
64
75
|
/**
|
|
65
76
|
* Verify HMAC signature
|
|
66
77
|
*/
|
|
67
|
-
verifyHmac(data, secret, signature,
|
|
78
|
+
verifyHmac(data, secret, signature, _options) {
|
|
68
79
|
// Use the basic HMAC verify function
|
|
69
80
|
return (0, index_1.hmacVerify)(data, secret, signature);
|
|
70
81
|
}
|
|
@@ -76,7 +87,9 @@ class CryptoManager {
|
|
|
76
87
|
const crypto = require('crypto');
|
|
77
88
|
crypto.pbkdf2(password, salt, iterations, keyLength, 'sha256', (err, derivedKey) => {
|
|
78
89
|
if (err) {
|
|
79
|
-
reject(
|
|
90
|
+
reject(new errors_utils_1.InternalServerError(undefined, {
|
|
91
|
+
message: 'Key derivation failed',
|
|
92
|
+
}, err instanceof Error ? err : undefined));
|
|
80
93
|
}
|
|
81
94
|
else {
|
|
82
95
|
resolve(derivedKey.toString('hex'));
|
|
@@ -102,7 +115,7 @@ class CryptoManager {
|
|
|
102
115
|
* Generate a secure key pair for asymmetric encryption
|
|
103
116
|
*/
|
|
104
117
|
generateKeyPair(options) {
|
|
105
|
-
return new Promise((resolve,
|
|
118
|
+
return new Promise((resolve, _reject) => {
|
|
106
119
|
const crypto = require('crypto');
|
|
107
120
|
const keyPair = crypto.generateKeyPairSync('rsa', {
|
|
108
121
|
modulusLength: options?.modulusLength || 2048,
|
|
@@ -122,7 +135,7 @@ class CryptoManager {
|
|
|
122
135
|
* Encrypt data using RSA public key
|
|
123
136
|
*/
|
|
124
137
|
rsaEncrypt(data, publicKey) {
|
|
125
|
-
return new Promise((resolve,
|
|
138
|
+
return new Promise((resolve, _reject) => {
|
|
126
139
|
const crypto = require('crypto');
|
|
127
140
|
const buffer = Buffer.from(data, 'utf8');
|
|
128
141
|
const encrypted = crypto.publicEncrypt(publicKey, buffer);
|
|
@@ -133,7 +146,7 @@ class CryptoManager {
|
|
|
133
146
|
* Decrypt data using RSA private key
|
|
134
147
|
*/
|
|
135
148
|
rsaDecrypt(encryptedData, privateKey) {
|
|
136
|
-
return new Promise((resolve,
|
|
149
|
+
return new Promise((resolve, _reject) => {
|
|
137
150
|
const crypto = require('crypto');
|
|
138
151
|
const buffer = Buffer.from(encryptedData, 'base64');
|
|
139
152
|
const decrypted = crypto.privateDecrypt(privateKey, buffer);
|
|
@@ -146,15 +159,17 @@ class CryptoManager {
|
|
|
146
159
|
rsaSign(data, privateKey, algorithm = 'sha256') {
|
|
147
160
|
return new Promise((resolve, reject) => {
|
|
148
161
|
const crypto = require('crypto');
|
|
149
|
-
const sign = crypto.createSign(algorithm);
|
|
150
|
-
sign.update(data);
|
|
151
|
-
sign.end();
|
|
152
162
|
try {
|
|
163
|
+
const sign = crypto.createSign(algorithm);
|
|
164
|
+
sign.update(data);
|
|
165
|
+
sign.end();
|
|
153
166
|
const signature = sign.sign(privateKey, 'base64');
|
|
154
167
|
resolve(signature);
|
|
155
168
|
}
|
|
156
|
-
catch (
|
|
157
|
-
reject(
|
|
169
|
+
catch (err) {
|
|
170
|
+
reject(new errors_utils_1.InternalServerError(undefined, {
|
|
171
|
+
message: 'RSA signing failed',
|
|
172
|
+
}, err instanceof Error ? err : undefined));
|
|
158
173
|
}
|
|
159
174
|
});
|
|
160
175
|
}
|
|
@@ -164,15 +179,17 @@ class CryptoManager {
|
|
|
164
179
|
rsaVerify(data, signature, publicKey, algorithm = 'sha256') {
|
|
165
180
|
return new Promise((resolve, reject) => {
|
|
166
181
|
const crypto = require('crypto');
|
|
167
|
-
const verify = crypto.createVerify(algorithm);
|
|
168
|
-
verify.update(data);
|
|
169
|
-
verify.end();
|
|
170
182
|
try {
|
|
183
|
+
const verify = crypto.createVerify(algorithm);
|
|
184
|
+
verify.update(data);
|
|
185
|
+
verify.end();
|
|
171
186
|
const isValid = verify.verify(publicKey, signature, 'base64');
|
|
172
187
|
resolve(isValid);
|
|
173
188
|
}
|
|
174
|
-
catch (
|
|
175
|
-
reject(
|
|
189
|
+
catch (err) {
|
|
190
|
+
reject(new errors_utils_1.InternalServerError(undefined, {
|
|
191
|
+
message: 'RSA verification failed',
|
|
192
|
+
}, err instanceof Error ? err : undefined));
|
|
176
193
|
}
|
|
177
194
|
});
|
|
178
195
|
}
|
|
@@ -4,6 +4,7 @@ exports.decodeToken = decodeToken;
|
|
|
4
4
|
exports.decodeTokenStrict = decodeTokenStrict;
|
|
5
5
|
// src/jwt/decodeToken.ts
|
|
6
6
|
const jsonwebtoken_1 = require("jsonwebtoken");
|
|
7
|
+
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
7
8
|
/**
|
|
8
9
|
* Flexible decode
|
|
9
10
|
* Returns: null | string | JwtPayload
|
|
@@ -19,7 +20,9 @@ function decodeToken(token) {
|
|
|
19
20
|
function decodeTokenStrict(token) {
|
|
20
21
|
const decoded = (0, jsonwebtoken_1.decode)(token);
|
|
21
22
|
if (!decoded || typeof decoded === 'string') {
|
|
22
|
-
throw new
|
|
23
|
+
throw new errors_utils_1.BadRequestError({
|
|
24
|
+
message: 'Invalid JWT payload structure',
|
|
25
|
+
});
|
|
23
26
|
}
|
|
24
27
|
return decoded;
|
|
25
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Secret } from 'jsonwebtoken';
|
|
2
2
|
import type { RefreshToken, TokenPair } from './types';
|
|
3
3
|
export declare const generateTokens: (payload: Record<string, unknown>, accessSecret: Secret, refreshSecret: Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => TokenPair;
|
|
4
4
|
export declare function rotateRefreshToken(oldToken: string, secret: Secret): RefreshToken;
|
|
@@ -4,10 +4,11 @@ exports.generateTokens = void 0;
|
|
|
4
4
|
exports.rotateRefreshToken = rotateRefreshToken;
|
|
5
5
|
const signToken_1 = require("./signToken");
|
|
6
6
|
const verify_1 = require("./verify");
|
|
7
|
+
const errors_utils_1 = require("@naman_deep_singh/errors-utils");
|
|
7
8
|
// Helper function to create branded tokens
|
|
8
|
-
const createBrandedToken = (token, _brand) => {
|
|
9
|
-
return token
|
|
10
|
-
}
|
|
9
|
+
/* const createBrandedToken = <T extends string>(token: string, _brand: T): T => {
|
|
10
|
+
return token as T
|
|
11
|
+
} */
|
|
11
12
|
const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry = '15m', refreshExpiry = '7d') => {
|
|
12
13
|
const accessToken = (0, signToken_1.signToken)(payload, accessSecret, accessExpiry, {
|
|
13
14
|
algorithm: 'HS256',
|
|
@@ -24,7 +25,9 @@ exports.generateTokens = generateTokens;
|
|
|
24
25
|
function rotateRefreshToken(oldToken, secret) {
|
|
25
26
|
const decoded = (0, verify_1.verifyToken)(oldToken, secret);
|
|
26
27
|
if (typeof decoded === 'string') {
|
|
27
|
-
throw new
|
|
28
|
+
throw new errors_utils_1.TokenMalformedError({
|
|
29
|
+
message: 'Invalid token payload — expected JWT payload object',
|
|
30
|
+
});
|
|
28
31
|
}
|
|
29
32
|
const payload = { ...decoded };
|
|
30
33
|
delete payload.iat;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type JwtPayload, type Secret } from 'jsonwebtoken';
|
|
2
|
-
import type { AccessToken, ITokenManager, JWTConfig, RefreshToken, TokenPair
|
|
2
|
+
import type { AccessToken, ITokenManager, JWTConfig, RefreshToken, TokenPair } from '../../interfaces/jwt.interface';
|
|
3
3
|
export declare class JWTManager implements ITokenManager {
|
|
4
4
|
private accessSecret;
|
|
5
5
|
private refreshSecret;
|
|
@@ -8,60 +8,36 @@ export declare class JWTManager implements ITokenManager {
|
|
|
8
8
|
private cache?;
|
|
9
9
|
private cacheTTL;
|
|
10
10
|
constructor(config: JWTConfig);
|
|
11
|
-
/**
|
|
12
|
-
* Generate both access and refresh tokens
|
|
13
|
-
*/
|
|
11
|
+
/** Generate both access and refresh tokens */
|
|
14
12
|
generateTokens(payload: Record<string, unknown>): Promise<TokenPair>;
|
|
15
|
-
/**
|
|
16
|
-
* Generate access token
|
|
17
|
-
*/
|
|
13
|
+
/** Generate access token */
|
|
18
14
|
generateAccessToken(payload: Record<string, unknown>): Promise<AccessToken>;
|
|
19
|
-
/**
|
|
20
|
-
* Generate refresh token
|
|
21
|
-
*/
|
|
15
|
+
/** Generate refresh token */
|
|
22
16
|
generateRefreshToken(payload: Record<string, unknown>): Promise<RefreshToken>;
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Verify refresh token
|
|
29
|
-
*/
|
|
30
|
-
verifyRefreshToken(token: string): Promise<JwtPayload | string>;
|
|
31
|
-
/**
|
|
32
|
-
* Decode token without verification
|
|
33
|
-
*/
|
|
17
|
+
/** Verify access token */
|
|
18
|
+
verifyAccessToken(token: string): Promise<JwtPayload>;
|
|
19
|
+
/** Verify refresh token */
|
|
20
|
+
verifyRefreshToken(token: string): Promise<JwtPayload>;
|
|
21
|
+
/** Decode token without verification */
|
|
34
22
|
decodeToken(token: string, complete?: boolean): JwtPayload | string | null;
|
|
35
|
-
/**
|
|
36
|
-
* Extract token from Authorization header
|
|
37
|
-
*/
|
|
23
|
+
/** Extract token from Authorization header */
|
|
38
24
|
extractTokenFromHeader(authHeader: string): string | null;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
validateToken(token: string, secret: Secret, options?: TokenValidationOptions): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Rotate refresh token
|
|
45
|
-
*/
|
|
25
|
+
/** Validate token without throwing exceptions */
|
|
26
|
+
validateToken(token: string, secret: Secret): boolean;
|
|
27
|
+
/** Rotate refresh token */
|
|
46
28
|
rotateRefreshToken(oldToken: string): Promise<RefreshToken>;
|
|
47
|
-
/**
|
|
48
|
-
* Check if token is expired
|
|
49
|
-
*/
|
|
29
|
+
/** Check if token is expired */
|
|
50
30
|
isTokenExpired(token: string): boolean;
|
|
51
|
-
/**
|
|
52
|
-
* Get token expiration date
|
|
53
|
-
*/
|
|
31
|
+
/** Get token expiration date */
|
|
54
32
|
getTokenExpiration(token: string): Date | null;
|
|
55
|
-
/**
|
|
56
|
-
* Clear token cache
|
|
57
|
-
*/
|
|
33
|
+
/** Clear token cache */
|
|
58
34
|
clearCache(): void;
|
|
59
|
-
/**
|
|
60
|
-
* Get cache statistics
|
|
61
|
-
*/
|
|
35
|
+
/** Get cache statistics */
|
|
62
36
|
getCacheStats(): {
|
|
63
37
|
size: number;
|
|
64
38
|
maxSize: number;
|
|
65
39
|
} | null;
|
|
40
|
+
/** Private helper methods */
|
|
66
41
|
private validatePayload;
|
|
42
|
+
private verifyTokenWithCache;
|
|
67
43
|
}
|