@naman_deep_singh/security 1.1.0 → 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 (36) hide show
  1. package/README.md +8 -4
  2. package/dist/cjs/core/jwt/extractToken.d.ts +2 -2
  3. package/dist/cjs/core/jwt/extractToken.js +12 -7
  4. package/dist/cjs/core/jwt/generateTokens.d.ts +3 -6
  5. package/dist/cjs/core/jwt/generateTokens.js +10 -3
  6. package/dist/cjs/core/jwt/index.d.ts +1 -0
  7. package/dist/cjs/core/jwt/index.js +1 -0
  8. package/dist/cjs/core/jwt/signToken.d.ts +1 -1
  9. package/dist/cjs/core/jwt/types.d.ts +22 -0
  10. package/dist/cjs/core/jwt/types.js +2 -0
  11. package/dist/cjs/core/jwt/validateToken.d.ts +1 -1
  12. package/dist/cjs/core/jwt/verify.d.ts +12 -7
  13. package/dist/cjs/core/jwt/verify.js +23 -3
  14. package/dist/cjs/index.d.ts +7 -9
  15. package/dist/esm/core/jwt/extractToken.d.ts +2 -2
  16. package/dist/esm/core/jwt/extractToken.js +12 -7
  17. package/dist/esm/core/jwt/generateTokens.d.ts +3 -6
  18. package/dist/esm/core/jwt/generateTokens.js +10 -3
  19. package/dist/esm/core/jwt/index.d.ts +1 -0
  20. package/dist/esm/core/jwt/index.js +1 -0
  21. package/dist/esm/core/jwt/signToken.d.ts +1 -1
  22. package/dist/esm/core/jwt/types.d.ts +22 -0
  23. package/dist/esm/core/jwt/types.js +1 -0
  24. package/dist/esm/core/jwt/validateToken.d.ts +1 -1
  25. package/dist/esm/core/jwt/verify.d.ts +12 -7
  26. package/dist/esm/core/jwt/verify.js +20 -2
  27. package/dist/esm/index.d.ts +7 -9
  28. package/dist/types/core/jwt/extractToken.d.ts +2 -2
  29. package/dist/types/core/jwt/generateTokens.d.ts +3 -6
  30. package/dist/types/core/jwt/index.d.ts +1 -0
  31. package/dist/types/core/jwt/signToken.d.ts +1 -1
  32. package/dist/types/core/jwt/types.d.ts +22 -0
  33. package/dist/types/core/jwt/validateToken.d.ts +1 -1
  34. package/dist/types/core/jwt/verify.d.ts +12 -7
  35. package/dist/types/index.d.ts +7 -9
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @naman_deep_singh/security
2
2
 
3
- **Version:** 1.1.0
3
+ **Version:** 1.2.0
4
4
 
5
5
  A complete, lightweight security toolkit for Node.js & TypeScript providing:
6
6
 
@@ -12,7 +12,11 @@ A complete, lightweight security toolkit for Node.js & TypeScript providing:
12
12
  🧰 **Robust token extraction** (Headers, Cookies, Query, Body, WebSocket)
13
13
  🧩 **Safe & strict JWT decode** utilities
14
14
  🚨 **Standardized error handling** with @naman_deep_singh/errors-utils
15
+
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
16
20
  ✔ **Consistent errors** across your application ecosystem
17
21
  ✔ **Works in both ESM and CommonJS**
18
22
 
@@ -60,13 +64,13 @@ hashPassword(password: string): Promise<string>
60
64
  const hashed = await hashPassword("mypassword");
61
65
  console.log(hashed); // $2a$10$...
62
66
 
67
+
63
68
  verifyPassword(password: string, hash: string): Promise<boolean>
64
69
  const isValid = await verifyPassword("mypassword", hashed);
65
70
  if (isValid) console.log("Correct password");
66
71
 
67
- comparePassword()
68
-
69
- Alias for backward compatibility.
72
+ // Synchronous version also available
73
+ const isValidSync = verifyPasswordSync("mypassword", hashed);
70
74
 
71
75
  🔑 2. JWT Signing
72
76
  signToken(payload, secret, expiresIn, options)
