@naman_deep_singh/security 1.0.4 → 1.1.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.
Files changed (106) hide show
  1. package/README.md +311 -80
  2. package/dist/cjs/core/crypto/decrypt.d.ts +1 -0
  3. package/dist/cjs/core/crypto/decrypt.js +21 -0
  4. package/dist/cjs/core/crypto/encrypt.d.ts +1 -0
  5. package/dist/cjs/core/crypto/encrypt.js +16 -0
  6. package/dist/cjs/core/crypto/hmac.d.ts +8 -0
  7. package/dist/cjs/core/crypto/hmac.js +24 -0
  8. package/dist/cjs/core/crypto/index.d.ts +4 -0
  9. package/dist/cjs/core/crypto/index.js +20 -0
  10. package/dist/cjs/core/crypto/random.d.ts +8 -0
  11. package/dist/cjs/core/crypto/random.js +21 -0
  12. package/dist/cjs/core/jwt/decode.d.ts +12 -0
  13. package/dist/cjs/core/jwt/decode.js +25 -0
  14. package/dist/cjs/core/jwt/extractToken.d.ts +11 -0
  15. package/dist/cjs/core/jwt/extractToken.js +49 -0
  16. package/dist/cjs/core/jwt/generateTokens.d.ts +7 -0
  17. package/dist/cjs/core/jwt/generateTokens.js +23 -0
  18. package/dist/cjs/core/jwt/index.d.ts +7 -0
  19. package/dist/cjs/core/jwt/index.js +23 -0
  20. package/dist/cjs/core/jwt/parseDuration.d.ts +1 -0
  21. package/dist/cjs/core/jwt/parseDuration.js +29 -0
  22. package/dist/cjs/core/jwt/signToken.d.ts +2 -0
  23. package/dist/cjs/core/jwt/signToken.js +26 -0
  24. package/dist/cjs/core/jwt/validateToken.d.ts +13 -0
  25. package/dist/cjs/core/jwt/validateToken.js +37 -0
  26. package/dist/cjs/core/jwt/verify.d.ts +13 -0
  27. package/dist/cjs/core/jwt/verify.js +24 -0
  28. package/dist/cjs/core/password/hash.d.ts +10 -0
  29. package/dist/cjs/core/password/hash.js +45 -0
  30. package/dist/cjs/core/password/index.d.ts +3 -0
  31. package/dist/cjs/core/password/index.js +19 -0
  32. package/dist/cjs/core/password/strength.d.ts +2 -0
  33. package/dist/cjs/core/password/strength.js +21 -0
  34. package/dist/cjs/core/password/types.d.ts +7 -0
  35. package/dist/cjs/core/password/types.js +2 -0
  36. package/dist/cjs/core/password/utils.d.ts +4 -0
  37. package/dist/cjs/core/password/utils.js +38 -0
  38. package/dist/cjs/core/password/verify.d.ts +10 -0
  39. package/dist/cjs/core/password/verify.js +46 -0
  40. package/dist/cjs/index.d.ts +43 -0
  41. package/dist/cjs/index.js +56 -0
  42. package/dist/esm/core/crypto/decrypt.d.ts +1 -0
  43. package/dist/esm/core/crypto/decrypt.js +14 -0
  44. package/dist/esm/core/crypto/encrypt.d.ts +1 -0
  45. package/dist/esm/core/crypto/encrypt.js +9 -0
  46. package/dist/esm/core/crypto/hmac.d.ts +8 -0
  47. package/dist/esm/core/crypto/hmac.js +16 -0
  48. package/dist/esm/core/crypto/index.d.ts +4 -0
  49. package/dist/esm/core/crypto/index.js +4 -0
  50. package/dist/esm/core/crypto/random.d.ts +8 -0
  51. package/dist/esm/core/crypto/random.js +13 -0
  52. package/dist/esm/core/jwt/decode.d.ts +12 -0
  53. package/dist/esm/core/jwt/decode.js +21 -0
  54. package/dist/esm/core/jwt/extractToken.d.ts +11 -0
  55. package/dist/esm/core/jwt/extractToken.js +46 -0
  56. package/dist/esm/core/jwt/generateTokens.d.ts +7 -0
  57. package/dist/esm/core/jwt/generateTokens.js +18 -0
  58. package/dist/esm/core/jwt/index.d.ts +7 -0
  59. package/dist/esm/core/jwt/index.js +7 -0
  60. package/dist/esm/core/jwt/parseDuration.d.ts +1 -0
  61. package/dist/esm/core/jwt/parseDuration.js +26 -0
  62. package/dist/esm/core/jwt/signToken.d.ts +2 -0
  63. package/dist/esm/core/jwt/signToken.js +22 -0
  64. package/dist/esm/core/jwt/validateToken.d.ts +13 -0
  65. package/dist/esm/core/jwt/validateToken.js +33 -0
  66. package/dist/esm/core/jwt/verify.d.ts +13 -0
  67. package/dist/esm/core/jwt/verify.js +19 -0
  68. package/dist/esm/core/password/hash.d.ts +10 -0
  69. package/dist/esm/core/password/hash.js +35 -0
  70. package/dist/esm/core/password/index.d.ts +3 -0
  71. package/dist/esm/core/password/index.js +3 -0
  72. package/dist/esm/core/password/strength.d.ts +2 -0
  73. package/dist/esm/core/password/strength.js +17 -0
  74. package/dist/esm/core/password/types.d.ts +7 -0
  75. package/dist/esm/core/password/types.js +1 -0
  76. package/dist/esm/core/password/utils.d.ts +4 -0
  77. package/dist/esm/core/password/utils.js +29 -0
  78. package/dist/esm/core/password/verify.d.ts +10 -0
  79. package/dist/esm/core/password/verify.js +36 -0
  80. package/dist/esm/index.d.ts +43 -0
  81. package/dist/esm/index.js +13 -0
  82. package/dist/types/core/crypto/decrypt.d.ts +1 -0
  83. package/dist/types/core/crypto/encrypt.d.ts +1 -0
  84. package/dist/types/core/crypto/hmac.d.ts +8 -0
  85. package/dist/types/core/crypto/index.d.ts +4 -0
  86. package/dist/types/core/crypto/random.d.ts +8 -0
  87. package/dist/types/core/jwt/decode.d.ts +12 -0
  88. package/dist/types/core/jwt/extractToken.d.ts +11 -0
  89. package/dist/types/core/jwt/generateTokens.d.ts +7 -0
  90. package/dist/types/core/jwt/index.d.ts +7 -0
  91. package/dist/types/core/jwt/parseDuration.d.ts +1 -0
  92. package/dist/types/core/jwt/signToken.d.ts +2 -0
  93. package/dist/types/core/jwt/validateToken.d.ts +13 -0
  94. package/dist/types/core/jwt/verify.d.ts +13 -0
  95. package/dist/types/core/password/hash.d.ts +10 -0
  96. package/dist/types/core/password/index.d.ts +3 -0
  97. package/dist/types/core/password/strength.d.ts +2 -0
  98. package/dist/types/core/password/types.d.ts +7 -0
  99. package/dist/types/core/password/utils.d.ts +4 -0
  100. package/dist/types/core/password/verify.d.ts +10 -0
  101. package/dist/types/index.d.ts +43 -0
  102. package/package.json +23 -7
  103. package/dist/index.d.ts +0 -16
  104. package/dist/index.js +0 -41
  105. package/src/index.ts +0 -39
  106. package/tsconfig.json +0 -21
