@naman_deep_singh/security 1.2.0 → 1.3.1
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 +355 -176
- package/dist/cjs/core/crypto/cryptoManager.d.ts +111 -0
- package/dist/cjs/core/crypto/cryptoManager.js +191 -0
- package/dist/cjs/core/crypto/decrypt.js +6 -6
- package/dist/cjs/core/crypto/encrypt.js +4 -4
- package/dist/cjs/core/crypto/hmac.js +1 -1
- package/dist/cjs/core/crypto/index.d.ts +5 -4
- package/dist/cjs/core/crypto/index.js +12 -4
- package/dist/cjs/core/crypto/random.js +2 -2
- package/dist/cjs/core/jwt/decode.d.ts +1 -1
- package/dist/cjs/core/jwt/decode.js +2 -2
- package/dist/cjs/core/jwt/extractToken.js +7 -7
- package/dist/cjs/core/jwt/generateTokens.d.ts +2 -2
- package/dist/cjs/core/jwt/generateTokens.js +10 -6
- package/dist/cjs/core/jwt/index.d.ts +8 -8
- package/dist/cjs/core/jwt/jwtManager.d.ts +67 -0
- package/dist/cjs/core/jwt/jwtManager.js +299 -0
- package/dist/cjs/core/jwt/parseDuration.js +3 -3
- package/dist/cjs/core/jwt/signToken.d.ts +1 -1
- package/dist/cjs/core/jwt/signToken.js +7 -7
- package/dist/cjs/core/jwt/types.d.ts +1 -1
- package/dist/cjs/core/jwt/validateToken.d.ts +2 -2
- package/dist/cjs/core/jwt/validateToken.js +3 -3
- package/dist/cjs/core/jwt/verify.d.ts +3 -2
- package/dist/cjs/core/password/hash.js +1 -1
- package/dist/cjs/core/password/index.d.ts +3 -3
- package/dist/cjs/core/password/passwordManager.d.ts +29 -0
- package/dist/cjs/core/password/passwordManager.js +243 -0
- package/dist/cjs/core/password/strength.d.ts +1 -1
- package/dist/cjs/core/password/strength.js +4 -4
- package/dist/cjs/core/password/utils.js +2 -2
- package/dist/cjs/core/password/verify.js +1 -1
- package/dist/cjs/index.d.ts +9 -5
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/interfaces/jwt.interface.d.ts +47 -0
- package/dist/cjs/interfaces/jwt.interface.js +2 -0
- package/dist/cjs/interfaces/password.interface.d.ts +60 -0
- package/dist/cjs/interfaces/password.interface.js +2 -0
- package/dist/esm/core/crypto/cryptoManager.d.ts +111 -0
- package/dist/esm/core/crypto/cryptoManager.js +186 -0
- package/dist/esm/core/crypto/decrypt.js +7 -7
- package/dist/esm/core/crypto/encrypt.js +5 -5
- package/dist/esm/core/crypto/hmac.js +2 -2
- package/dist/esm/core/crypto/index.d.ts +5 -4
- package/dist/esm/core/crypto/index.js +5 -4
- package/dist/esm/core/crypto/random.js +3 -3
- package/dist/esm/core/jwt/decode.d.ts +1 -1
- package/dist/esm/core/jwt/decode.js +3 -3
- package/dist/esm/core/jwt/extractToken.js +7 -7
- package/dist/esm/core/jwt/generateTokens.d.ts +2 -2
- package/dist/esm/core/jwt/generateTokens.js +12 -8
- package/dist/esm/core/jwt/index.d.ts +8 -8
- package/dist/esm/core/jwt/index.js +8 -8
- package/dist/esm/core/jwt/jwtManager.d.ts +67 -0
- package/dist/esm/core/jwt/jwtManager.js +292 -0
- package/dist/esm/core/jwt/parseDuration.js +3 -3
- package/dist/esm/core/jwt/signToken.d.ts +1 -1
- package/dist/esm/core/jwt/signToken.js +9 -9
- package/dist/esm/core/jwt/types.d.ts +1 -1
- package/dist/esm/core/jwt/validateToken.d.ts +2 -2
- package/dist/esm/core/jwt/validateToken.js +3 -3
- package/dist/esm/core/jwt/verify.d.ts +3 -2
- package/dist/esm/core/jwt/verify.js +1 -1
- package/dist/esm/core/password/hash.js +3 -3
- package/dist/esm/core/password/index.d.ts +3 -3
- package/dist/esm/core/password/index.js +3 -3
- package/dist/esm/core/password/passwordManager.d.ts +29 -0
- package/dist/esm/core/password/passwordManager.js +236 -0
- package/dist/esm/core/password/strength.d.ts +1 -1
- package/dist/esm/core/password/strength.js +5 -5
- package/dist/esm/core/password/utils.js +4 -4
- package/dist/esm/core/password/verify.js +2 -2
- package/dist/esm/index.d.ts +9 -5
- package/dist/esm/index.js +7 -7
- package/dist/esm/interfaces/jwt.interface.d.ts +47 -0
- package/dist/esm/interfaces/jwt.interface.js +1 -0
- package/dist/esm/interfaces/password.interface.d.ts +60 -0
- package/dist/esm/interfaces/password.interface.js +1 -0
- package/dist/types/core/crypto/cryptoManager.d.ts +111 -0
- package/dist/types/core/crypto/index.d.ts +5 -4
- package/dist/types/core/jwt/decode.d.ts +1 -1
- package/dist/types/core/jwt/generateTokens.d.ts +2 -2
- package/dist/types/core/jwt/index.d.ts +8 -8
- package/dist/types/core/jwt/jwtManager.d.ts +67 -0
- package/dist/types/core/jwt/signToken.d.ts +1 -1
- package/dist/types/core/jwt/types.d.ts +1 -1
- package/dist/types/core/jwt/validateToken.d.ts +2 -2
- package/dist/types/core/jwt/verify.d.ts +3 -2
- package/dist/types/core/password/index.d.ts +3 -3
- package/dist/types/core/password/passwordManager.d.ts +29 -0
- package/dist/types/core/password/strength.d.ts +1 -1
- package/dist/types/index.d.ts +9 -5
- package/dist/types/interfaces/jwt.interface.d.ts +47 -0
- package/dist/types/interfaces/password.interface.d.ts +60 -0
- package/package.json +4 -3
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { decrypt as functionalDecrypt, encrypt as functionalEncrypt, hmacSign as functionalHmacSign, hmacVerify as functionalHmacVerify, randomToken as functionalRandomToken, } from './index';
|
|
2
|
+
/**
|
|
3
|
+
* Default configuration
|
|
4
|
+
*/
|
|
5
|
+
const DEFAULT_CONFIG = {
|
|
6
|
+
defaultAlgorithm: 'aes-256-gcm',
|
|
7
|
+
defaultEncoding: 'utf8',
|
|
8
|
+
hmacAlgorithm: 'sha256',
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* CryptoManager - Class-based wrapper for all cryptographic operations
|
|
12
|
+
* Provides a consistent interface for encryption, decryption, HMAC generation, and secure random generation
|
|
13
|
+
*/
|
|
14
|
+
export class CryptoManager {
|
|
15
|
+
constructor(config = {}) {
|
|
16
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Update configuration
|
|
20
|
+
*/
|
|
21
|
+
updateConfig(config) {
|
|
22
|
+
this.config = { ...this.config, ...config };
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get current configuration
|
|
26
|
+
*/
|
|
27
|
+
getConfig() {
|
|
28
|
+
return { ...this.config };
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Encrypt data using the default or specified algorithm
|
|
32
|
+
*/
|
|
33
|
+
encrypt(plaintext, key, options) {
|
|
34
|
+
// For now, use the basic encrypt function
|
|
35
|
+
// TODO: Enhance to support different algorithms and options
|
|
36
|
+
return functionalEncrypt(plaintext, key);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Decrypt data using the default or specified algorithm
|
|
40
|
+
*/
|
|
41
|
+
decrypt(encryptedData, key, options) {
|
|
42
|
+
// For now, use the basic decrypt function
|
|
43
|
+
// TODO: Enhance to support different algorithms and options
|
|
44
|
+
return functionalDecrypt(encryptedData, key);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Generate HMAC signature
|
|
48
|
+
*/
|
|
49
|
+
generateHmac(data, secret, options) {
|
|
50
|
+
// Use the basic HMAC sign function for now
|
|
51
|
+
// TODO: Add support for different algorithms
|
|
52
|
+
return functionalHmacSign(data, secret);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate cryptographically secure random bytes
|
|
56
|
+
*/
|
|
57
|
+
generateSecureRandom(length, encoding = 'hex') {
|
|
58
|
+
// Use the basic random token function
|
|
59
|
+
return functionalRandomToken(length);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Verify HMAC signature
|
|
63
|
+
*/
|
|
64
|
+
verifyHmac(data, secret, signature, options) {
|
|
65
|
+
// Use the basic HMAC verify function
|
|
66
|
+
return functionalHmacVerify(data, secret, signature);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create a key derivation function using PBKDF2
|
|
70
|
+
*/
|
|
71
|
+
deriveKey(password, salt, iterations = 100000, keyLength = 32) {
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
const crypto = require('crypto');
|
|
74
|
+
crypto.pbkdf2(password, salt, iterations, keyLength, 'sha256', (err, derivedKey) => {
|
|
75
|
+
if (err) {
|
|
76
|
+
reject(err);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
resolve(derivedKey.toString('hex'));
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Hash data using SHA-256
|
|
86
|
+
*/
|
|
87
|
+
sha256(data, encoding = 'hex') {
|
|
88
|
+
const crypto = require('crypto');
|
|
89
|
+
return crypto.createHash('sha256').update(data).digest(encoding);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Hash data using SHA-512
|
|
93
|
+
*/
|
|
94
|
+
sha512(data, encoding = 'hex') {
|
|
95
|
+
const crypto = require('crypto');
|
|
96
|
+
return crypto.createHash('sha512').update(data).digest(encoding);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Generate a secure key pair for asymmetric encryption
|
|
100
|
+
*/
|
|
101
|
+
generateKeyPair(options) {
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
const crypto = require('crypto');
|
|
104
|
+
const keyPair = crypto.generateKeyPairSync('rsa', {
|
|
105
|
+
modulusLength: options?.modulusLength || 2048,
|
|
106
|
+
publicKeyEncoding: options?.publicKeyEncoding || {
|
|
107
|
+
type: 'spki',
|
|
108
|
+
format: 'pem',
|
|
109
|
+
},
|
|
110
|
+
privateKeyEncoding: options?.privateKeyEncoding || {
|
|
111
|
+
type: 'pkcs8',
|
|
112
|
+
format: 'pem',
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
resolve(keyPair);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Encrypt data using RSA public key
|
|
120
|
+
*/
|
|
121
|
+
rsaEncrypt(data, publicKey) {
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const crypto = require('crypto');
|
|
124
|
+
const buffer = Buffer.from(data, 'utf8');
|
|
125
|
+
const encrypted = crypto.publicEncrypt(publicKey, buffer);
|
|
126
|
+
resolve(encrypted.toString('base64'));
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Decrypt data using RSA private key
|
|
131
|
+
*/
|
|
132
|
+
rsaDecrypt(encryptedData, privateKey) {
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
const crypto = require('crypto');
|
|
135
|
+
const buffer = Buffer.from(encryptedData, 'base64');
|
|
136
|
+
const decrypted = crypto.privateDecrypt(privateKey, buffer);
|
|
137
|
+
resolve(decrypted.toString('utf8'));
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Create digital signature using RSA private key
|
|
142
|
+
*/
|
|
143
|
+
rsaSign(data, privateKey, algorithm = 'sha256') {
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
const crypto = require('crypto');
|
|
146
|
+
const sign = crypto.createSign(algorithm);
|
|
147
|
+
sign.update(data);
|
|
148
|
+
sign.end();
|
|
149
|
+
try {
|
|
150
|
+
const signature = sign.sign(privateKey, 'base64');
|
|
151
|
+
resolve(signature);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
reject(error);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Verify digital signature using RSA public key
|
|
160
|
+
*/
|
|
161
|
+
rsaVerify(data, signature, publicKey, algorithm = 'sha256') {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
const crypto = require('crypto');
|
|
164
|
+
const verify = crypto.createVerify(algorithm);
|
|
165
|
+
verify.update(data);
|
|
166
|
+
verify.end();
|
|
167
|
+
try {
|
|
168
|
+
const isValid = verify.verify(publicKey, signature, 'base64');
|
|
169
|
+
resolve(isValid);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
reject(error);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Create a CryptoManager instance with default configuration
|
|
179
|
+
*/
|
|
180
|
+
export const createCryptoManager = (config) => {
|
|
181
|
+
return new CryptoManager(config);
|
|
182
|
+
};
|
|
183
|
+
/**
|
|
184
|
+
* Default CryptoManager instance
|
|
185
|
+
*/
|
|
186
|
+
export const cryptoManager = new CryptoManager();
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import crypto from
|
|
2
|
-
const ALGO =
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
const ALGO = 'AES-256-GCM';
|
|
3
3
|
export const decrypt = (data, secret) => {
|
|
4
|
-
const [ivHex, encryptedHex] = data.split(
|
|
5
|
-
const iv = Buffer.from(ivHex,
|
|
6
|
-
const encrypted = Buffer.from(encryptedHex,
|
|
7
|
-
const key = crypto.createHash(
|
|
4
|
+
const [ivHex, encryptedHex] = data.split(':');
|
|
5
|
+
const iv = Buffer.from(ivHex, 'hex');
|
|
6
|
+
const encrypted = Buffer.from(encryptedHex, 'hex');
|
|
7
|
+
const key = crypto.createHash('sha256').update(secret).digest();
|
|
8
8
|
const decipher = crypto.createDecipheriv(ALGO, key, iv);
|
|
9
9
|
const decrypted = Buffer.concat([
|
|
10
10
|
decipher.update(encrypted),
|
|
11
11
|
decipher.final(),
|
|
12
12
|
]);
|
|
13
|
-
return decrypted.toString(
|
|
13
|
+
return decrypted.toString('utf8');
|
|
14
14
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import crypto from
|
|
2
|
-
const ALGO =
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
const ALGO = 'AES-256-GCM';
|
|
3
3
|
export const encrypt = (text, secret) => {
|
|
4
|
-
const key = crypto.createHash(
|
|
4
|
+
const key = crypto.createHash('sha256').update(secret).digest();
|
|
5
5
|
const iv = crypto.randomBytes(16);
|
|
6
6
|
const cipher = crypto.createCipheriv(ALGO, key, iv);
|
|
7
|
-
const encrypted = Buffer.concat([cipher.update(text,
|
|
8
|
-
return `${iv.toString(
|
|
7
|
+
const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
|
|
8
|
+
return `${iv.toString('hex')}:${encrypted.toString('hex')}`;
|
|
9
9
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import crypto from
|
|
1
|
+
import crypto from 'crypto';
|
|
2
2
|
/**
|
|
3
3
|
* Sign message using HMAC SHA-256
|
|
4
4
|
*/
|
|
5
5
|
export const hmacSign = (message, secret) => {
|
|
6
|
-
return crypto.createHmac(
|
|
6
|
+
return crypto.createHmac('sha256', secret).update(message).digest('hex');
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Verify HMAC signature
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
export { decrypt } from './decrypt';
|
|
2
|
+
export { encrypt } from './encrypt';
|
|
3
|
+
export { hmacSign, hmacVerify } from './hmac';
|
|
4
|
+
export { randomToken, generateStrongPassword } from './random';
|
|
5
|
+
export * from './cryptoManager';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
export { decrypt } from './decrypt';
|
|
2
|
+
export { encrypt } from './encrypt';
|
|
3
|
+
export { hmacSign, hmacVerify } from './hmac';
|
|
4
|
+
export { randomToken, generateStrongPassword } from './random';
|
|
5
|
+
export * from './cryptoManager';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import crypto from
|
|
1
|
+
import crypto from 'crypto';
|
|
2
2
|
/**
|
|
3
3
|
* Generate cryptographically secure random string
|
|
4
4
|
*/
|
|
5
5
|
export const randomToken = (length = 32) => {
|
|
6
|
-
return crypto.randomBytes(length).toString(
|
|
6
|
+
return crypto.randomBytes(length).toString('hex');
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Generate a strong random password
|
|
10
10
|
*/
|
|
11
11
|
export const generateStrongPassword = (length = 16) => {
|
|
12
|
-
return crypto.randomBytes(length).toString(
|
|
12
|
+
return crypto.randomBytes(length).toString('hex').slice(0, length);
|
|
13
13
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/jwt/decodeToken.ts
|
|
2
|
-
import { decode } from
|
|
2
|
+
import { decode } from 'jsonwebtoken';
|
|
3
3
|
/**
|
|
4
4
|
* Flexible decode
|
|
5
5
|
* Returns: null | string | JwtPayload
|
|
@@ -14,8 +14,8 @@ export function decodeToken(token) {
|
|
|
14
14
|
*/
|
|
15
15
|
export function decodeTokenStrict(token) {
|
|
16
16
|
const decoded = decode(token);
|
|
17
|
-
if (!decoded || typeof decoded ===
|
|
18
|
-
throw new Error(
|
|
17
|
+
if (!decoded || typeof decoded === 'string') {
|
|
18
|
+
throw new Error('Invalid JWT payload structure');
|
|
19
19
|
}
|
|
20
20
|
return decoded;
|
|
21
21
|
}
|
|
@@ -5,16 +5,16 @@ export function extractToken(sources) {
|
|
|
5
5
|
const { header, cookies, query, body, wsMessage } = sources;
|
|
6
6
|
// 1. Authorization: Bearer <token>
|
|
7
7
|
if (header) {
|
|
8
|
-
const parts = header.split(
|
|
9
|
-
if (parts.length === 2 && parts[0] ===
|
|
8
|
+
const parts = header.split(' ');
|
|
9
|
+
if (parts.length === 2 && parts[0] === 'Bearer')
|
|
10
10
|
return parts[1];
|
|
11
11
|
}
|
|
12
12
|
// 2. Cookies: token / accessToken
|
|
13
13
|
if (cookies) {
|
|
14
|
-
if (cookies[
|
|
15
|
-
return cookies[
|
|
16
|
-
if (cookies[
|
|
17
|
-
return cookies[
|
|
14
|
+
if (cookies['token'])
|
|
15
|
+
return cookies['token'];
|
|
16
|
+
if (cookies['accessToken'])
|
|
17
|
+
return cookies['accessToken'];
|
|
18
18
|
}
|
|
19
19
|
// 3. Query params: ?token=xxx
|
|
20
20
|
if (query?.token)
|
|
@@ -27,7 +27,7 @@ export function extractToken(sources) {
|
|
|
27
27
|
try {
|
|
28
28
|
let msg = wsMessage;
|
|
29
29
|
// If it's a JSON string → parse safely
|
|
30
|
-
if (typeof wsMessage ===
|
|
30
|
+
if (typeof wsMessage === 'string') {
|
|
31
31
|
msg = JSON.parse(wsMessage);
|
|
32
32
|
}
|
|
33
33
|
// Ensure msg is an object before property access
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Secret } from
|
|
2
|
-
import { RefreshToken, TokenPair } from
|
|
1
|
+
import { type Secret } from 'jsonwebtoken';
|
|
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,12 +1,16 @@
|
|
|
1
|
-
import { signToken } from
|
|
2
|
-
import { verifyToken } from
|
|
1
|
+
import { signToken } from './signToken';
|
|
2
|
+
import { verifyToken } from './verify';
|
|
3
3
|
// Helper function to create branded tokens
|
|
4
4
|
const createBrandedToken = (token, _brand) => {
|
|
5
5
|
return token;
|
|
6
6
|
};
|
|
7
|
-
export const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry =
|
|
8
|
-
const accessToken = signToken(payload, accessSecret, accessExpiry, {
|
|
9
|
-
|
|
7
|
+
export const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry = '15m', refreshExpiry = '7d') => {
|
|
8
|
+
const accessToken = signToken(payload, accessSecret, accessExpiry, {
|
|
9
|
+
algorithm: 'HS256',
|
|
10
|
+
});
|
|
11
|
+
const refreshToken = signToken(payload, refreshSecret, refreshExpiry, {
|
|
12
|
+
algorithm: 'HS256',
|
|
13
|
+
});
|
|
10
14
|
return {
|
|
11
15
|
accessToken: accessToken,
|
|
12
16
|
refreshToken: refreshToken,
|
|
@@ -14,12 +18,12 @@ export const generateTokens = (payload, accessSecret, refreshSecret, accessExpir
|
|
|
14
18
|
};
|
|
15
19
|
export function rotateRefreshToken(oldToken, secret) {
|
|
16
20
|
const decoded = verifyToken(oldToken, secret);
|
|
17
|
-
if (typeof decoded ===
|
|
18
|
-
throw new Error(
|
|
21
|
+
if (typeof decoded === 'string') {
|
|
22
|
+
throw new Error('Invalid token payload — expected JWT payload object');
|
|
19
23
|
}
|
|
20
24
|
const payload = { ...decoded };
|
|
21
25
|
delete payload.iat;
|
|
22
26
|
delete payload.exp;
|
|
23
|
-
const newToken = signToken(payload, secret,
|
|
27
|
+
const newToken = signToken(payload, secret, '7d');
|
|
24
28
|
return newToken;
|
|
25
29
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
1
|
+
export * from './decode';
|
|
2
|
+
export * from './extractToken';
|
|
3
|
+
export * from './generateTokens';
|
|
4
|
+
export * from './parseDuration';
|
|
5
|
+
export * from './signToken';
|
|
6
|
+
export * from './types';
|
|
7
|
+
export * from './validateToken';
|
|
8
|
+
export * from './verify';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
1
|
+
export * from './decode';
|
|
2
|
+
export * from './extractToken';
|
|
3
|
+
export * from './generateTokens';
|
|
4
|
+
export * from './parseDuration';
|
|
5
|
+
export * from './signToken';
|
|
6
|
+
export * from './types';
|
|
7
|
+
export * from './validateToken';
|
|
8
|
+
export * from './verify';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type JwtPayload, type Secret } from 'jsonwebtoken';
|
|
2
|
+
import type { AccessToken, ITokenManager, JWTConfig, RefreshToken, TokenPair, TokenValidationOptions } from '../../interfaces/jwt.interface';
|
|
3
|
+
export declare class JWTManager implements ITokenManager {
|
|
4
|
+
private accessSecret;
|
|
5
|
+
private refreshSecret;
|
|
6
|
+
private accessExpiry;
|
|
7
|
+
private refreshExpiry;
|
|
8
|
+
private cache?;
|
|
9
|
+
private cacheTTL;
|
|
10
|
+
constructor(config: JWTConfig);
|
|
11
|
+
/**
|
|
12
|
+
* Generate both access and refresh tokens
|
|
13
|
+
*/
|
|
14
|
+
generateTokens(payload: Record<string, unknown>): Promise<TokenPair>;
|
|
15
|
+
/**
|
|
16
|
+
* Generate access token
|
|
17
|
+
*/
|
|
18
|
+
generateAccessToken(payload: Record<string, unknown>): Promise<AccessToken>;
|
|
19
|
+
/**
|
|
20
|
+
* Generate refresh token
|
|
21
|
+
*/
|
|
22
|
+
generateRefreshToken(payload: Record<string, unknown>): Promise<RefreshToken>;
|
|
23
|
+
/**
|
|
24
|
+
* Verify access token
|
|
25
|
+
*/
|
|
26
|
+
verifyAccessToken(token: string): Promise<JwtPayload | string>;
|
|
27
|
+
/**
|
|
28
|
+
* Verify refresh token
|
|
29
|
+
*/
|
|
30
|
+
verifyRefreshToken(token: string): Promise<JwtPayload | string>;
|
|
31
|
+
/**
|
|
32
|
+
* Decode token without verification
|
|
33
|
+
*/
|
|
34
|
+
decodeToken(token: string, complete?: boolean): JwtPayload | string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Extract token from Authorization header
|
|
37
|
+
*/
|
|
38
|
+
extractTokenFromHeader(authHeader: string): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Validate token without throwing exceptions
|
|
41
|
+
*/
|
|
42
|
+
validateToken(token: string, secret: Secret, options?: TokenValidationOptions): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Rotate refresh token
|
|
45
|
+
*/
|
|
46
|
+
rotateRefreshToken(oldToken: string): Promise<RefreshToken>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if token is expired
|
|
49
|
+
*/
|
|
50
|
+
isTokenExpired(token: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Get token expiration date
|
|
53
|
+
*/
|
|
54
|
+
getTokenExpiration(token: string): Date | null;
|
|
55
|
+
/**
|
|
56
|
+
* Clear token cache
|
|
57
|
+
*/
|
|
58
|
+
clearCache(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get cache statistics
|
|
61
|
+
*/
|
|
62
|
+
getCacheStats(): {
|
|
63
|
+
size: number;
|
|
64
|
+
maxSize: number;
|
|
65
|
+
} | null;
|
|
66
|
+
private validatePayload;
|
|
67
|
+
}
|