@@ -2,8 +2,8 @@ export interface TokenSources {
2
2
  header?: string | undefined | null;
3
3
  cookies?: Record<string, string> | undefined;
4
4
  query?: Record<string, string | undefined> | undefined;
5
- body?: Record<string, any> | undefined;
6
- wsMessage?: string | Record<string, any> | undefined;
5
+ body?: Record<string, unknown> | undefined;
6
+ wsMessage?: string | Record<string, unknown> | undefined;
7
7
  }
8
8
  /**
9
9
  * Universal token extractor
@@ -23,7 +23,7 @@ function extractToken(sources) {
23
23
  if (query?.token)
24
24
  return query.token;
25
25
  // 4. Body: { token: "" }
26
- if (body?.token)
26
+ if (body?.token && typeof body.token === 'string')
27
27
  return body.token;
28
28
  // 5. WebSocket message extraction (NEW)
29
29
  if (wsMessage) {
@@ -33,12 +33,17 @@ function extractToken(sources) {
33
33
  if (typeof wsMessage === "string") {
34
34
  msg = JSON.parse(wsMessage);
35
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;
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
+ }
42
47
  }
43
48
  }
44
49
  catch {
@@ -1,7 +1,4 @@
1
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;
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;
@@ -4,10 +4,16 @@ exports.generateTokens = void 0;
4
4
  exports.rotateRefreshToken = rotateRefreshToken;
5
5
  const signToken_1 = require("./signToken");
6
6
  const verify_1 = require("./verify");
7
+ // Helper function to create branded tokens
8
+ const createBrandedToken = (token, _brand) => {
9
+ return token;
10
+ };
7
11
  const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry = "15m", refreshExpiry = "7d") => {
12
+ const accessToken = (0, signToken_1.signToken)(payload, accessSecret, accessExpiry, { algorithm: "HS256" });
13
+ const refreshToken = (0, signToken_1.signToken)(payload, refreshSecret, refreshExpiry, { algorithm: "HS256" });
8
14
  return {
9
- accessToken: (0, signToken_1.signToken)(payload, accessSecret, accessExpiry, { algorithm: "HS256" }),
10
- refreshToken: (0, signToken_1.signToken)(payload, refreshSecret, refreshExpiry, { algorithm: "HS256" }),
15
+ accessToken: accessToken,
16
+ refreshToken: refreshToken,
11
17
  };
12
18
  };
13
19
  exports.generateTokens = generateTokens;
@@ -19,5 +25,6 @@ function rotateRefreshToken(oldToken, secret) {
19
25
  const payload = { ...decoded };
20
26
  delete payload.iat;
21
27
  delete payload.exp;
22
- return (0, signToken_1.signToken)(payload, secret, "7d");
28
+ const newToken = (0, signToken_1.signToken)(payload, secret, "7d");
29
+ return newToken;
23
30
  }
@@ -3,5 +3,6 @@ export * from "./extractToken";
3
3
  export * from "./generateTokens";
4
4
  export * from "./parseDuration";
5
5
  export * from "./signToken";
6
+ export * from "./types";
6
7
  export * from "./validateToken";
7
8
  export * from "./verify";
@@ -19,5 +19,6 @@ __exportStar(require("./extractToken"), exports);
19
19
  __exportStar(require("./generateTokens"), exports);
20
20
  __exportStar(require("./parseDuration"), exports);
21
21
  __exportStar(require("./signToken"), exports);
22
+ __exportStar(require("./types"), exports);
22
23
  __exportStar(require("./validateToken"), exports);
23
24
  __exportStar(require("./verify"), exports);
@@ -1,2 +1,2 @@
1
1
  import { Secret, SignOptions } from "jsonwebtoken";
2
- export declare const signToken: (payload: Record<string, any>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
2
+ export declare const signToken: (payload: Record<string, unknown>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
@@ -0,0 +1,22 @@
1
+ import { JwtPayload } from "jsonwebtoken";
2
+ export interface AccessTokenBrand {
3
+ readonly access: unique symbol;
4
+ }
5
+ export interface RefreshTokenBrand {
6
+ readonly refresh: unique symbol;
7
+ }
8
+ export type AccessToken = string & AccessTokenBrand;
9
+ export type RefreshToken = string & RefreshTokenBrand;
10
+ export interface TokenPair {
11
+ accessToken: AccessToken;
12
+ refreshToken: RefreshToken;
13
+ }
14
+ export interface VerificationResult<T = JwtPayload> {
15
+ valid: boolean;
16
+ payload?: T | string;
17
+ error?: Error;
18
+ }
19
+ export interface TokenValidationOptions {
20
+ ignoreExpiration?: boolean;
21
+ ignoreIssuedAt?: boolean;
22
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -4,7 +4,7 @@ export interface TokenRequirements {
4
4
  forbiddenFields?: string[];
5
5
  validateTypes?: Record<string, "string" | "number" | "boolean">;
6
6
  }
7
- export declare function validateTokenPayload(payload: Record<string, any>, rules?: TokenRequirements): {
7
+ export declare function validateTokenPayload(payload: Record<string, unknown>, rules?: TokenRequirements): {
8
8
  valid: true;
9
9
  } | {
10
10
  valid: false;
@@ -1,13 +1,18 @@
1
- import { Secret, JwtPayload } from "jsonwebtoken";
1
+ import jwt, { Secret, JwtPayload } from "jsonwebtoken";
2
+ import { VerificationResult } from "./types";
2
3
  /**
3
4
  * Verify token (throws if invalid or expired)
4
5
  */