package/README.md CHANGED
@@ -1,116 +1,347 @@
1
1
  # @naman_deep_singh/security
2
2
 
3
- Security utilities for password hashing and JWT token management with TypeScript support.
3
+ **Version:** 1.1.0
4
4
 
5
- ## Installation
5
+ A complete, lightweight security toolkit for Node.js & TypeScript providing:
6
+
7
+ 🔐 **Password hashing & validation** with bcrypt
8
+ 🔑 **JWT signing & verification** (no deprecated expiresIn)
9
+ 🧮 **Duration parser** ("15m", "7d", etc.)
10
+ 🪪 **Token generator** (access + refresh pair)
11
+ ♻️ **Refresh token rotation** helper
12
+ 🧰 **Robust token extraction** (Headers, Cookies, Query, Body, WebSocket)
13
+ 🧩 **Safe & strict JWT decode** utilities
14
+ 🚨 **Standardized error handling** with @naman_deep_singh/errors-utils
15
+ ✔ **Fully typed** with TypeScript
16
+ ✔ **Consistent errors** across your application ecosystem
17
+ ✔ **Works in both ESM and CommonJS**
6
18
 
7
19
  ```bash
20
+
21
+ 📦 Installation
8
22
  npm install @naman_deep_singh/security
9
- ```
10
23
 
