@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.
- package/README.md +8 -4
- package/dist/cjs/core/jwt/extractToken.d.ts +2 -2
- package/dist/cjs/core/jwt/extractToken.js +12 -7
- package/dist/cjs/core/jwt/generateTokens.d.ts +3 -6
- package/dist/cjs/core/jwt/generateTokens.js +10 -3
- package/dist/cjs/core/jwt/index.d.ts +1 -0
- package/dist/cjs/core/jwt/index.js +1 -0
- package/dist/cjs/core/jwt/signToken.d.ts +1 -1
- package/dist/cjs/core/jwt/types.d.ts +22 -0
- package/dist/cjs/core/jwt/types.js +2 -0
- package/dist/cjs/core/jwt/validateToken.d.ts +1 -1
- package/dist/cjs/core/jwt/verify.d.ts +12 -7
- package/dist/cjs/core/jwt/verify.js +23 -3
- package/dist/cjs/index.d.ts +7 -9
- package/dist/esm/core/jwt/extractToken.d.ts +2 -2
- package/dist/esm/core/jwt/extractToken.js +12 -7
- package/dist/esm/core/jwt/generateTokens.d.ts +3 -6
- package/dist/esm/core/jwt/generateTokens.js +10 -3
- package/dist/esm/core/jwt/index.d.ts +1 -0
- package/dist/esm/core/jwt/index.js +1 -0
- package/dist/esm/core/jwt/signToken.d.ts +1 -1
- package/dist/esm/core/jwt/types.d.ts +22 -0
- package/dist/esm/core/jwt/types.js +1 -0
- package/dist/esm/core/jwt/validateToken.d.ts +1 -1
- package/dist/esm/core/jwt/verify.d.ts +12 -7
- package/dist/esm/core/jwt/verify.js +20 -2
- package/dist/esm/index.d.ts +7 -9
- package/dist/types/core/jwt/extractToken.d.ts +2 -2
- package/dist/types/core/jwt/generateTokens.d.ts +3 -6
- package/dist/types/core/jwt/index.d.ts +1 -0
- package/dist/types/core/jwt/signToken.d.ts +1 -1
- package/dist/types/core/jwt/types.d.ts +22 -0
- package/dist/types/core/jwt/validateToken.d.ts +1 -1
- package/dist/types/core/jwt/verify.d.ts +12 -7
- package/dist/types/index.d.ts +7 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @naman_deep_singh/security
|
|
2
2
|
|
|
3
|
-
**Version:** 1.
|
|
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
|
-
|
|
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,
|
|
6
|
-
wsMessage?: string | Record<string,
|
|
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
|
-
//
|
|
37
|
-
if (typeof msg
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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:
|
|
10
|
-
refreshToken:
|
|
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
|
-
|
|
28
|
+
const newToken = (0, signToken_1.signToken)(payload, secret, "7d");
|
|
29
|
+
return newToken;
|
|
23
30
|
}
|
|
@@ -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,
|
|
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,
|
|
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
|
|
8
|
+
* Safe verify — never throws, returns structured result
|
|
8
9
|
*/
|
|
9
|
-
export declare const safeVerifyToken: (token: string, secret: Secret) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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;
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -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):
|
|
17
|
-
generateTokens: (payload:
|
|
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,
|
|
20
|
-
validateTokenPayload(payload: Record<string,
|
|
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
|
-
|
|
30
|
-
|
|
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,
|
|
6
|
-
wsMessage?: string | Record<string,
|
|
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
|
-
//
|
|
34
|
-
if (typeof msg
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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:
|
|
6
|
-
refreshToken:
|
|
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
|
-
|
|
23
|
+
const newToken = signToken(payload, secret, "7d");
|
|
24
|
+
return newToken;
|
|
18
25
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Secret, SignOptions } from "jsonwebtoken";
|
|
2
|
-
export declare const signToken: (payload: Record<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,
|
|
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
|
|
8
|
+
* Safe verify — never throws, returns structured result
|
|
8
9
|
*/
|
|
9
|
-
export declare const safeVerifyToken: (token: string, secret: Secret) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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
|
};
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -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):
|
|
17
|
-
generateTokens: (payload:
|
|
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,
|
|
20
|
-
validateTokenPayload(payload: Record<string,
|
|
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
|
-
|
|
30
|
-
|
|
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,
|
|
6
|
-
wsMessage?: string | Record<string,
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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,2 +1,2 @@
|
|
|
1
1
|
import { Secret, SignOptions } from "jsonwebtoken";
|
|
2
|
-
export declare const signToken: (payload: Record<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,
|
|
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
|
|
8
|
+
* Safe verify — never throws, returns structured result
|
|
8
9
|
*/
|
|
9
|
-
export declare const safeVerifyToken: (token: string, secret: Secret) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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):
|
|
17
|
-
generateTokens: (payload:
|
|
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,
|
|
20
|
-
validateTokenPayload(payload: Record<string,
|
|
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
|
-
|
|
30
|
-
|
|
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