5
6
  export declare const verifyToken: (token: string, secret: Secret) => string | JwtPayload;
6
7
  /**
7
- * Safe verify — never throws, returns { valid, payload?, error? }
8
+ * Safe verify — never throws, returns structured result
8
9
  */
9
- export declare const safeVerifyToken: (token: string, secret: Secret) => {
10
- valid: boolean;
11
- payload?: string | JwtPayload;
12
- error?: unknown;
13
- };
10
+ export declare const safeVerifyToken: (token: string, secret: Secret) => VerificationResult;
11
+ /**
12
+ * Verify token with validation options
13
+ */
14
+ export declare const verifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => string | JwtPayload;
15
+ /**
16
+ * Safe verify with validation options
17
+ */
18
+ export declare const safeVerifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => VerificationResult;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.safeVerifyToken = exports.verifyToken = void 0;
3
+ exports.safeVerifyTokenWithOptions = exports.verifyTokenWithOptions = exports.safeVerifyToken = exports.verifyToken = void 0;
4
4
  const jsonwebtoken_1 = require("jsonwebtoken");
5
5
  /**
6
6
  * Verify token (throws if invalid or expired)
@@ -10,7 +10,7 @@ const verifyToken = (token, secret) => {
10
10
  };
11
11
  exports.verifyToken = verifyToken;
12
12
  /**
13
- * Safe verify — never throws, returns { valid, payload?, error? }
13
+ * Safe verify — never throws, returns structured result
14
14
  */
