@naman_deep_singh/security 1.3.2 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +153 -355
  2. package/dist/cjs/core/crypto/cryptoManager.d.ts +5 -5
  3. package/dist/cjs/core/crypto/cryptoManager.js +42 -25
  4. package/dist/cjs/core/jwt/decode.js +4 -1
  5. package/dist/cjs/core/jwt/generateTokens.d.ts +1 -1
  6. package/dist/cjs/core/jwt/generateTokens.js +7 -4
  7. package/dist/cjs/core/jwt/jwtManager.d.ts +19 -43
  8. package/dist/cjs/core/jwt/jwtManager.js +72 -202
  9. package/dist/cjs/core/jwt/parseDuration.js +3 -2
  10. package/dist/cjs/core/jwt/signToken.js +2 -1
  11. package/dist/cjs/core/jwt/validateToken.d.ts +10 -7
  12. package/dist/cjs/core/jwt/validateToken.js +14 -11
  13. package/dist/cjs/core/jwt/verify.d.ts +9 -10
  14. package/dist/cjs/core/jwt/verify.js +57 -14
  15. package/dist/cjs/core/password/hash.js +4 -4
  16. package/dist/cjs/core/password/passwordManager.d.ts +2 -2
  17. package/dist/cjs/core/password/passwordManager.js +43 -82
  18. package/dist/cjs/core/password/strength.js +5 -5
  19. package/dist/cjs/core/password/utils.d.ts +12 -0
  20. package/dist/cjs/core/password/utils.js +16 -1
  21. package/dist/cjs/core/password/verify.js +5 -5
  22. package/dist/cjs/index.d.ts +2 -7
  23. package/dist/esm/core/crypto/cryptoManager.d.ts +5 -5
  24. package/dist/esm/core/crypto/cryptoManager.js +42 -25
  25. package/dist/esm/core/jwt/decode.js +4 -1
  26. package/dist/esm/core/jwt/generateTokens.d.ts +1 -1
  27. package/dist/esm/core/jwt/generateTokens.js +7 -4
  28. package/dist/esm/core/jwt/jwtManager.d.ts +19 -43
  29. package/dist/esm/core/jwt/jwtManager.js +73 -203
  30. package/dist/esm/core/jwt/parseDuration.js +3 -2
  31. package/dist/esm/core/jwt/signToken.js +2 -1
  32. package/dist/esm/core/jwt/validateToken.d.ts +10 -7
  33. package/dist/esm/core/jwt/validateToken.js +14 -11
  34. package/dist/esm/core/jwt/verify.d.ts +9 -10
  35. package/dist/esm/core/jwt/verify.js +55 -12
  36. package/dist/esm/core/password/hash.js +4 -4
  37. package/dist/esm/core/password/passwordManager.d.ts +2 -2
  38. package/dist/esm/core/password/passwordManager.js +43 -82
  39. package/dist/esm/core/password/strength.js +5 -5
  40. package/dist/esm/core/password/utils.d.ts +12 -0
  41. package/dist/esm/core/password/utils.js +16 -1
  42. package/dist/esm/core/password/verify.js +5 -5
  43. package/dist/esm/index.d.ts +2 -7
  44. package/dist/types/core/crypto/cryptoManager.d.ts +5 -5
  45. package/dist/types/core/jwt/generateTokens.d.ts +1 -1
  46. package/dist/types/core/jwt/jwtManager.d.ts +19 -43
  47. package/dist/types/core/jwt/validateToken.d.ts +10 -7
  48. package/dist/types/core/jwt/verify.d.ts +9 -10
  49. package/dist/types/core/password/passwordManager.d.ts +2 -2
  50. package/dist/types/core/password/utils.d.ts +12 -0
  51. package/dist/types/index.d.ts +2 -7
  52. package/package.json +2 -2
