@naman_deep_singh/security 1.3.2 → 1.3.3
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 +1 -1
- package/dist/cjs/core/crypto/cryptoManager.d.ts +5 -5
- package/dist/cjs/core/crypto/cryptoManager.js +8 -8
- package/dist/cjs/core/jwt/generateTokens.d.ts +1 -1
- package/dist/cjs/core/jwt/generateTokens.js +3 -3
- package/dist/cjs/core/jwt/jwtManager.d.ts +1 -1
- package/dist/cjs/core/jwt/jwtManager.js +6 -2
- package/dist/cjs/core/password/hash.js +2 -2
- package/dist/cjs/core/password/passwordManager.d.ts +1 -1
- package/dist/cjs/core/password/passwordManager.js +24 -11
- package/dist/cjs/core/password/verify.js +1 -1
- package/dist/esm/core/crypto/cryptoManager.d.ts +5 -5
- package/dist/esm/core/crypto/cryptoManager.js +8 -8
- package/dist/esm/core/jwt/generateTokens.d.ts +1 -1
- package/dist/esm/core/jwt/generateTokens.js +3 -3
- package/dist/esm/core/jwt/jwtManager.d.ts +1 -1
- package/dist/esm/core/jwt/jwtManager.js +6 -2
- package/dist/esm/core/password/hash.js +2 -2
- package/dist/esm/core/password/passwordManager.d.ts +1 -1
- package/dist/esm/core/password/passwordManager.js +24 -11
- package/dist/esm/core/password/verify.js +1 -1
- 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 +1 -1
- package/dist/types/core/password/passwordManager.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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;
|
|
@@ -33,7 +33,7 @@ class CryptoManager {
|
|
|
33
33
|
/**
|
|
34
34
|
* Encrypt data using the default or specified algorithm
|
|
35
35
|
*/
|
|
36
|
-
encrypt(plaintext, key,
|
|
36
|
+
encrypt(plaintext, key, _options) {
|
|
37
37
|
// For now, use the basic encrypt function
|
|
38
38
|
// TODO: Enhance to support different algorithms and options
|
|
39
39
|
return (0, index_1.encrypt)(plaintext, key);
|
|
@@ -41,7 +41,7 @@ class CryptoManager {
|
|
|
41
41
|
/**
|
|
42
42
|
* Decrypt data using the default or specified algorithm
|
|
43
43
|
*/
|
|
44
|
-
decrypt(encryptedData, key,
|
|
44
|
+
decrypt(encryptedData, key, _options) {
|
|
45
45
|
// For now, use the basic decrypt function
|
|
46
46
|
// TODO: Enhance to support different algorithms and options
|
|
47
47
|
return (0, index_1.decrypt)(encryptedData, key);
|
|
@@ -49,7 +49,7 @@ class CryptoManager {
|
|
|
49
49
|
/**
|
|
50
50
|
* Generate HMAC signature
|
|
51
51
|
*/
|
|
52
|
-
generateHmac(data, secret,
|
|
52
|
+
generateHmac(data, secret, _options) {
|
|
53
53
|
// Use the basic HMAC sign function for now
|
|
54
54
|
// TODO: Add support for different algorithms
|
|
55
55
|
return (0, index_1.hmacSign)(data, secret);
|
|
@@ -57,14 +57,14 @@ class CryptoManager {
|
|
|
57
57
|
/**
|
|
58
58
|
* Generate cryptographically secure random bytes
|
|
59
59
|
*/
|
|
60
|
-
generateSecureRandom(length,
|
|
60
|
+
generateSecureRandom(length, _encoding = 'hex') {
|
|
61
61
|
// Use the basic random token function
|
|
62
62
|
return (0, index_1.randomToken)(length);
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Verify HMAC signature
|
|
66
66
|
*/
|
|
67
|
-
verifyHmac(data, secret, signature,
|
|
67
|
+
verifyHmac(data, secret, signature, _options) {
|
|
68
68
|
// Use the basic HMAC verify function
|
|
69
69
|
return (0, index_1.hmacVerify)(data, secret, signature);
|
|
70
70
|
}
|
|
@@ -102,7 +102,7 @@ class CryptoManager {
|
|
|
102
102
|
* Generate a secure key pair for asymmetric encryption
|
|
103
103
|
*/
|
|
104
104
|
generateKeyPair(options) {
|
|
105
|
-
return new Promise((resolve,
|
|
105
|
+
return new Promise((resolve, _reject) => {
|
|
106
106
|
const crypto = require('crypto');
|
|
107
107
|
const keyPair = crypto.generateKeyPairSync('rsa', {
|
|
108
108
|
modulusLength: options?.modulusLength || 2048,
|
|
@@ -122,7 +122,7 @@ class CryptoManager {
|
|
|
122
122
|
* Encrypt data using RSA public key
|
|
123
123
|
*/
|
|
124
124
|
rsaEncrypt(data, publicKey) {
|
|
125
|
-
return new Promise((resolve,
|
|
125
|
+
return new Promise((resolve, _reject) => {
|
|
126
126
|
const crypto = require('crypto');
|
|
127
127
|
const buffer = Buffer.from(data, 'utf8');
|
|
128
128
|
const encrypted = crypto.publicEncrypt(publicKey, buffer);
|
|
@@ -133,7 +133,7 @@ class CryptoManager {
|
|
|
133
133
|
* Decrypt data using RSA private key
|
|
134
134
|
*/
|
|
135
135
|
rsaDecrypt(encryptedData, privateKey) {
|
|
136
|
-
return new Promise((resolve,
|
|
136
|
+
return new Promise((resolve, _reject) => {
|
|
137
137
|
const crypto = require('crypto');
|
|
138
138
|
const buffer = Buffer.from(encryptedData, 'base64');
|
|
139
139
|
const decrypted = crypto.privateDecrypt(privateKey, buffer);
|
|
@@ -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;
|
|
@@ -5,9 +5,9 @@ exports.rotateRefreshToken = rotateRefreshToken;
|
|
|
5
5
|
const signToken_1 = require("./signToken");
|
|
6
6
|
const verify_1 = require("./verify");
|
|
7
7
|
// Helper function to create branded tokens
|
|
8
|
-
const createBrandedToken = (token, _brand) => {
|
|
9
|
-
return token
|
|
10
|
-
}
|
|
8
|
+
/* const createBrandedToken = <T extends string>(token: string, _brand: T): T => {
|
|
9
|
+
return token as T
|
|
10
|
+
} */
|
|
11
11
|
const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry = '15m', refreshExpiry = '7d') => {
|
|
12
12
|
const accessToken = (0, signToken_1.signToken)(payload, accessSecret, accessExpiry, {
|
|
13
13
|
algorithm: 'HS256',
|
|
@@ -39,7 +39,7 @@ export declare class JWTManager implements ITokenManager {
|
|
|
39
39
|
/**
|
|
40
40
|
* Validate token without throwing exceptions
|
|
41
41
|
*/
|
|
42
|
-
validateToken(token: string, secret: Secret,
|
|
42
|
+
validateToken(token: string, secret: Secret, _options?: TokenValidationOptions): boolean;
|
|
43
43
|
/**
|
|
44
44
|
* Rotate refresh token
|
|
45
45
|
*/
|
|
@@ -141,7 +141,11 @@ class JWTManager {
|
|
|
141
141
|
}
|
|
142
142
|
const decoded = (0, verify_1.verifyToken)(token, this.refreshSecret);
|
|
143
143
|
if (this.cache) {
|
|
144
|
-
this.cache.set(cacheKey, {
|
|
144
|
+
this.cache.set(cacheKey, {
|
|
145
|
+
valid: true,
|
|
146
|
+
payload: decoded,
|
|
147
|
+
timestamp: Date.now(),
|
|
148
|
+
});
|
|
145
149
|
}
|
|
146
150
|
return decoded;
|
|
147
151
|
}
|
|
@@ -197,7 +201,7 @@ class JWTManager {
|
|
|
197
201
|
/**
|
|
198
202
|
* Validate token without throwing exceptions
|
|
199
203
|
*/
|
|
200
|
-
validateToken(token, secret,
|
|
204
|
+
validateToken(token, secret, _options = {}) {
|
|
201
205
|
try {
|
|
202
206
|
if (!token || typeof token !== 'string') {
|
|
203
207
|
return false;
|
|
@@ -18,7 +18,7 @@ const hashPassword = async (password, saltRounds = 10) => {
|
|
|
18
18
|
const salt = await bcryptjs_1.default.genSalt(saltRounds);
|
|
19
19
|
return bcryptjs_1.default.hash(password, salt);
|
|
20
20
|
}
|
|
21
|
-
catch (
|
|
21
|
+
catch (_err) {
|
|
22
22
|
throw new errors_utils_1.InternalServerError('Password hashing failed');
|
|
23
23
|
}
|
|
24
24
|
};
|
|
@@ -35,7 +35,7 @@ const hashPasswordSync = (password, saltRounds = 10) => {
|
|
|
35
35
|
const salt = bcryptjs_1.default.genSaltSync(saltRounds);
|
|
36
36
|
return bcryptjs_1.default.hashSync(password, salt);
|
|
37
37
|
}
|
|
38
|
-
catch (
|
|
38
|
+
catch (_error) {
|
|
39
39
|
throw new errors_utils_1.InternalServerError('Password hashing failed');
|
|
40
40
|
}
|
|
41
41
|
};
|
|
@@ -25,5 +25,5 @@ export declare class PasswordManager implements IPasswordManager {
|
|
|
25
25
|
/**
|
|
26
26
|
* Check if password hash needs upgrade (different salt rounds)
|
|
27
27
|
*/
|
|
28
|
-
needsUpgrade(
|
|
28
|
+
needsUpgrade(_hash: string, _currentConfig: PasswordConfig): boolean;
|
|
29
29
|
}
|
|
@@ -65,7 +65,7 @@ class PasswordManager {
|
|
|
65
65
|
}
|
|
66
66
|
return isValid;
|
|
67
67
|
}
|
|
68
|
-
catch (
|
|
68
|
+
catch (_error) {
|
|
69
69
|
return false;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -158,14 +158,26 @@ class PasswordManager {
|
|
|
158
158
|
let score = 0;
|
|
159
159
|
const feedback = [];
|
|
160
160
|
const suggestions = [];
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
|
|
161
|
+
/* ---------------- Entropy baseline ---------------- */
|
|
162
|
+
if (entropy < 28) {
|
|
163
|
+
feedback.push('Password is easy to guess');
|
|
164
|
+
suggestions.push('Use more unique characters and length');
|
|
165
|
+
}
|
|
166
|
+
else if (entropy < 36) {
|
|
167
|
+
score += 1;
|
|
168
|
+
}
|
|
169
|
+
else if (entropy < 60) {
|
|
170
|
+
score += 2;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
score += 3;
|
|
174
|
+
}
|
|
175
|
+
/* ---------------- Length scoring ---------------- */
|
|
164
176
|
if (password.length >= 12)
|
|
165
177
|
score++;
|
|
166
178
|
if (password.length >= 16)
|
|
167
179
|
score++;
|
|
168
|
-
|
|
180
|
+
/* ---------------- Character variety ---------------- */
|
|
169
181
|
if (/[a-z]/.test(password))
|
|
170
182
|
score++;
|
|
171
183
|
if (/[A-Z]/.test(password))
|
|
@@ -174,10 +186,10 @@ class PasswordManager {
|
|
|
174
186
|
score++;
|
|
175
187
|
if (/[^A-Za-z0-9]/.test(password))
|
|
176
188
|
score++;
|
|
177
|
-
|
|
189
|
+
/* ---------------- Pattern deductions ---------------- */
|
|
178
190
|
if (/^[A-Za-z]+$/.test(password)) {
|
|
179
191
|
score--;
|
|
180
|
-
feedback.push('Consider adding numbers
|
|
192
|
+
feedback.push('Consider adding numbers or symbols');
|
|
181
193
|
}
|
|
182
194
|
if (/^[0-9]+$/.test(password)) {
|
|
183
195
|
score -= 2;
|
|
@@ -191,14 +203,15 @@ class PasswordManager {
|
|
|
191
203
|
score--;
|
|
192
204
|
feedback.push('Avoid sequential patterns');
|
|
193
205
|
}
|
|
194
|
-
|
|
206
|
+
/* ---------------- Common passwords ---------------- */
|
|
195
207
|
const commonPasswords = ['password', '123456', 'qwerty', 'admin', 'letmein'];
|
|
196
208
|
if (commonPasswords.some((common) => password.toLowerCase().includes(common))) {
|
|
197
209
|
score = 0;
|
|
198
210
|
feedback.push('Avoid common passwords');
|
|
199
211
|
}
|
|
200
|
-
|
|
212
|
+
/* ---------------- Clamp score ---------------- */
|
|
201
213
|
score = Math.max(0, Math.min(4, score));
|
|
214
|
+
/* ---------------- Strength label ---------------- */
|
|
202
215
|
let label;
|
|
203
216
|
switch (score) {
|
|
204
217
|
case 0:
|
|
@@ -211,7 +224,7 @@ class PasswordManager {
|
|
|
211
224
|
break;
|
|
212
225
|
case 2:
|
|
213
226
|
label = 'fair';
|
|
214
|
-
suggestions.push('Consider
|
|
227
|
+
suggestions.push('Consider increasing length or randomness');
|
|
215
228
|
break;
|
|
216
229
|
case 3:
|
|
217
230
|
label = 'good';
|
|
@@ -234,7 +247,7 @@ class PasswordManager {
|
|
|
234
247
|
/**
|
|
235
248
|
* Check if password hash needs upgrade (different salt rounds)
|
|
236
249
|
*/
|
|
237
|
-
needsUpgrade(
|
|
250
|
+
needsUpgrade(_hash, _currentConfig) {
|
|
238
251
|
// Simple heuristic: if the hash doesn't match current salt rounds pattern
|
|
239
252
|
// In practice, you'd need to store the salt rounds with the hash
|
|
240
253
|
return false;
|
|
@@ -36,7 +36,7 @@ const verifyPasswordSync = (password, hash) => {
|
|
|
36
36
|
throw new errors_utils_1.UnauthorizedError('Password verification failed');
|
|
37
37
|
return result;
|
|
38
38
|
}
|
|
39
|
-
catch (
|
|
39
|
+
catch (_error) {
|
|
40
40
|
throw new errors_utils_1.UnauthorizedError('Password verification failed');
|
|
41
41
|
}
|
|
42
42
|
};
|
|
@@ -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;
|
|
@@ -30,7 +30,7 @@ export class CryptoManager {
|
|
|
30
30
|
/**
|
|
31
31
|
* Encrypt data using the default or specified algorithm
|
|
32
32
|
*/
|
|
33
|
-
encrypt(plaintext, key,
|
|
33
|
+
encrypt(plaintext, key, _options) {
|
|
34
34
|
// For now, use the basic encrypt function
|
|
35
35
|
// TODO: Enhance to support different algorithms and options
|
|
36
36
|
return functionalEncrypt(plaintext, key);
|
|
@@ -38,7 +38,7 @@ export class CryptoManager {
|
|
|
38
38
|
/**
|
|
39
39
|
* Decrypt data using the default or specified algorithm
|
|
40
40
|
*/
|
|
41
|
-
decrypt(encryptedData, key,
|
|
41
|
+
decrypt(encryptedData, key, _options) {
|
|
42
42
|
// For now, use the basic decrypt function
|
|
43
43
|
// TODO: Enhance to support different algorithms and options
|
|
44
44
|
return functionalDecrypt(encryptedData, key);
|
|
@@ -46,7 +46,7 @@ export class CryptoManager {
|
|
|
46
46
|
/**
|
|
47
47
|
* Generate HMAC signature
|
|
48
48
|
*/
|
|
49
|
-
generateHmac(data, secret,
|
|
49
|
+
generateHmac(data, secret, _options) {
|
|
50
50
|
// Use the basic HMAC sign function for now
|
|
51
51
|
// TODO: Add support for different algorithms
|
|
52
52
|
return functionalHmacSign(data, secret);
|
|
@@ -54,14 +54,14 @@ export class CryptoManager {
|
|
|
54
54
|
/**
|
|
55
55
|
* Generate cryptographically secure random bytes
|
|
56
56
|
*/
|
|
57
|
-
generateSecureRandom(length,
|
|
57
|
+
generateSecureRandom(length, _encoding = 'hex') {
|
|
58
58
|
// Use the basic random token function
|
|
59
59
|
return functionalRandomToken(length);
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
62
|
* Verify HMAC signature
|
|
63
63
|
*/
|
|
64
|
-
verifyHmac(data, secret, signature,
|
|
64
|
+
verifyHmac(data, secret, signature, _options) {
|
|
65
65
|
// Use the basic HMAC verify function
|
|
66
66
|
return functionalHmacVerify(data, secret, signature);
|
|
67
67
|
}
|
|
@@ -99,7 +99,7 @@ export class CryptoManager {
|
|
|
99
99
|
* Generate a secure key pair for asymmetric encryption
|
|
100
100
|
*/
|
|
101
101
|
generateKeyPair(options) {
|
|
102
|
-
return new Promise((resolve,
|
|
102
|
+
return new Promise((resolve, _reject) => {
|
|
103
103
|
const crypto = require('crypto');
|
|
104
104
|
const keyPair = crypto.generateKeyPairSync('rsa', {
|
|
105
105
|
modulusLength: options?.modulusLength || 2048,
|
|
@@ -119,7 +119,7 @@ export class CryptoManager {
|
|
|
119
119
|
* Encrypt data using RSA public key
|
|
120
120
|
*/
|
|
121
121
|
rsaEncrypt(data, publicKey) {
|
|
122
|
-
return new Promise((resolve,
|
|
122
|
+
return new Promise((resolve, _reject) => {
|
|
123
123
|
const crypto = require('crypto');
|
|
124
124
|
const buffer = Buffer.from(data, 'utf8');
|
|
125
125
|
const encrypted = crypto.publicEncrypt(publicKey, buffer);
|
|
@@ -130,7 +130,7 @@ export class CryptoManager {
|
|
|
130
130
|
* Decrypt data using RSA private key
|
|
131
131
|
*/
|
|
132
132
|
rsaDecrypt(encryptedData, privateKey) {
|
|
133
|
-
return new Promise((resolve,
|
|
133
|
+
return new Promise((resolve, _reject) => {
|
|
134
134
|
const crypto = require('crypto');
|
|
135
135
|
const buffer = Buffer.from(encryptedData, 'base64');
|
|
136
136
|
const decrypted = crypto.privateDecrypt(privateKey, buffer);
|
|
@@ -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;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { signToken } from './signToken';
|
|
2
2
|
import { verifyToken } from './verify';
|
|
3
3
|
// Helper function to create branded tokens
|
|
4
|
-
const createBrandedToken = (token, _brand) => {
|
|
5
|
-
return token
|
|
6
|
-
}
|
|
4
|
+
/* const createBrandedToken = <T extends string>(token: string, _brand: T): T => {
|
|
5
|
+
return token as T
|
|
6
|
+
} */
|
|
7
7
|
export const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry = '15m', refreshExpiry = '7d') => {
|
|
8
8
|
const accessToken = signToken(payload, accessSecret, accessExpiry, {
|
|
9
9
|
algorithm: 'HS256',
|
|
@@ -39,7 +39,7 @@ export declare class JWTManager implements ITokenManager {
|
|
|
39
39
|
/**
|
|
40
40
|
* Validate token without throwing exceptions
|
|
41
41
|
*/
|
|
42
|
-
validateToken(token: string, secret: Secret,
|
|
42
|
+
validateToken(token: string, secret: Secret, _options?: TokenValidationOptions): boolean;
|
|
43
43
|
/**
|
|
44
44
|
* Rotate refresh token
|
|
45
45
|
*/
|
|
@@ -135,7 +135,11 @@ export class JWTManager {
|
|
|
135
135
|
}
|
|
136
136
|
const decoded = verifyToken(token, this.refreshSecret);
|
|
137
137
|
if (this.cache) {
|
|
138
|
-
this.cache.set(cacheKey, {
|
|
138
|
+
this.cache.set(cacheKey, {
|
|
139
|
+
valid: true,
|
|
140
|
+
payload: decoded,
|
|
141
|
+
timestamp: Date.now(),
|
|
142
|
+
});
|
|
139
143
|
}
|
|
140
144
|
return decoded;
|
|
141
145
|
}
|
|
@@ -191,7 +195,7 @@ export class JWTManager {
|
|
|
191
195
|
/**
|
|
192
196
|
* Validate token without throwing exceptions
|
|
193
197
|
*/
|
|
194
|
-
validateToken(token, secret,
|
|
198
|
+
validateToken(token, secret, _options = {}) {
|
|
195
199
|
try {
|
|
196
200
|
if (!token || typeof token !== 'string') {
|
|
197
201
|
return false;
|
|
@@ -10,7 +10,7 @@ export const hashPassword = async (password, saltRounds = 10) => {
|
|
|
10
10
|
const salt = await bcrypt.genSalt(saltRounds);
|
|
11
11
|
return bcrypt.hash(password, salt);
|
|
12
12
|
}
|
|
13
|
-
catch (
|
|
13
|
+
catch (_err) {
|
|
14
14
|
throw new InternalServerError('Password hashing failed');
|
|
15
15
|
}
|
|
16
16
|
};
|
|
@@ -26,7 +26,7 @@ export const hashPasswordSync = (password, saltRounds = 10) => {
|
|
|
26
26
|
const salt = bcrypt.genSaltSync(saltRounds);
|
|
27
27
|
return bcrypt.hashSync(password, salt);
|
|
28
28
|
}
|
|
29
|
-
catch (
|
|
29
|
+
catch (_error) {
|
|
30
30
|
throw new InternalServerError('Password hashing failed');
|
|
31
31
|
}
|
|
32
32
|
};
|
|
@@ -25,5 +25,5 @@ export declare class PasswordManager implements IPasswordManager {
|
|
|
25
25
|
/**
|
|
26
26
|
* Check if password hash needs upgrade (different salt rounds)
|
|
27
27
|
*/
|
|
28
|
-
needsUpgrade(
|
|
28
|
+
needsUpgrade(_hash: string, _currentConfig: PasswordConfig): boolean;
|
|
29
29
|
}
|
|
@@ -59,7 +59,7 @@ export class PasswordManager {
|
|
|
59
59
|
}
|
|
60
60
|
return isValid;
|
|
61
61
|
}
|
|
62
|
-
catch (
|
|
62
|
+
catch (_error) {
|
|
63
63
|
return false;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -152,14 +152,26 @@ export class PasswordManager {
|
|
|
152
152
|
let score = 0;
|
|
153
153
|
const feedback = [];
|
|
154
154
|
const suggestions = [];
|
|
155
|
-
|
|
156
|
-
if (
|
|
157
|
-
|
|
155
|
+
/* ---------------- Entropy baseline ---------------- */
|
|
156
|
+
if (entropy < 28) {
|
|
157
|
+
feedback.push('Password is easy to guess');
|
|
158
|
+
suggestions.push('Use more unique characters and length');
|
|
159
|
+
}
|
|
160
|
+
else if (entropy < 36) {
|
|
161
|
+
score += 1;
|
|
162
|
+
}
|
|
163
|
+
else if (entropy < 60) {
|
|
164
|
+
score += 2;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
score += 3;
|
|
168
|
+
}
|
|
169
|
+
/* ---------------- Length scoring ---------------- */
|
|
158
170
|
if (password.length >= 12)
|
|
159
171
|
score++;
|
|
160
172
|
if (password.length >= 16)
|
|
161
173
|
score++;
|
|
162
|
-
|
|
174
|
+
/* ---------------- Character variety ---------------- */
|
|
163
175
|
if (/[a-z]/.test(password))
|
|
164
176
|
score++;
|
|
165
177
|
if (/[A-Z]/.test(password))
|
|
@@ -168,10 +180,10 @@ export class PasswordManager {
|
|
|
168
180
|
score++;
|
|
169
181
|
if (/[^A-Za-z0-9]/.test(password))
|
|
170
182
|
score++;
|
|
171
|
-
|
|
183
|
+
/* ---------------- Pattern deductions ---------------- */
|
|
172
184
|
if (/^[A-Za-z]+$/.test(password)) {
|
|
173
185
|
score--;
|
|
174
|
-
feedback.push('Consider adding numbers
|
|
186
|
+
feedback.push('Consider adding numbers or symbols');
|
|
175
187
|
}
|
|
176
188
|
if (/^[0-9]+$/.test(password)) {
|
|
177
189
|
score -= 2;
|
|
@@ -185,14 +197,15 @@ export class PasswordManager {
|
|
|
185
197
|
score--;
|
|
186
198
|
feedback.push('Avoid sequential patterns');
|
|
187
199
|
}
|
|
188
|
-
|
|
200
|
+
/* ---------------- Common passwords ---------------- */
|
|
189
201
|
const commonPasswords = ['password', '123456', 'qwerty', 'admin', 'letmein'];
|
|
190
202
|
if (commonPasswords.some((common) => password.toLowerCase().includes(common))) {
|
|
191
203
|
score = 0;
|
|
192
204
|
feedback.push('Avoid common passwords');
|
|
193
205
|
}
|
|
194
|
-
|
|
206
|
+
/* ---------------- Clamp score ---------------- */
|
|
195
207
|
score = Math.max(0, Math.min(4, score));
|
|
208
|
+
/* ---------------- Strength label ---------------- */
|
|
196
209
|
let label;
|
|
197
210
|
switch (score) {
|
|
198
211
|
case 0:
|
|
@@ -205,7 +218,7 @@ export class PasswordManager {
|
|
|
205
218
|
break;
|
|
206
219
|
case 2:
|
|
207
220
|
label = 'fair';
|
|
208
|
-
suggestions.push('Consider
|
|
221
|
+
suggestions.push('Consider increasing length or randomness');
|
|
209
222
|
break;
|
|
210
223
|
case 3:
|
|
211
224
|
label = 'good';
|
|
@@ -228,7 +241,7 @@ export class PasswordManager {
|
|
|
228
241
|
/**
|
|
229
242
|
* Check if password hash needs upgrade (different salt rounds)
|
|
230
243
|
*/
|
|
231
|
-
needsUpgrade(
|
|
244
|
+
needsUpgrade(_hash, _currentConfig) {
|
|
232
245
|
// Simple heuristic: if the hash doesn't match current salt rounds pattern
|
|
233
246
|
// In practice, you'd need to store the salt rounds with the hash
|
|
234
247
|
return false;
|
|
@@ -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,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;
|
|
@@ -39,7 +39,7 @@ export declare class JWTManager implements ITokenManager {
|
|
|
39
39
|
/**
|
|
40
40
|
* Validate token without throwing exceptions
|
|
41
41
|
*/
|
|
42
|
-
validateToken(token: string, secret: Secret,
|
|
42
|
+
validateToken(token: string, secret: Secret, _options?: TokenValidationOptions): boolean;
|
|
43
43
|
/**
|
|
44
44
|
* Rotate refresh token
|
|
45
45
|
*/
|
|
@@ -25,5 +25,5 @@ export declare class PasswordManager implements IPasswordManager {
|
|
|
25
25
|
/**
|
|
26
26
|
* Check if password hash needs upgrade (different salt rounds)
|
|
27
27
|
*/
|
|
28
|
-
needsUpgrade(
|
|
28
|
+
needsUpgrade(_hash: string, _currentConfig: PasswordConfig): boolean;
|
|
29
29
|
}
|
package/package.json
CHANGED