11
- ## Features
24
+ 🔧 Features
12
25
 
13
- - ✅ **Password hashing** with bcrypt (salt rounds: 10)
14
- - ✅ **JWT token management** with configurable expiration
15
- - ✅ **TypeScript support** with full type safety
16
- - ✅ **Hybrid exports** - use named imports or namespace imports
17
- - ✅ **Backward compatibility** with legacy function names
18
- - ✅ **Async/await support** for all operations
26
+ 🔥 Password Hashing secure & async (bcrypt with 10 salt rounds)
19
27
 
20
- ## Usage
28
+ 🔥 Custom Expiry JWT — manual exp support using duration strings
21
29
 
22
- ### Named Imports (Tree-shakable)
23
- ```typescript
24
- import { hashPassword, verifyPassword, generateToken, verifyToken } from '@naman_deep_singh/security';
30
+ 🔥 Token Pair Generation (accessToken + refreshToken)
25
31
 
26
- // Password hashing
27
- const hashedPassword = await hashPassword('mypassword');
28
- const isValid = await verifyPassword('mypassword', hashedPassword);
32
+ 🔥 Refresh Token Rotation
29
33
 
30
- // JWT tokens
31
- const token = generateToken({ userId: 1, role: 'admin' }, 'your-secret-key', '24h');
32
- const decoded = verifyToken(token, 'your-secret-key');
33
- ```
34
+ 🔥 Safe & Unsafe JWT Verification
34
35
 
35
- ### Namespace Import
36
- ```typescript
37
- import SecurityUtils from '@naman_deep_singh/security';
36
+ 🔥 Strict vs Flexible Decoding
38
37
 
39
- const hashedPassword = await SecurityUtils.hashPassword('mypassword');
40
- const token = SecurityUtils.generateToken({ userId: 1 }, 'secret');
41
- ```
38
+ 🔥 Universal Token Extraction (Headers, Cookies, Query, Body, WebSocket)
42
39
 
43
- ### Backward Compatibility
44
- ```typescript
45
- import { comparePassword, signToken } from '@naman_deep_singh/security';
40
+ 🔥 Duration Parser ("15m", "1h", "7d")
46
41
 
47
- // Legacy function names still work
48
- const isValid = await comparePassword('password', 'hash');
49
- const token = signToken({ userId: 1 }, 'secret');
50
- ```
42
+ 🔥 Production-grade types
51
43
 
52
- ## API Reference
44
+ 📘 Quick Start
45
+ import {
46
+ hashPassword,
47
+ verifyPassword,
48
+ generateTokens,
49
+ verifyToken,
50
+ safeVerifyToken,
51
+ extractToken
52
+ } from "@naman_deep_singh/security";
53
53
 