@@ -15,285 +15,155 @@ class JWTManager {
15
15
  this.refreshSecret = config.refreshSecret;
16
16
  this.accessExpiry = config.accessExpiry || '15m';
17
17
  this.refreshExpiry = config.refreshExpiry || '7d';
18
- this.cacheTTL = 5 * 60 * 1000; // 5 minutes default TTL
18
+ this.cacheTTL = 5 * 60 * 1000; // 5 minutes
19
19
  if (config.enableCaching) {
20
20
  this.cache = new js_extensions_1.LRUCache(config.maxCacheSize || 100);
21
21
  }
22
22
  }
23
- /**
24
- * Generate both access and refresh tokens
25
- */
23
+ /** Generate both access and refresh tokens */
26
24
  async generateTokens(payload) {
27
25
  try {
28
26
  this.validatePayload(payload);
29
27
  const accessToken = await this.generateAccessToken(payload);
30
28
  const refreshToken = await this.generateRefreshToken(payload);
31
- return {
32
- accessToken,
33
- refreshToken,
34
- };
29
+ return { accessToken, refreshToken };
35
30
  }
36
31
  catch (error) {
37
- if (error instanceof errors_utils_1.BadRequestError ||
38
- error instanceof errors_utils_1.ValidationError) {
32
+ if (error instanceof errors_utils_1.BadRequestError || error instanceof errors_utils_1.ValidationError)
39
33
  throw error;
40
- }
41
- throw new errors_utils_1.BadRequestError('Failed to generate tokens');
34
+ throw new errors_utils_1.BadRequestError({ message: 'Failed to generate tokens' }, error instanceof Error ? error : undefined);
42
35
  }
43
36
  }
44
- /**
45
- * Generate access token
46
- */
37
+ /** Generate access token */
47
38
  async generateAccessToken(payload) {
48
39
  try {
49
40
  this.validatePayload(payload);
50
- const token = (0, signToken_1.signToken)(payload, this.accessSecret, this.accessExpiry, {
51
- algorithm: 'HS256',
52
- });
41
+ const token = (0, signToken_1.signToken)(payload, this.accessSecret, this.accessExpiry, { algorithm: 'HS256' });
53
42
  return token;
54
43
  }
55
44
  catch (error) {
56
- if (error instanceof errors_utils_1.BadRequestError ||
57
- error instanceof errors_utils_1.ValidationError) {
45
+ if (error instanceof errors_utils_1.BadRequestError || error instanceof errors_utils_1.ValidationError)
58
46
  throw error;
59
- }
60
- throw new errors_utils_1.BadRequestError('Failed to generate access token');
47
+ throw new errors_utils_1.BadRequestError({ message: 'Failed to generate access token' }, error instanceof Error ? error : undefined);
61
48
  }
62
49
  }
63
- /**
64
- * Generate refresh token
65
- */
50
+ /** Generate refresh token */
66
51
  async generateRefreshToken(payload) {
67
52
  try {
68
53
  this.validatePayload(payload);
69
- const token = (0, signToken_1.signToken)(payload, this.refreshSecret, this.refreshExpiry, {
70
- algorithm: 'HS256',
71
- });
54
+ const token = (0, signToken_1.signToken)(payload, this.refreshSecret, this.refreshExpiry, { algorithm: 'HS256' });
72
55
  return token;
73
56
  }
74
57
  catch (error) {
75
- if (error instanceof errors_utils_1.BadRequestError ||
76
- error instanceof errors_utils_1.ValidationError) {
58
+ if (error instanceof errors_utils_1.BadRequestError || error instanceof errors_utils_1.ValidationError)
77
59
  throw error;
78
- }
79
- throw new errors_utils_1.BadRequestError('Failed to generate refresh token');
60
+ throw new errors_utils_1.BadRequestError({ message: 'Failed to generate refresh token' }, error instanceof Error ? error : undefined);
80
61
  }
81
62
  }