15
15
  const safeVerifyToken = (token, secret) => {
16
16
  try {
@@ -18,7 +18,27 @@ const safeVerifyToken = (token, secret) => {
18
18
  return { valid: true, payload: decoded };
19
19
  }
20
20
  catch (error) {
21
- return { valid: false, error };
21
+ return { valid: false, error: error };
22
22
  }
23
23
  };
24
24
  exports.safeVerifyToken = safeVerifyToken;
25
+ /**
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
34
+ */
35
+ const safeVerifyTokenWithOptions = (token, secret, options = {}) => {
36
+ try {
37
+ const decoded = (0, jsonwebtoken_1.verify)(token, secret, options);
38
+ return { valid: true, payload: decoded };
39
+ }
40
+ catch (error) {
41
+ return { valid: false, error: error };
42
+ }
43
+ };
44
+ exports.safeVerifyTokenWithOptions = safeVerifyTokenWithOptions;
@@ -13,11 +13,11 @@ declare const _default: {
13
13
  decodeToken(token: string): null | string | import("node_modules/@types/jsonwebtoken").JwtPayload;
14
14
  decodeTokenStrict(token: string): import("node_modules/@types/jsonwebtoken").JwtPayload;
15
15
  extractToken(sources: JWTUtils.TokenSources): string | null;
16
- rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): string;
17
- generateTokens: (payload: object, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
16
+ rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): JWTUtils.RefreshToken;
17
+ generateTokens: (payload: Record<string, unknown>, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
18
18
  parseDuration(input: string | number): number;
19
- signToken: (payload: Record<string, any>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
20
- validateTokenPayload(payload: Record<string, any>, rules?: JWTUtils.TokenRequirements): {
19
+ signToken: (payload: Record<string, unknown>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
20
+ validateTokenPayload(payload: Record<string, unknown>, rules?: JWTUtils.TokenRequirements): {
21
21
  valid: true;
22
22
  } | {
23
23
  valid: false;
@@ -25,11 +25,9 @@ declare const _default: {
25
25
  };
26
26
  isTokenExpired(payload: import("node_modules/@types/jsonwebtoken").JwtPayload): boolean;
27
27
  verifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
28
- safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => {
29
- valid: boolean;
30
- payload?: string | import("node_modules/@types/jsonwebtoken").JwtPayload;
31
- error?: unknown;
32
- };
28
+ safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => JWTUtils.VerificationResult;
29
+ verifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
30
+ safeVerifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => JWTUtils.VerificationResult;
33
31
  hashPasswordWithPepper(password: string, pepper: string): Promise<string>;
34
32
  hashPasswordWithPepperSync(password: string, pepper: string): string;
35
33
  hashPassword: (password: string, saltRounds?: number) => Promise<string>;
@@ -2,8 +2,8 @@ export interface TokenSources {
2
2
  header?: string | undefined | null;
3
3
  cookies?: Record<string, string> | undefined;
4
4
  query?: Record<string, string | undefined> | undefined;
5
- body?: Record<string, any> | undefined;
6
- wsMessage?: string | Record<string, any> | undefined;
5
+ body?: Record<string, unknown> | undefined;
6
+ wsMessage?: string | Record<string, unknown> | undefined;
7
7
  }
8
8
  /**
9
9
  * Universal token extractor
@@ -20,7 +20,7 @@ export function extractToken(sources) {
20
20
  if (query?.token)
21
21
  return query.token;
22
22
  // 4. Body: { token: "" }
23
- if (body?.token)
23
+ if (body?.token && typeof body.token === 'string')
24
24
  return body.token;
25
25
  // 5. WebSocket message extraction (NEW)
26
26
  if (wsMessage) {
@@ -30,12 +30,17 @@ export function extractToken(sources) {
30
30
  if (typeof wsMessage === "string") {
31
31
  msg = JSON.parse(wsMessage);
32
32
  }
33
- // Direct token
34
- if (typeof msg.token === "string")
35
- return msg.token;
36
- // Nested token: { auth: { token: "" } }
37
- if (msg.auth && typeof msg.auth.token === "string") {
38
- return msg.auth.token;
33
+ // Ensure msg is an object before property access
34
+ if (typeof msg === 'object' && msg !== null) {
35
+ const m = msg;
36
+ if (typeof m['token'] === 'string')
37
+ return m['token'];
38
+ const auth = m['auth'];
39
+ if (typeof auth === 'object' && auth !== null) {
40
+ const a = auth;
41
+ if (typeof a['token'] === 'string')
42
+ return a['token'];
43
+ }
39
44
  }
40
45
  }
41
46
  catch {
@@ -1,7 +1,4 @@
1
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;
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;
@@ -1,9 +1,15 @@
1
1
  import { signToken } from "./signToken";
2
2
  import { verifyToken } from "./verify";
3
+ // Helper function to create branded tokens
4
+ const createBrandedToken = (token, _brand) => {
5
+ return token;
6
+ };
3
7
  export const generateTokens = (payload, accessSecret, refreshSecret, accessExpiry = "15m", refreshExpiry = "7d") => {
8
+ const accessToken = signToken(payload, accessSecret, accessExpiry, { algorithm: "HS256" });
9
+ const refreshToken = signToken(payload, refreshSecret, refreshExpiry, { algorithm: "HS256" });
4
10
  return {
5
- accessToken: signToken(payload, accessSecret, accessExpiry, { algorithm: "HS256" }),
6
- refreshToken: signToken(payload, refreshSecret, refreshExpiry, { algorithm: "HS256" }),
11
+ accessToken: accessToken,
12
+ refreshToken: refreshToken,
7
13
  };
8
14
  };
9
15
  export function rotateRefreshToken(oldToken, secret) {
@@ -14,5 +20,6 @@ export function rotateRefreshToken(oldToken, secret) {
14
20
  const payload = { ...decoded };
15
21
  delete payload.iat;
16
22
  delete payload.exp;
17
- return signToken(payload, secret, "7d");
23
+ const newToken = signToken(payload, secret, "7d");
24
+ return newToken;
18
25
  }
@@ -3,5 +3,6 @@ export * from "./extractToken";
3
3
  export * from "./generateTokens";
4
4
  export * from "./parseDuration";
5
5
  export * from "./signToken";
6
+ export * from "./types";
6
7
  export * from "./validateToken";
7
8
  export * from "./verify";
@@ -3,5 +3,6 @@ export * from "./extractToken";
3
3
  export * from "./generateTokens";
4
4
  export * from "./parseDuration";
5
5
  export * from "./signToken";
6
+ export * from "./types";
6
7
  export * from "./validateToken";
7
8
  export * from "./verify";
@@ -1,2 +1,2 @@
1
1
  import { Secret, SignOptions } from "jsonwebtoken";
2
- export declare const signToken: (payload: Record<string, any>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
2
+ export declare const signToken: (payload: Record<string, unknown>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
@@ -0,0 +1,22 @@
1
+ import { JwtPayload } from "jsonwebtoken";
2
+ export interface AccessTokenBrand {
3
+ readonly access: unique symbol;
4
+ }
5
+ export interface RefreshTokenBrand {
6
+ readonly refresh: unique symbol;
7
+ }
8
+ export type AccessToken = string & AccessTokenBrand;
9
+ export type RefreshToken = string & RefreshTokenBrand;
10
+ export interface TokenPair {
11
+ accessToken: AccessToken;
12
+ refreshToken: RefreshToken;
13
+ }
14
+ export interface VerificationResult<T = JwtPayload> {
15
+ valid: boolean;
16
+ payload?: T | string;
17
+ error?: Error;
18
+ }
19
+ export interface TokenValidationOptions {
20
+ ignoreExpiration?: boolean;
21
+ ignoreIssuedAt?: boolean;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -4,7 +4,7 @@ export interface TokenRequirements {
4
4
  forbiddenFields?: string[];
5
5
  validateTypes?: Record<string, "string" | "number" | "boolean">;
6
6
  }
7
- export declare function validateTokenPayload(payload: Record<string, any>, rules?: TokenRequirements): {
7
+ export declare function validateTokenPayload(payload: Record<string, unknown>, rules?: TokenRequirements): {
8
8
  valid: true;
9
9
  } | {
10
10
  valid: false;
@@ -1,13 +1,18 @@
1
- import { Secret, JwtPayload } from "jsonwebtoken";
1
+ import jwt, { Secret, JwtPayload } from "jsonwebtoken";
2
+ import { VerificationResult } from "./types";
2
3
  /**
3
4
  * Verify token (throws if invalid or expired)
4
5
  */
5
6
  export declare const verifyToken: (token: string, secret: Secret) => string | JwtPayload;
6
7
  /**
7
- * Safe verify — never throws, returns { valid, payload?, error? }
8
+ * Safe verify — never throws, returns structured result
8
9
  */
9
- export declare const safeVerifyToken: (token: string, secret: Secret) => {
10
- valid: boolean;
11
- payload?: string | JwtPayload;
12
- error?: unknown;
13
- };
10
+ export declare const safeVerifyToken: (token: string, secret: Secret) => VerificationResult;
11
+ /**
12
+ * Verify token with validation options
13
+ */
14
+ export declare const verifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => string | JwtPayload;
15
+ /**
16
+ * Safe verify with validation options
17
+ */
18
+ export declare const safeVerifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => VerificationResult;
@@ -6,7 +6,7 @@ export const verifyToken = (token, secret) => {
6
6
  return verify(token, secret);
7
7
  };
8
8
  /**
9
- * Safe verify — never throws, returns { valid, payload?, error? }
9
+ * Safe verify — never throws, returns structured result
10
10
  */
11
11
  export const safeVerifyToken = (token, secret) => {
12
12
  try {
@@ -14,6 +14,24 @@ export const safeVerifyToken = (token, secret) => {
14
14
  return { valid: true, payload: decoded };
15
15
  }
16
16
  catch (error) {
17
- return { valid: false, error };
17
+ return { valid: false, error: error };
18
+ }
19
+ };
20
+ /**
21
+ * Verify token with validation options
22
+ */
23
+ export const verifyTokenWithOptions = (token, secret, options = {}) => {
24
+ return verify(token, secret, options);
25
+ };
26
+ /**
27
+ * Safe verify with validation options
28
+ */
29
+ export const safeVerifyTokenWithOptions = (token, secret, options = {}) => {
30
+ try {
31
+ const decoded = verify(token, secret, options);
32
+ return { valid: true, payload: decoded };
33
+ }
34
+ catch (error) {
35
+ return { valid: false, error: error };
18
36
  }
19
37
  };
@@ -13,11 +13,11 @@ declare const _default: {
13
13
  decodeToken(token: string): null | string | import("node_modules/@types/jsonwebtoken").JwtPayload;
14
14
  decodeTokenStrict(token: string): import("node_modules/@types/jsonwebtoken").JwtPayload;
15
15
  extractToken(sources: JWTUtils.TokenSources): string | null;
16
- rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): string;
17
- generateTokens: (payload: object, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
16
+ rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): JWTUtils.RefreshToken;
17
+ generateTokens: (payload: Record<string, unknown>, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
18
18
  parseDuration(input: string | number): number;
19
- signToken: (payload: Record<string, any>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
20
- validateTokenPayload(payload: Record<string, any>, rules?: JWTUtils.TokenRequirements): {
19
+ signToken: (payload: Record<string, unknown>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
20
+ validateTokenPayload(payload: Record<string, unknown>, rules?: JWTUtils.TokenRequirements): {
21
21
  valid: true;
22
22
  } | {
23
23
  valid: false;
@@ -25,11 +25,9 @@ declare const _default: {
25
25
  };
26
26
  isTokenExpired(payload: import("node_modules/@types/jsonwebtoken").JwtPayload): boolean;
27
27
  verifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
28
- safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => {
29
- valid: boolean;
30
- payload?: string | import("node_modules/@types/jsonwebtoken").JwtPayload;
31
- error?: unknown;
32
- };
28
+ safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => JWTUtils.VerificationResult;
29
+ verifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
30
+ safeVerifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => JWTUtils.VerificationResult;
33
31
  hashPasswordWithPepper(password: string, pepper: string): Promise<string>;
34
32
  hashPasswordWithPepperSync(password: string, pepper: string): string;
35
33
  hashPassword: (password: string, saltRounds?: number) => Promise<string>;
@@ -2,8 +2,8 @@ export interface TokenSources {
2
2
  header?: string | undefined | null;
3
3
  cookies?: Record<string, string> | undefined;
4
4
  query?: Record<string, string | undefined> | undefined;
5
- body?: Record<string, any> | undefined;
6
- wsMessage?: string | Record<string, any> | undefined;
5
+ body?: Record<string, unknown> | undefined;
6
+ wsMessage?: string | Record<string, unknown> | undefined;
7
7
  }
8
8
  /**
9
9
  * Universal token extractor
@@ -1,7 +1,4 @@
1
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;
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;
@@ -3,5 +3,6 @@ export * from "./extractToken";
3
3
  export * from "./generateTokens";
4
4
  export * from "./parseDuration";
5
5
  export * from "./signToken";
6
+ export * from "./types";
6
7
  export * from "./validateToken";
7
8
  export * from "./verify";
@@ -1,2 +1,2 @@
1
1
  import { Secret, SignOptions } from "jsonwebtoken";
2
- export declare const signToken: (payload: Record<string, any>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
2
+ export declare const signToken: (payload: Record<string, unknown>, secret: Secret, expiresIn?: string | number, options?: SignOptions) => string;
@@ -0,0 +1,22 @@
1
+ import { JwtPayload } from "jsonwebtoken";
2
+ export interface AccessTokenBrand {
3
+ readonly access: unique symbol;
4
+ }
5
+ export interface RefreshTokenBrand {
6
+ readonly refresh: unique symbol;
7
+ }
8
+ export type AccessToken = string & AccessTokenBrand;
9
+ export type RefreshToken = string & RefreshTokenBrand;
10
+ export interface TokenPair {
11
+ accessToken: AccessToken;
12
+ refreshToken: RefreshToken;
13
+ }
14
+ export interface VerificationResult<T = JwtPayload> {
15
+ valid: boolean;
16
+ payload?: T | string;
17
+ error?: Error;
18
+ }
19
+ export interface TokenValidationOptions {
20
+ ignoreExpiration?: boolean;
21
+ ignoreIssuedAt?: boolean;
22
+ }
@@ -4,7 +4,7 @@ export interface TokenRequirements {
4
4
  forbiddenFields?: string[];
5
5
  validateTypes?: Record<string, "string" | "number" | "boolean">;
6
6
  }
7
- export declare function validateTokenPayload(payload: Record<string, any>, rules?: TokenRequirements): {
7
+ export declare function validateTokenPayload(payload: Record<string, unknown>, rules?: TokenRequirements): {
8
8
  valid: true;
9
9
  } | {
10
10
  valid: false;
@@ -1,13 +1,18 @@
1
- import { Secret, JwtPayload } from "jsonwebtoken";
1
+ import jwt, { Secret, JwtPayload } from "jsonwebtoken";
2
+ import { VerificationResult } from "./types";
2
3
  /**
3
4
  * Verify token (throws if invalid or expired)
4
5
  */
5
6
  export declare const verifyToken: (token: string, secret: Secret) => string | JwtPayload;
6
7
  /**
7
- * Safe verify — never throws, returns { valid, payload?, error? }
8
+ * Safe verify — never throws, returns structured result
8
9
  */
9
- export declare const safeVerifyToken: (token: string, secret: Secret) => {
10
- valid: boolean;
11
- payload?: string | JwtPayload;
12
- error?: unknown;
13
- };
10
+ export declare const safeVerifyToken: (token: string, secret: Secret) => VerificationResult;
11
+ /**
12
+ * Verify token with validation options
13
+ */
14
+ export declare const verifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => string | JwtPayload;
15
+ /**
16
+ * Safe verify with validation options
17
+ */
18
+ export declare const safeVerifyTokenWithOptions: (token: string, secret: Secret, options?: jwt.VerifyOptions) => VerificationResult;
@@ -13,11 +13,11 @@ declare const _default: {
13
13
  decodeToken(token: string): null | string | import("node_modules/@types/jsonwebtoken").JwtPayload;
14
14
  decodeTokenStrict(token: string): import("node_modules/@types/jsonwebtoken").JwtPayload;
15
15
  extractToken(sources: JWTUtils.TokenSources): string | null;
16
- rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): string;
17
- generateTokens: (payload: object, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
16
+ rotateRefreshToken(oldToken: string, secret: import("node_modules/@types/jsonwebtoken").Secret): JWTUtils.RefreshToken;
17
+ generateTokens: (payload: Record<string, unknown>, accessSecret: import("node_modules/@types/jsonwebtoken").Secret, refreshSecret: import("node_modules/@types/jsonwebtoken").Secret, accessExpiry?: string | number, refreshExpiry?: string | number) => JWTUtils.TokenPair;
18
18
  parseDuration(input: string | number): number;
19
- signToken: (payload: Record<string, any>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
20
- validateTokenPayload(payload: Record<string, any>, rules?: JWTUtils.TokenRequirements): {
19
+ signToken: (payload: Record<string, unknown>, secret: import("node_modules/@types/jsonwebtoken").Secret, expiresIn?: string | number, options?: import("node_modules/@types/jsonwebtoken").SignOptions) => string;
20
+ validateTokenPayload(payload: Record<string, unknown>, rules?: JWTUtils.TokenRequirements): {
21
21
  valid: true;
22
22
  } | {
23
23
  valid: false;
@@ -25,11 +25,9 @@ declare const _default: {
25
25
  };
26
26
  isTokenExpired(payload: import("node_modules/@types/jsonwebtoken").JwtPayload): boolean;
27
27
  verifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
28
- safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => {
29
- valid: boolean;
30
- payload?: string | import("node_modules/@types/jsonwebtoken").JwtPayload;
31
- error?: unknown;
32
- };
28
+ safeVerifyToken: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret) => JWTUtils.VerificationResult;
29
+ verifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => string | import("node_modules/@types/jsonwebtoken").JwtPayload;
30
+ safeVerifyTokenWithOptions: (token: string, secret: import("node_modules/@types/jsonwebtoken").Secret, options?: import("node_modules/@types/jsonwebtoken").VerifyOptions) => JWTUtils.VerificationResult;
33
31
  hashPasswordWithPepper(password: string, pepper: string): Promise<string>;
34
32
  hashPasswordWithPepperSync(password: string, pepper: string): string;
35
33
  hashPassword: (password: string, saltRounds?: number) => Promise<string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naman_deep_singh/security",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Security utilities for password hashing and JWT token management with TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",