54
- ### Password Functions
55
- - `hashPassword(password: string): Promise<string>` - Hash a password using bcrypt with salt rounds 10
56
- - `verifyPassword(password: string, hash: string): Promise<boolean>` - Verify password against hash
57
- - `comparePassword(password: string, hash: string): Promise<boolean>` - Alias for verifyPassword (backward compatibility)
54
+ 📚 API Documentation
58
55
 
59
- ### JWT Functions
60
- - `generateToken(payload: Record<string, unknown>, secret: Secret, expiresIn?: string): string` - Generate JWT token
61
- - `verifyToken(token: string, secret: Secret): string | JwtPayload` - Verify and decode JWT token
62
- - `signToken(payload: Record<string, unknown>, secret: Secret, expiresIn?: string): string` - Alias for generateToken (backward compatibility)
56
+ Below is a complete reference with full usage examples.
63
57
 
64
- ## Examples
58
+ 🧂 1. Password Utilities
59
+ hashPassword(password: string): Promise<string>
60
+ const hashed = await hashPassword("mypassword");
61
+ console.log(hashed); // $2a$10$...
65
62
 
66
- ### Complete Authentication Flow
67
- ```typescript
68
- import { hashPassword, verifyPassword, generateToken, verifyToken } from '@naman_deep_singh/security';
63
+ verifyPassword(password: string, hash: string): Promise<boolean>
64
+ const isValid = await verifyPassword("mypassword", hashed);
65
+ if (isValid) console.log("Correct password");
69
66
 
70
- // Registration
71
- async function registerUser(email: string, password: string) {
72
- const hashedPassword = await hashPassword(password);
73
- // Save user with hashedPassword to database
74
- return { email, password: hashedPassword };
67
+ comparePassword()
68
+
69
+ Alias for backward compatibility.
70
+
71
+ 🔑 2. JWT Signing
72
+ signToken(payload, secret, expiresIn, options)
73
+
74
+ Creates a JWT with custom exp logic ("15m", "1h", "7d")
75
+
76
+ const token = signToken(
77
+ { userId: 1 },
78
+ process.env.JWT_SECRET!,
79
+ "1h"
80
+ );
81
+
82
+ console.log(token);
83
+
84
+
85
+ ✔ No deprecated expiresIn from jsonwebtoken
86
+ ✔ Expiration is injected manually via exp
87
+
88
+ 🧮 3. parseDuration()
89
+
90
+ Parses duration strings into seconds.
91
+
92
+ parseDuration("15m"); // 900
93
+ parseDuration("2h"); // 7200
94
+ parseDuration("7d"); // 604800
95
+
96
+
97
+ Useful for token expiry, cache expiry, rate limiting, etc.
98
+
99
+ 🪪 4. generateTokens()
100
+
101
+ Generates access + refresh token pair.
102
+
103
+ const tokens = generateTokens(
104
+ { userId: 42 },
105
+ process.env.ACCESS_SECRET!,
106
+ process.env.REFRESH_SECRET!,
107
+ "15m",
108
+ "7d"
109
+ );
110
+
111
+ console.log(tokens.accessToken);
112
+ console.log(tokens.refreshToken);
113
+
114
+ ♻️ 5. rotateRefreshToken()
115
+
116
+ Creates a new refresh token using the old one:
117
+
118
+ import { rotateRefreshToken } from "@naman_deep_singh/security";
119
+
120
+ const newRefreshToken = rotateRefreshToken(
121
+ oldRefreshToken,
122
+ process.env.REFRESH_SECRET!
123
+ );
124
+
125
+
126
+ ✔ Automatically removes old exp and iat
127
+ ✔ Generates fresh expiration
128
+
129
+ 🔍 6. verifyToken()
130
+
131
+ Throws if token is invalid or expired.
132
+
133
+ try {
134
+ const payload = verifyToken(token, process.env.ACCESS_SECRET!);
135
+ console.log("User authenticated:", payload);
136
+ } catch (err) {
137
+ console.error("Invalid or expired token");
75
138
  }
76
139
 
77
- // Login
78
- async function loginUser(email: string, password: string, storedHash: string) {
79
- const isValid = await verifyPassword(password, storedHash);
80
-
81
- if (!isValid) {
82
- throw new Error('Invalid credentials');
140
+ 🛡 7. safeVerifyToken()
141
+
142
+ Never throws returns { valid, payload?, error? }
143
+
144
+ const result = safeVerifyToken(token, process.env.ACCESS_SECRET!);
145
+
146
+ if (!result.valid) {
147
+ console.log("Token invalid:", result.error);
148
+ } else {
149
+ console.log("Token OK:", result.payload);
150
+ }
151
+
152
+ 🧬 8. Decoding Helpers
153
+ decodeToken(token)
154
+
155
+ Flexible — returns null | string | JwtPayload
156
+
157
+ const decoded = decodeToken(token);
158
+ console.log(decoded);
159
+
160
+ decodeTokenStrict(token)
161
+
162
+ Throws if payload is not an object.
163
+
164
+ try {
165
+ const payload = decodeTokenStrict(token);
166
+ console.log(payload.userId);
167
+ } catch (e) {
168
+ console.error("Invalid token payload");
169
+ }
170
+
171
+ 🛰 9. extractToken()
172
+
173
+ Extracts tokens from:
174
+
175
+ Headers (Authorization: Bearer <token>)
176
+
177
+ Cookies (token, accessToken)
178
+
179
+ Query (?token=...)
180
+
181
+ Body ({ token: "" })
182
+
183
+ WebSocket messages (string or object)
184
+
185
+ Example: Express middleware
186
+ export function authMiddleware(req, res, next) {
187
+ const token = extractToken({
188
+ header: req.headers.authorization,
189
+ cookies: req.cookies,
190
+ query: req.query,
191
+ body: req.body
192
+ });
193
+
194
+ if (!token) return res.status(401).json({ error: "Token missing" });
195
+
196
+ try {
197
+ req.user = verifyToken(token, process.env.ACCESS_SECRET!);
198
+ next();
199
+ } catch (err) {
200
+ return res.status(401).json({ error: "Invalid token" });
201
+ }
202
+ }
203
+
204
+ Example: WebSocket (ws library)
205
+ ws.on("message", (msg) => {
206
+ const token = extractToken({ wsMessage: msg });
207
+
208
+ if (!token) return;
209
+
210
+ const result = safeVerifyToken(token, process.env.ACCESS_SECRET!);
211
+
212
+ if (result.valid) {
213
+ console.log("WS authenticated user:", result.payload);
83
214
  }
84
-
85
- const token = generateToken(
86
- { email, loginTime: Date.now() },
87
- process.env.JWT_SECRET!,
88
- '7d'
215
+ });
216
+
217
+ 🧩 10. Full Authentication Example
218
+ Registration
219
+ async function registerUser(email: string, password: string) {
220
+ const hash = await hashPassword(password);
221
+
222
+ return {
223
+ email,
224
+ passwordHash: hash
225
+ };
226
+ }
227
+
228
+ Login
229
+ async function loginUser(email, password, storedHash) {
230
+ const valid = await verifyPassword(password, storedHash);
231
+
232
+ if (!valid) throw new Error("Invalid credentials");
233
+
234
+ return generateTokens(
235
+ { email },
236
+ process.env.ACCESS_SECRET!,
237
+ process.env.REFRESH_SECRET!,
238
+ "15m",
239
+ "7d"
240
+ );
241
+ }
242
+
243
+ Token Refresh
244
+ function refresh(oldRefreshToken) {
245
+ const newRefreshToken = rotateRefreshToken(
246
+ oldRefreshToken,
247
+ process.env.REFRESH_SECRET!
248
+ );
249
+
250
+ const decoded = decodeTokenStrict(oldRefreshToken);
251
+
252
+ const newAccessToken = signToken(
253
+ { userId: decoded.userId },
254
+ process.env.ACCESS_SECRET!,
255
+ "15m"
89
256
  );
90
-
91
- return { token };
257
+
258
+ return { accessToken: newAccessToken, refreshToken: newRefreshToken };
92
259
  }
93
260
 
94
- // Verify JWT
95
- function authenticateRequest(token: string) {
261
+ 🚨 Error Handling
262
+
263
+ This package uses standardized errors from `@naman_deep_singh/errors-utils`:
264
+
265
+ ```typescript
266
+ import {
267
+ hashPassword,
268
+ verifyPassword,
269
+ BadRequestError,
270
+ UnauthorizedError,
271
+ ValidationError,
272
+ InternalServerError
273
+ } from '@naman_deep_singh/security';
274
+
275
+ try {
276
+ const hash = await hashPassword('mypassword');
277
+ } catch (error) {
278
+ if (error instanceof BadRequestError) {
279
+ // Invalid password input (400)
280
+ console.log('Invalid password provided');
281
+ } else if (error instanceof InternalServerError) {
282
+ // Hashing failed (500)
283
+ console.log('Server error during hashing');
284
+ }
285
+ }
286
+
287
+ try {
288
+ const isValid = await verifyPassword('password', hash);
289
+ } catch (error) {
290
+ if (error instanceof UnauthorizedError) {
291
+ // Password verification failed (401)
292
+ console.log('Invalid credentials');
293
+ }
294
+ }
295
+ ```
296
+
297
+ **Error Types:**
298
+ - `BadRequestError` (400) - Invalid input data
299
+ - `UnauthorizedError` (401) - Authentication failures
300
+ - `ValidationError` (422) - Password strength validation
301
+ - `InternalServerError` (500) - Server-side processing errors
302
+
303
+ 🔐 Security Best Practices
304
+
305
+ ✔ Use 32+ character secrets
306
+ ✔ Store secrets in environment variables
307
+ ✔ Always use HTTPS in production
308
+ ✔ Keep refresh tokens secure (HttpOnly cookie recommended)
309
+ ✔ Do not store passwords in plain text—ever
310
+ ✔ Handle errors appropriately with proper HTTP status codes
311
+
312
+ 🔗 Integration with Other Packages
313
+
314
+ ### With @naman_deep_singh/server-utils
315
+
316
+ ```typescript
317
+ import { createServer } from '@naman_deep_singh/server-utils';
318
+ import { hashPassword, verifyPassword } from '@naman_deep_singh/security';
319
+
320
+ const server = createServer('Auth API', '1.0.0');
321
+
322
+ server.app.post('/register', async (req, res) => {
96
323
  try {
97
- const decoded = verifyToken(token, process.env.JWT_SECRET!);
98
- return decoded;
324
+ const { password } = req.body;
325
+ const hash = await hashPassword(password);
326
+ // Save user with hash...
327
+ res.json({ success: true });
99
328
  } catch (error) {
100
- throw new Error('Invalid token');
329
+ // Errors automatically handled by server-utils middleware
330
+ throw error; // Will be caught and formatted consistently
101
331
  }
102
- }
332
+ });
103
333
  ```
104
334
 
105
- ## Dependencies
335
+ ### With @naman_deep_singh/errors-utils + @naman_deep_singh/response-utils
106
336
 
107
- - **bcryptjs** - For secure password hashing
108
- - **jsonwebtoken** - For JWT token management
337
+ ```typescript
338
+ import { expressErrorHandler } from '@naman_deep_singh/errors-utils';
339
+ import { responderMiddleware } from '@naman_deep_singh/response-utils';
340
+
341
+ server.app.use(responderMiddleware());
342
+ server.app.use(expressErrorHandler); // Handles security errors consistently
343
+ ```
109
344
 
110
- ## Security Best Practices
345
+ 📜 License
111
346
 
112
- 1. **Use strong secrets** for JWT signing (minimum 32 characters)
113
- 2. **Set appropriate expiration times** for tokens
114
- 3. **Store JWT secrets in environment variables**
115
- 4. **Never log or expose hashed passwords**
116
- 5. **Use HTTPS** in production for token transmission
347
+ MIT free to use & modify.
@@ -0,0 +1 @@
1
+ export declare const decrypt: (data: string, secret: string) => string;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.decrypt = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const ALGO = "AES-256-GCM";
9
+ const decrypt = (data, secret) => {
10
+ const [ivHex, encryptedHex] = data.split(":");
11
+ const iv = Buffer.from(ivHex, "hex");
12
+ const encrypted = Buffer.from(encryptedHex, "hex");
13
+ const key = crypto_1.default.createHash("sha256").update(secret).digest();
14
+ const decipher = crypto_1.default.createDecipheriv(ALGO, key, iv);
15
+ const decrypted = Buffer.concat([
16
+ decipher.update(encrypted),
17
+ decipher.final(),
18
+ ]);
19
+ return decrypted.toString("utf8");
20
+ };
21
+ exports.decrypt = decrypt;
@@ -0,0 +1 @@
1
+ export declare const encrypt: (text: string, secret: string) => string;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.encrypt = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const ALGO = "AES-256-GCM";
9
+ const encrypt = (text, secret) => {
10
+ const key = crypto_1.default.createHash("sha256").update(secret).digest();
11
+ const iv = crypto_1.default.randomBytes(16);
12
+ const cipher = crypto_1.default.createCipheriv(ALGO, key, iv);
13
+ const encrypted = Buffer.concat([cipher.update(text, "utf8"), cipher.final()]);
14
+ return `${iv.toString("hex")}:${encrypted.toString("hex")}`;
15
+ };
16
+ exports.encrypt = encrypt;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Sign message using HMAC SHA-256
3
+ */
4
+ export declare const hmacSign: (message: string, secret: string) => string;
5
+ /**
6
+ * Verify HMAC signature
7
+ */
8
+ export declare const hmacVerify: (message: string, secret: string, signature: string) => boolean;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.hmacVerify = exports.hmacSign = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ /**
9
+ * Sign message using HMAC SHA-256
10
+ */
11
+ const hmacSign = (message, secret) => {
12
+ return crypto_1.default.createHmac("sha256", secret).update(message).digest("hex");
13
+ };
14
+ exports.hmacSign = hmacSign;
15
+ /**
16
+ * Verify HMAC signature
17
+ */
18
+ const hmacVerify = (message, secret, signature) => {
19
+ const expected = (0, exports.hmacSign)(message, secret);
20
+ if (signature.length !== expected.length)
21
+ return false;
22
+ return crypto_1.default.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
23
+ };
24
+ exports.hmacVerify = hmacVerify;
@@ -0,0 +1,4 @@
1
+ export * from "./decrypt";
2
+ export * from "./encrypt";
3
+ export * from "./hmac";
4
+ export * from "./random";
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./decrypt"), exports);
18
+ __exportStar(require("./encrypt"), exports);
19
+ __exportStar(require("./hmac"), exports);
20
+ __exportStar(require("./random"), exports);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Generate cryptographically secure random string
3
+ */
4
+ export declare const randomToken: (length?: number) => string;
5
+ /**
6
+ * Generate a strong random password
7
+ */
8
+ export declare const generateStrongPassword: (length?: number) => string;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateStrongPassword = exports.randomToken = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ /**
9
+ * Generate cryptographically secure random string
10
+ */
11
+ const randomToken = (length = 32) => {
12
+ return crypto_1.default.randomBytes(length).toString("hex");
13
+ };
14
+ exports.randomToken = randomToken;
15
+ /**
16
+ * Generate a strong random password
17
+ */
18
+ const generateStrongPassword = (length = 16) => {
19
+ return crypto_1.default.randomBytes(length).toString("hex").slice(0, length);
20
+ };
21
+ exports.generateStrongPassword = generateStrongPassword;
@@ -0,0 +1,12 @@
1
+ import { JwtPayload } from "jsonwebtoken";
2
+ /**
3
+ * Flexible decode
4
+ * Returns: null | string | JwtPayload
5
+ * Mirrors jsonwebtoken.decode()
6
+ */
7
+ export declare function decodeToken(token: string): null | string | JwtPayload;
8
+ /**
9
+ * Strict decode
10
+ * Always returns JwtPayload or throws error
11
+ */
12
+ export declare function decodeTokenStrict(token: string): JwtPayload;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decodeToken = decodeToken;
4
+ exports.decodeTokenStrict = decodeTokenStrict;
5
+ // src/jwt/decodeToken.ts
6
+ const jsonwebtoken_1 = require("jsonwebtoken");
7
+ /**
8
+ * Flexible decode
9
+ * Returns: null | string | JwtPayload
10
+ * Mirrors jsonwebtoken.decode()
11
+ */
12
+ function decodeToken(token) {
13
+ return (0, jsonwebtoken_1.decode)(token);
14
+ }
15
+ /**
16
+ * Strict decode
17
+ * Always returns JwtPayload or throws error
18
+ */
19
+ function decodeTokenStrict(token) {
20
+ const decoded = (0, jsonwebtoken_1.decode)(token);
21
+ if (!decoded || typeof decoded === "string") {
22
+ throw new Error("Invalid JWT payload structure");
23
+ }
24
+ return decoded;
25
+ }
@@ -0,0 +1,11 @@
1
+ export interface TokenSources {
2
+ header?: string | undefined | null;
3
+ cookies?: Record<string, string> | undefined;
4
+ query?: Record<string, string | undefined> | undefined;
5
+ body?: Record<string, any> | undefined;
6
+ wsMessage?: string | Record<string, any> | undefined;
7
+ }
8
+ /**
9
+ * Universal token extractor
10
+ */
11
+ export declare function extractToken(sources: TokenSources): string | null;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractToken = extractToken;
4
+ /**
5
+ * Universal token extractor
6
+ */
7
+ function extractToken(sources) {
8
+ const { header, cookies, query, body, wsMessage } = sources;
9
+ // 1. Authorization: Bearer <token>
10
+ if (header) {
11
+ const parts = header.split(" ");
12
+ if (parts.length === 2 && parts[0] === "Bearer")
13
+ return parts[1];
14
+ }
15
+ // 2. Cookies: token / accessToken
16
+ if (cookies) {
17
+ if (cookies["token"])
18
+ return cookies["token"];
19
+ if (cookies["accessToken"])
20
+ return cookies["accessToken"];
21
+ }
22
+ // 3. Query params: ?token=xxx
23
+ if (query?.token)
24
+ return query.token;
25
+ // 4. Body: { token: "" }
26
+ if (body?.token)
27
+ return body.token;
28
+ // 5. WebSocket message extraction (NEW)
29
+ if (wsMessage) {
30
+ try {
31
+ let msg = wsMessage;
32
+ // If it's a JSON string → parse safely
33
+ if (typeof wsMessage === "string") {
34
+ msg = JSON.parse(wsMessage);
35
+ }
36
+ // Direct token
37
+ if (typeof msg.token === "string")
38
+ return msg.token;
39
+ // Nested token: { auth: { token: "" } }
40
+ if (msg.auth && typeof msg.auth.token === "string") {
41
+ return msg.auth.token;
42
+ }
43
+ }
44
+ catch {
45
+ // Ignore parse errors gracefully
46
+ }
47
+ }
48
+ return null;
49
+ }
@@ -0,0 +1,7 @@
1
+ import { Secret } from "jsonwebtoken";
2
+ export interface TokenPair {
3
+ accessToken: string;
4
+ refreshToken: string;
5
+ }
6
+ export declare const generateTokens: (payload: object, accessSecret: Secret, refreshSecret: Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => TokenPair;
7
+ export declare function rotateRefreshToken(oldToken: string, secret: Secret): string;