82
- /**
83
- * Verify access token
84
- */
63
+ /** Verify access token */
85
64
  async verifyAccessToken(token) {
86
- try {
87
- if (!token || typeof token !== 'string') {
88
- throw new errors_utils_1.ValidationError('Access token must be a non-empty string');
89
- }
90
- const cacheKey = `access_${token}`;
91
- if (this.cache) {
92
- const cached = this.cache.get(cacheKey);
93
- if (cached && Date.now() - cached.timestamp <= this.cacheTTL) {
94
- if (!cached.valid) {
95
- throw new errors_utils_1.UnauthorizedError('Access token is invalid or expired');
96
- }
97
- return cached.payload;
98
- }
99
- }
100
- const decoded = (0, verify_1.verifyToken)(token, this.accessSecret);
101
- if (this.cache) {
102
- this.cache.set(cacheKey, {
103
- valid: true,
104
- payload: decoded,
105
- timestamp: Date.now(),
106
- });
107
- }
108
- return decoded;
109
- }
110
- catch (error) {
111
- if (error instanceof errors_utils_1.ValidationError ||
112
- error instanceof errors_utils_1.UnauthorizedError) {
113
- throw error;
114
- }
115
- if (error instanceof Error && error.name === 'TokenExpiredError') {
116
- throw new errors_utils_1.UnauthorizedError('Access token has expired');
117
- }
118
- if (error instanceof Error && error.name === 'JsonWebTokenError') {
119
- throw new errors_utils_1.UnauthorizedError('Access token is invalid');
120
- }
121
- throw new errors_utils_1.UnauthorizedError('Failed to verify access token');
122
- }
65
+ return this.verifyTokenWithCache(token, this.accessSecret, 'access');
123
66
  }
124
- /**
125
- * Verify refresh token
126
- */
67
+ /** Verify refresh token */
127
68
  async verifyRefreshToken(token) {
128
- try {
129
- if (!token || typeof token !== 'string') {
130
- throw new errors_utils_1.ValidationError('Refresh token must be a non-empty string');
131
- }
132
- const cacheKey = `refresh_${token}`;
133
- if (this.cache) {
134
- const cached = this.cache.get(cacheKey);
135
- if (cached) {
136
- if (!cached.valid) {
137
- throw new errors_utils_1.UnauthorizedError('Refresh token is invalid or expired');
138
- }
139
- return cached.payload;
140
- }
141
- }
142
- const decoded = (0, verify_1.verifyToken)(token, this.refreshSecret);
143
- if (this.cache) {
144
- this.cache.set(cacheKey, { valid: true, payload: decoded, timestamp: Date.now() });
145
- }
146
- return decoded;
147
- }
148
- catch (error) {
149
- if (error instanceof errors_utils_1.ValidationError ||
150
- error instanceof errors_utils_1.UnauthorizedError) {
151
- throw error;
152
- }
153
- if (error instanceof Error && error.name === 'TokenExpiredError') {
154
- throw new errors_utils_1.UnauthorizedError('Refresh token has expired');
155
- }
156
- if (error instanceof Error && error.name === 'JsonWebTokenError') {
157
- throw new errors_utils_1.UnauthorizedError('Refresh token is invalid');
158
- }
159
- throw new errors_utils_1.UnauthorizedError('Failed to verify refresh token');
160
- }
69
+ return this.verifyTokenWithCache(token, this.refreshSecret, 'refresh');
161
70
  }
162
- /**
163
- * Decode token without verification
164
- */
71
+ /** Decode token without verification */
165
72
  decodeToken(token, complete = false) {
166
- try {
167
- if (!token || typeof token !== 'string') {
168
- throw new errors_utils_1.ValidationError('Token must be a non-empty string');
169
- }
170
- return jsonwebtoken_1.default.decode(token, { complete });
171
- }
172
- catch (error) {
173
- if (error instanceof errors_utils_1.ValidationError) {
174
- throw error;
175
- }
73
+ if (!token || typeof token !== 'string')
176
74
  return null;
177
- }
75
+ return jsonwebtoken_1.default.decode(token, { complete });
178
76
  }
