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