179
- /**
180
- * Extract token from Authorization header
181
- */
77
+ /** Extract token from Authorization header */
182
78
  extractTokenFromHeader(authHeader) {
183
- try {
184
- if (!authHeader || typeof authHeader !== 'string') {
185
- return null;
186
- }
187
- const parts = authHeader.split(' ');
188
- if (parts.length !== 2 || parts[0] !== 'Bearer') {
189
- return null;
190
- }
191
- return parts[1];
192
- }
193
- catch {
79
+ if (!authHeader || typeof authHeader !== 'string')
194
80
  return null;
195
- }
81
+ const parts = authHeader.split(' ');
82
+ if (parts.length !== 2 || parts[0] !== 'Bearer')
83
+ return null;
84
+ return parts[1];
196
85
  }
197
- /**
198
- * Validate token without throwing exceptions
199
- */
200
- validateToken(token, secret, options = {}) {
201
- try {
202
- if (!token || typeof token !== 'string') {
203
- return false;
204
- }
205
- const result = (0, verify_1.safeVerifyToken)(token, secret);
206
- return result.valid;
207
- }
208
- catch {
86
+ /** Validate token without throwing exceptions */
87
+ validateToken(token, secret) {
88
+ if (!token || typeof token !== 'string')
209
89
  return false;
210
- }
90
+ return (0, verify_1.safeVerifyToken)(token, secret).valid;
211
91
  }
212
- /**
213
- * Rotate refresh token
214
- */
92
+ /** Rotate refresh token */
215
93
  async rotateRefreshToken(oldToken) {
216
- try {
217
- if (!oldToken || typeof oldToken !== 'string') {
218
- throw new errors_utils_1.ValidationError('Old refresh token must be a non-empty string');
219
- }
220
- const decoded = await this.verifyRefreshToken(oldToken);
221
- if (typeof decoded === 'string') {
222
- throw new errors_utils_1.ValidationError('Invalid token payload — expected JWT payload object');
223
- }
224
- // Create new payload without issued/expired timestamps
225
- const payload = { ...decoded };
226
- delete payload.iat;
227
- delete payload.exp;
228
- // Generate new refresh token
229
- const newToken = (0, signToken_1.signToken)(payload, this.refreshSecret, this.refreshExpiry);
230
- return newToken;
231
- }
232
- catch (error) {
233
- if (error instanceof errors_utils_1.ValidationError ||
234
- error instanceof errors_utils_1.UnauthorizedError) {
235
- throw error;
236
- }
237
- throw new errors_utils_1.BadRequestError('Failed to rotate refresh token');
238
- }
94
+ if (!oldToken || typeof oldToken !== 'string') {
95
+ throw new errors_utils_1.ValidationError({ message: 'Old refresh token must be a non-empty string' });
96
+ }
97
+ const decoded = await this.verifyRefreshToken(oldToken);
98
+ const payload = { ...decoded };
99
+ delete payload.iat;
100
+ delete payload.exp;
101
+ const newToken = (0, signToken_1.signToken)(payload, this.refreshSecret, this.refreshExpiry);
102
+ return newToken;
239
103
  }
240
- /**
241
- * Check if token is expired
242
- */
104
+ /** Check if token is expired */
243
105
  isTokenExpired(token) {
244
106
  try {
245
107
  const decoded = this.decodeToken(token);
246
- if (!decoded || !decoded.exp) {
108
+ if (!decoded || !decoded.exp)
247
109
  return true;
248
- }
249
- const currentTime = Math.floor(Date.now() / 1000);
250
- return decoded.exp < currentTime;
110
+ return decoded.exp < Math.floor(Date.now() / 1000);
251
111
  }
252
112
  catch {
253
113
  return true;
254
114
  }
255
115
  }
256
- /**
257
- * Get token expiration date
258
- */
116
+ /** Get token expiration date */
259
117
  getTokenExpiration(token) {
260
118
  try {
261
119
  const decoded = this.decodeToken(token);
262
- if (!decoded || !decoded.exp) {
120
+ if (!decoded || !decoded.exp)
263
121
  return null;
264
- }
265
122
  return new Date(decoded.exp * 1000);
266
123
  }
267
124
  catch {
268
125
  return null;
269
126
  }
270
127
  }
271
- /**
272
- * Clear token cache
273
- */
128
+ /** Clear token cache */
274
129
  clearCache() {
275
130
  this.cache?.clear();
276
131
  }
277
- /**
278
- * Get cache statistics
279
- */
132
+ /** Get cache statistics */
280
133
  getCacheStats() {
281
134
  if (!this.cache)
282
135
  return null;
283
- // Note: LRUCache doesn't expose internal size, so we return maxSize only
284
- return {
285
- size: -1, // Size not available from LRUCache
286
- maxSize: this.cache.maxSize,
287
- };
136
+ return { size: -1, maxSize: this.cache.maxSize };
288
137
  }
289
- // Private helper methods
138
+ /** Private helper methods */
290
139
  validatePayload(payload) {
291
140
  if (!payload || typeof payload !== 'object') {
292
- throw new errors_utils_1.ValidationError('Payload must be a non-null object');
141
+ throw new errors_utils_1.ValidationError({ message: 'Payload must be a non-null object' });
293
142
  }
294
143
  if (Object.keys(payload).length === 0) {
295
- throw new errors_utils_1.ValidationError('Payload cannot be empty');
144
+ throw new errors_utils_1.ValidationError({ message: 'Payload cannot be empty' });
296
145
  }
297
146
  }
147
+ async verifyTokenWithCache(token, secret, type) {
148
+ if (!token || typeof token !== 'string') {
149
+ throw new errors_utils_1.ValidationError({ message: `${type} token must be a non-empty string` });
150
+ }
151
+ const cacheKey = `${type}_${token}`;
152
+ if (this.cache) {
153
+ const cached = this.cache.get(cacheKey);
154
+ if (cached && Date.now() - cached.timestamp <= this.cacheTTL) {
155
+ if (!cached.valid)
156
+ throw new errors_utils_1.UnauthorizedError({ message: `${type} token is invalid or expired` });
157
+ return cached.payload;
158
+ }
159
+ }
160
+ const { valid, payload, error } = (0, verify_1.safeVerifyToken)(token, secret);
161
+ if (!valid || !payload || typeof payload === 'string') {
162
+ this.cache?.set(cacheKey, { valid: false, payload: {}, timestamp: Date.now() });
163
+ throw new errors_utils_1.UnauthorizedError({ message: `${type} token is invalid or expired`, cause: error });
164
+ }
165
+ this.cache?.set(cacheKey, { valid: true, payload, timestamp: Date.now() });
166
+ return payload;
167
+ }
298
168
  }
299
169
  exports.JWTManager = JWTManager;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseDuration = parseDuration;
4
+ const errors_utils_1 = require("@naman_deep_singh/errors-utils");
4
5
  const TIME_UNITS = {
5
6
  s: 1,
6
7
  m: 60,
@@ -18,12 +19,12 @@ function parseDuration(input) {
18
19
  const value = Number.parseInt(match[1], 10);
19
20
  const unit = match[2].toLowerCase();
20
21
  if (!TIME_UNITS[unit]) {
21
- throw new Error(`Invalid time unit: ${unit}`);
22
+ throw new errors_utils_1.ValidationError({ message: `Invalid time unit: ${unit}` });
22
23
  }
23
24
  totalSeconds += value * TIME_UNITS[unit];
24
25
  }
25
26
  if (totalSeconds === 0) {
26
- throw new Error(`Invalid expiry format: "${input}"`);
27
+ throw new errors_utils_1.ValidationError({ message: `Invalid expiry format: "${input}"` });
27
28
  }
28
29
  return totalSeconds;
29
30
  }
@@ -3,13 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.signToken = void 0;
4
4
  const jsonwebtoken_1 = require("jsonwebtoken");
5
5
  const parseDuration_1 = require("./parseDuration");
6
+ const errors_utils_1 = require("@naman_deep_singh/errors-utils");
6
7
  function getExpiryTimestamp(seconds) {
7
8
  return Math.floor(Date.now() / 1000) + seconds;
8
9
  }
9
10
  const signToken = (payload, secret, expiresIn = '1h', options = {}) => {
10
11
  const seconds = (0, parseDuration_1.parseDuration)(expiresIn);
11
12
  if (!seconds || seconds < 10) {
12
- throw new Error('Token expiry too small');
13
+ throw new errors_utils_1.ValidationError({ message: 'Token expiry too small' });
13
14
  }
14
15
  const tokenPayload = {
15
16
  ...payload,
@@ -1,13 +1,16 @@
1
- import type { JwtPayload } from 'node_modules/@types/jsonwebtoken';
1
+ import type { JwtPayload } from 'jsonwebtoken';
2
2
  export interface TokenRequirements {
3
3
  requiredFields?: string[];
4
4
  forbiddenFields?: string[];
5
5
  validateTypes?: Record<string, 'string' | 'number' | 'boolean'>;
6
6
  }
7
- export declare function validateTokenPayload(payload: Record<string, unknown>, rules?: TokenRequirements): {
8
- valid: true;
9
- } | {
10
- valid: false;
11
- error: string;
12
- };
7
+ /**
8
+ * Validates a JWT payload according to the provided rules.
9
+ * Throws ValidationError if validation fails.
10
+ */
11
+ export declare function validateTokenPayload(payload: Record<string, unknown>, rules?: TokenRequirements): void;
12
+ /**
13
+ * Checks if a JWT payload is expired.
14
+ * Returns true if expired or missing 'exp'.
15
+ */
13
16
  export declare function isTokenExpired(payload: JwtPayload): boolean;
@@ -2,34 +2,37 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateTokenPayload = validateTokenPayload;
4
4
  exports.isTokenExpired = isTokenExpired;
5
- function validateTokenPayload(payload, rules = {
6
- requiredFields: ['exp', 'iat'],
7
- }) {
8
- const { requiredFields = [], forbiddenFields = [], validateTypes = {}, } = rules;
5
+ const errors_utils_1 = require("@naman_deep_singh/errors-utils");
6
+ /**
7
+ * Validates a JWT payload according to the provided rules.
8
+ * Throws ValidationError if validation fails.
9
+ */
10
+ function validateTokenPayload(payload, rules = { requiredFields: ['exp', 'iat'] }) {
11
+ const { requiredFields = [], forbiddenFields = [], validateTypes = {} } = rules;
9
12
  // 1. Required fields
10
13
  for (const field of requiredFields) {
11
14
  if (!(field in payload)) {
12
- return { valid: false, error: `Missing required field: ${field}` };
15
+ throw new errors_utils_1.ValidationError(`Missing required field: ${field}`);
13
16
  }
14
17
  }
15
18
  // 2. Forbidden fields
16
19
  for (const field of forbiddenFields) {
17
20
  if (field in payload) {
18
- return { valid: false, error: `Forbidden field in token: ${field}` };
21
+ throw new errors_utils_1.ValidationError(`Forbidden field in token: ${field}`);
19
22
  }
20
23
  }
21
24
  // 3. Type validation
22
25
  for (const key in validateTypes) {
23
26
  const expectedType = validateTypes[key];
24
27
  if (key in payload && typeof payload[key] !== expectedType) {
25
- return {
26
- valid: false,
27
- error: `Invalid type for ${key}. Expected ${expectedType}.`,
28
- };
28
+ throw new errors_utils_1.ValidationError(`Invalid type for ${key}. Expected ${expectedType}, got ${typeof payload[key]}`);
29
29
  }
30
30
  }
31
- return { valid: true };
32
31
  }
32
+ /**
33
+ * Checks if a JWT payload is expired.
34
+ * Returns true if expired or missing 'exp'.
35
+ */
33
36
  function isTokenExpired(payload) {
34
37
  if (!payload.exp)
35
38
  return true;
@@ -1,19 +1,18 @@
1
- import type jwt from 'jsonwebtoken';
2
- import { type JwtPayload, type Secret } from 'jsonwebtoken';
3
- import type { VerificationResult } from './types';
1
+ import { type JwtPayload, type Secret, VerifyOptions } from 'jsonwebtoken';
2
+ import { VerificationResult } from './types';
4
3
  /**
5
- * Verify token (throws if invalid or expired)
4
+ * Verify token (throws UnauthorizedError if invalid or expired)
6
5
  */
7
6
  export declare const verifyToken: (token: string, secret: Secret) => string | JwtPayload;
8
7
  /**
9
- * Safe verify never throws, returns structured result
8
+ * Verify token with options
10
9
  */
11
- export declare const safeVerifyToken: (token: string, secret: Secret) => VerificationResult;
10
+ export declare const verifyTokenWithOptions: (token: string, secret: Secret, options?: VerifyOptions) => string | JwtPayload;
12
11
  /**
13
- * Verify token with validation options
12
+ * Safe verify — never throws, returns structured result with UnauthorizedError on failure
14
13
  */
15
- export declare const verifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => string | JwtPayload;
14
+ export declare const safeVerifyToken: (token: string, secret: Secret) => VerificationResult;
16
15
  /**
17
- * Safe verify with validation options
16
+ * Safe verify with options — never throws, returns structured result with UnauthorizedError on failure
18
17
  */
19
- export declare const safeVerifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => VerificationResult;
18
+ export declare const safeVerifyTokenWithOptions: (token: string, secret: Secret, options?: VerifyOptions) => VerificationResult;
@@ -1,16 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.safeVerifyTokenWithOptions = exports.verifyTokenWithOptions = exports.safeVerifyToken = exports.verifyToken = void 0;
3
+ exports.safeVerifyTokenWithOptions = exports.safeVerifyToken = exports.verifyTokenWithOptions = exports.verifyToken = void 0;
4
4
  const jsonwebtoken_1 = require("jsonwebtoken");
5
+ const errors_utils_1 = require("@naman_deep_singh/errors-utils");
5
6
  /**
6
- * Verify token (throws if invalid or expired)
7
+ * Verify token (throws UnauthorizedError if invalid or expired)
7
8
  */
8
9
  const verifyToken = (token, secret) => {
9
- return (0, jsonwebtoken_1.verify)(token, secret);
10
+ try {
11
+ return (0, jsonwebtoken_1.verify)(token, secret);
12
+ }
13
+ catch (error) {
14
+ if (error.name === 'TokenExpiredError') {
15
+ throw new errors_utils_1.UnauthorizedError({ message: 'Token has expired' }, error);
16
+ }
17
+ if (error.name === 'JsonWebTokenError') {
18
+ throw new errors_utils_1.UnauthorizedError({ message: 'Invalid token' }, error);
19
+ }
20
+ throw new errors_utils_1.UnauthorizedError({ message: 'Failed to verify token' }, error);
21
+ }
10
22
  };
11
23
  exports.verifyToken = verifyToken;
12
24
  /**
13
- * Safe verify never throws, returns structured result
25
+ * Verify token with options
26
+ */
27
+ const verifyTokenWithOptions = (token, secret, options = {}) => {
28
+ try {
29
+ return (0, jsonwebtoken_1.verify)(token, secret, options);
30
+ }
31
+ catch (error) {
32
+ if (error.name === 'TokenExpiredError') {
33
+ throw new errors_utils_1.UnauthorizedError({ message: 'Token has expired' }, error);
34
+ }
35
+ if (error.name === 'JsonWebTokenError') {
36
+ throw new errors_utils_1.UnauthorizedError({ message: 'Invalid token' }, error);
37
+ }
38
+ throw new errors_utils_1.UnauthorizedError({ message: 'Failed to verify token' }, error);
39
+ }
40
+ };
41
+ exports.verifyTokenWithOptions = verifyTokenWithOptions;
42
+ /**
43
+ * Safe verify — never throws, returns structured result with UnauthorizedError on failure
14
44
  */
15
45
  const safeVerifyToken = (token, secret) => {
16
46
  try {
@@ -18,19 +48,22 @@ const safeVerifyToken = (token, secret) => {
18
48
  return { valid: true, payload: decoded };
19
49
  }
20
50
  catch (error) {
21
- return { valid: false, error: error };
51
+ let wrappedError;
52
+ if (error.name === 'TokenExpiredError') {
53
+ wrappedError = new errors_utils_1.UnauthorizedError({ message: 'Token has expired' }, error);
54
+ }
55
+ else if (error.name === 'JsonWebTokenError') {
56
+ wrappedError = new errors_utils_1.UnauthorizedError({ message: 'Invalid token' }, error);
57
+ }
58
+ else {
59
+ wrappedError = new errors_utils_1.UnauthorizedError({ message: 'Failed to verify token' }, error);
60
+ }
61
+ return { valid: false, error: wrappedError };
22
62
  }
23
63
  };
24
64
  exports.safeVerifyToken = safeVerifyToken;
25
65
  /**
26
- * Verify token with validation options
27
- */
28
- const verifyTokenWithOptions = (token, secret, options = {}) => {
29
- return (0, jsonwebtoken_1.verify)(token, secret, options);
30
- };
31
- exports.verifyTokenWithOptions = verifyTokenWithOptions;
32
- /**
33
- * Safe verify with validation options
66
+ * Safe verify with options — never throws, returns structured result with UnauthorizedError on failure
34
67
  */
35
68
  const safeVerifyTokenWithOptions = (token, secret, options = {}) => {
36
69
  try {
@@ -38,7 +71,17 @@ const safeVerifyTokenWithOptions = (token, secret, options = {}) => {
38
71
  return { valid: true, payload: decoded };
39
72
  }
40
73
  catch (error) {
41
- return { valid: false, error: error };
74
+ let wrappedError;
75
+ if (error.name === 'TokenExpiredError') {
76
+ wrappedError = new errors_utils_1.UnauthorizedError({ message: 'Token has expired' }, error);
77
+ }
78
+ else if (error.name === 'JsonWebTokenError') {
79
+ wrappedError = new errors_utils_1.UnauthorizedError({ message: 'Invalid token' }, error);
80
+ }
81
+ else {
82
+ wrappedError = new errors_utils_1.UnauthorizedError({ message: 'Failed to verify token' }, error);
83
+ }
84
+ return { valid: false, error: wrappedError };
42
85
  }
43
86
  };
44
87
  exports.safeVerifyTokenWithOptions = safeVerifyTokenWithOptions;
@@ -18,8 +18,8 @@ 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 (err) {
22
- throw new errors_utils_1.InternalServerError('Password hashing failed');
21
+ catch (_err) {
22
+ throw new errors_utils_1.InternalServerError({ message: 'Password hashing failed' });
23
23
  }
24
24
  };
25
25
  exports.hashPassword = hashPassword;
@@ -35,8 +35,8 @@ 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 (error) {
39
- throw new errors_utils_1.InternalServerError('Password hashing failed');
38
+ catch (_error) {
39
+ throw new errors_utils_1.InternalServerError({ message: 'Password hashing failed' });
40
40
  }
41
41
  };
42
42
  exports.hashPasswordSync = hashPasswordSync;
@@ -23,7 +23,7 @@ export declare class PasswordManager implements IPasswordManager {
23
23
  */
24
24
  checkStrength(password: string): PasswordStrength;
25
25
  /**
26
- * Check if password hash needs upgrade (different salt rounds)
26
+ * Check if password hash needs upgrade (saltRounds change)
27
27
  */
28
- needsUpgrade(hash: string, currentConfig: PasswordConfig): boolean;
28
+ needsUpgrade(_hash: string, _currentConfig: PasswordConfig): boolean;
29
29
  }