secure-web-token 1.0.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 ADDED
@@ -0,0 +1,178 @@
1
+ # 🔐 Secure Web Token (Fingerprint Based)
2
+
3
+ A lightweight Node.js authentication package that allows you to **sign and verify tokens using one or more device fingerprints**.
4
+
5
+ This helps prevent token misuse across different devices.
6
+
7
+ ---
8
+
9
+ ## ✨ Features
10
+
11
+ - Supports **single or multiple fingerprints**
12
+ - Simple `sign()` and `verify()` API
13
+ - CommonJS compatible
14
+ - Editor IntelliSense support
15
+ - No heavy dependencies
16
+
17
+ ---
18
+
19
+ ## 📦 Installation
20
+
21
+ ```bash
22
+ npm install secure-web-token
23
+ ```
24
+
25
+ ---
26
+
27
+ ## 📥 Import
28
+
29
+ ```js
30
+ const { sign, verify } = require("secure-web-token");
31
+ ```
32
+
33
+ ---
34
+
35
+ ## 🧠 What is Fingerprint?
36
+
37
+ A fingerprint is any unique identifier of a device, for example:
38
+ - Browser + OS (`Chrome-Linux`)
39
+ - Device name
40
+ - IP address
41
+ - Custom string
42
+
43
+ You can pass **one or multiple fingerprints**.
44
+
45
+ ---
46
+
47
+ ## ✍️ sign()
48
+
49
+ Creates a secure token with fingerprint validation.
50
+
51
+ ### Syntax
52
+
53
+ ```js
54
+ sign(payload, secret, options)
55
+ ```
56
+
57
+ ### Parameters
58
+
59
+ | Parameter | Type | Description |
60
+ |---------|-----|-------------|
61
+ | payload | Object | Data you want inside token |
62
+ | secret | String | Secret key |
63
+ | options.expiresIn | Number | Expiry time (seconds) |
64
+ | options.fingerprint | String \| String[] | Allowed fingerprint(s) |
65
+
66
+ ---
67
+
68
+ ### Example: Single Fingerprint
69
+
70
+ ```js
71
+ const token = sign(
72
+ { userId: 1 },
73
+ "my-secret",
74
+ {
75
+ expiresIn: 60,
76
+ fingerprint: "Chrome-Linux"
77
+ }
78
+ );
79
+
80
+ console.log("TOKEN:", token);
81
+ ```
82
+
83
+ ---
84
+
85
+ ### Example: Multiple Fingerprints
86
+
87
+ ```js
88
+ const token = sign(
89
+ { userId: 1 },
90
+ "my-secret",
91
+ {
92
+ expiresIn: 60,
93
+ fingerprint: ["Chrome-Linux", "monjal"]
94
+ }
95
+ );
96
+ ```
97
+
98
+ ---
99
+
100
+ ## ✅ verify()
101
+
102
+ Verifies the token and checks whether the fingerprint is valid.
103
+
104
+ ### Syntax
105
+
106
+ ```js
107
+ verify(token, secret, options)
108
+ ```
109
+
110
+ ### Parameters
111
+
112
+ | Parameter | Type | Description |
113
+ |---------|-----|-------------|
114
+ | token | String | Token to verify |
115
+ | secret | String | Same secret used while signing |
116
+ | options.fingerprint | String \| String[] | Current device fingerprint |
117
+
118
+ ---
119
+
120
+ ### Example: Successful Verification
121
+
122
+ ```js
123
+ const payload = verify(token, "my-secret", {
124
+ fingerprint: "Chrome-Linux"
125
+ });
126
+
127
+ console.log("PAYLOAD:", payload);
128
+ ```
129
+
130
+ ---
131
+
132
+ ### Example: Multiple Fingerprints Verification
133
+
134
+ ```js
135
+ const payload = verify(token, "my-secret", {
136
+ fingerprint: ["Chrome-Linux", "monjal"]
137
+ });
138
+ ```
139
+
140
+ ---
141
+
142
+ ## ❌ Invalid Fingerprint Example
143
+
144
+ ```js
145
+ try {
146
+ verify(token, "my-secret", {
147
+ fingerprint: "Unknown-Device"
148
+ });
149
+ } catch (err) {
150
+ console.error(err.message);
151
+ }
152
+ ```
153
+
154
+ ---
155
+
156
+ ## ⏰ Token Expiry Example
157
+
158
+ ```js
159
+ const token = sign(
160
+ { role: "admin" },
161
+ "secret-key",
162
+ {
163
+ expiresIn: 5,
164
+ fingerprint: "Chrome-Linux"
165
+ }
166
+ );
167
+
168
+ // After 5 seconds
169
+ verify(token, "secret-key", {
170
+ fingerprint: "Chrome-Linux"
171
+ });
172
+ ```
173
+
174
+ ---
175
+
176
+ ## 📜 License
177
+
178
+ MIT License
@@ -0,0 +1,2 @@
1
+ export default function decrypt(encryptedPayload: string, secret: string): Record<string, any>;
2
+ //# sourceMappingURL=decrypt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../src/decrypt.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,OAAO,CAC3B,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,GACf,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA0BrB"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.default = decrypt;
37
+ const crypto = __importStar(require("crypto"));
38
+ const utils_1 = require("./utils");
39
+ function decrypt(encryptedPayload, secret) {
40
+ const data = (0, utils_1.base64urlDecode)(encryptedPayload);
41
+ const iv = data.subarray(0, 12);
42
+ const tag = data.subarray(12, 28);
43
+ const text = data.subarray(28);
44
+ const key = crypto
45
+ .createHash("sha256")
46
+ .update(secret)
47
+ .digest();
48
+ const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
49
+ decipher.setAuthTag(tag);
50
+ const decrypted = Buffer.concat([
51
+ decipher.update(text),
52
+ decipher.final(),
53
+ ]);
54
+ return JSON.parse(decrypted.toString("utf8"));
55
+ }
@@ -0,0 +1,2 @@
1
+ export default function encrypt(payload: Record<string, any>, secret: string): string;
2
+ //# sourceMappingURL=encrypt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../src/encrypt.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,OAAO,CAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,MAAM,EAAE,MAAM,GACf,MAAM,CAoBR"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.default = encrypt;
37
+ const crypto = __importStar(require("crypto"));
38
+ const utils_1 = require("./utils");
39
+ function encrypt(payload, secret) {
40
+ const iv = crypto.randomBytes(12);
41
+ const key = crypto
42
+ .createHash("sha256")
43
+ .update(secret)
44
+ .digest();
45
+ const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
46
+ const encrypted = Buffer.concat([
47
+ cipher.update(JSON.stringify(payload), "utf8"),
48
+ cipher.final(),
49
+ ]);
50
+ const tag = cipher.getAuthTag();
51
+ return (0, utils_1.base64urlEncode)(Buffer.concat([iv, tag, encrypted]));
52
+ }
@@ -0,0 +1,5 @@
1
+ export { default as sign } from "./sign";
2
+ export { default as verify } from "./verify";
3
+ export type { SignOptions } from "./sign";
4
+ export type { VerifyOptions } from "./verify";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAC;AAE7C,YAAY,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.verify = exports.sign = void 0;
7
+ var sign_1 = require("./sign");
8
+ Object.defineProperty(exports, "sign", { enumerable: true, get: function () { return __importDefault(sign_1).default; } });
9
+ var verify_1 = require("./verify");
10
+ Object.defineProperty(exports, "verify", { enumerable: true, get: function () { return __importDefault(verify_1).default; } });
package/dist/sign.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Options for signing a secure token
3
+ */
4
+ export interface SignOptions {
5
+ /**
6
+ * Token expiry time in seconds
7
+ * @default 900 (15 minutes)
8
+ */
9
+ expiresIn?: number;
10
+ /**
11
+ * One or more fingerprints allowed to use this token
12
+ * Example: device hash, IP hash, browser hash
13
+ */
14
+ fingerprint?: string | string[];
15
+ }
16
+ /**
17
+ * Creates a secure encrypted token.
18
+ *
19
+ * @param payload - Data you want to store inside the token
20
+ * @param secret - Secret key used for encryption & signature
21
+ * @param options - Optional token settings (expiry, fingerprint)
22
+ *
23
+ * @returns Encrypted and signed token string
24
+ *
25
+ * @example
26
+ * sign({ userId: 1 }, "secret", { expiresIn: 60 })
27
+ */
28
+ export default function sign(payload: Record<string, any>, secret: string, options?: SignOptions): string;
29
+ //# sourceMappingURL=sign.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACjC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,UAAU,IAAI,CAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,WAAgB,GACxB,MAAM,CA0BR"}
package/dist/sign.js ADDED
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.default = sign;
40
+ const crypto = __importStar(require("crypto"));
41
+ const encrypt_1 = __importDefault(require("./encrypt"));
42
+ const utils_1 = require("./utils");
43
+ /**
44
+ * Creates a secure encrypted token.
45
+ *
46
+ * @param payload - Data you want to store inside the token
47
+ * @param secret - Secret key used for encryption & signature
48
+ * @param options - Optional token settings (expiry, fingerprint)
49
+ *
50
+ * @returns Encrypted and signed token string
51
+ *
52
+ * @example
53
+ * sign({ userId: 1 }, "secret", { expiresIn: 60 })
54
+ */
55
+ function sign(payload, secret, options = {}) {
56
+ const header = {
57
+ alg: "AES-256-GCM+HMAC",
58
+ typ: "STK",
59
+ };
60
+ const now = Math.floor(Date.now() / 1000);
61
+ payload.iat = now;
62
+ payload.exp = now + (options.expiresIn ?? 900);
63
+ if (options.fingerprint) {
64
+ payload.fp = Array.isArray(options.fingerprint)
65
+ ? options.fingerprint
66
+ : [options.fingerprint];
67
+ }
68
+ const encodedHeader = (0, utils_1.base64urlEncode)(JSON.stringify(header));
69
+ const encryptedPayload = (0, encrypt_1.default)(payload, secret);
70
+ const dataToSign = `${encodedHeader}.${encryptedPayload}`;
71
+ const signature = crypto
72
+ .createHmac("sha256", secret)
73
+ .update(dataToSign)
74
+ .digest("base64url");
75
+ return `${dataToSign}.${signature}`;
76
+ }
@@ -0,0 +1,5 @@
1
+ export declare function base64urlEncode(input: Buffer | string): string;
2
+ export declare function base64urlDecode(input: string): Buffer;
3
+ export declare function hash(data: string | Buffer): Buffer;
4
+ export declare function timingSafeEqual(a: Buffer, b: Buffer): boolean;
5
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAG7D"}
package/dist/utils.js ADDED
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.base64urlEncode = base64urlEncode;
37
+ exports.base64urlDecode = base64urlDecode;
38
+ exports.hash = hash;
39
+ exports.timingSafeEqual = timingSafeEqual;
40
+ const crypto = __importStar(require("crypto"));
41
+ function base64urlEncode(input) {
42
+ return Buffer.from(input).toString("base64url");
43
+ }
44
+ function base64urlDecode(input) {
45
+ return Buffer.from(input, "base64url");
46
+ }
47
+ function hash(data) {
48
+ return crypto.createHash("sha256").update(data).digest();
49
+ }
50
+ function timingSafeEqual(a, b) {
51
+ if (a.length !== b.length)
52
+ return false;
53
+ return crypto.timingSafeEqual(a, b);
54
+ }
@@ -0,0 +1,5 @@
1
+ export interface VerifyOptions {
2
+ fingerprint?: string | string[];
3
+ }
4
+ export default function verify(token: string, secret: string, options?: VerifyOptions): Record<string, any>;
5
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC5B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiDrB"}
package/dist/verify.js ADDED
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.default = verify;
40
+ const crypto = __importStar(require("crypto"));
41
+ const decrypt_1 = __importDefault(require("./decrypt"));
42
+ const utils_1 = require("./utils");
43
+ function verify(token, secret, options = {}) {
44
+ const parts = token.split(".");
45
+ if (parts.length !== 3) {
46
+ throw new Error("Invalid token format");
47
+ }
48
+ const [header, encryptedPayload, signature] = parts;
49
+ const dataToVerify = `${header}.${encryptedPayload}`;
50
+ const expectedSignature = crypto
51
+ .createHmac("sha256", secret)
52
+ .update(dataToVerify)
53
+ .digest("base64url");
54
+ if (!(0, utils_1.timingSafeEqual)(Buffer.from(signature), Buffer.from(expectedSignature))) {
55
+ throw new Error("Invalid signature");
56
+ }
57
+ const payload = (0, decrypt_1.default)(encryptedPayload, secret);
58
+ const now = Math.floor(Date.now() / 1000);
59
+ if (payload.exp < now) {
60
+ throw new Error("Token expired");
61
+ }
62
+ if (options.fingerprint) {
63
+ const provided = Array.isArray(options.fingerprint)
64
+ ? options.fingerprint
65
+ : [options.fingerprint];
66
+ const stored = Array.isArray(payload.fp)
67
+ ? payload.fp
68
+ : [];
69
+ const matched = provided.some(fp => stored.includes(fp));
70
+ if (!matched) {
71
+ throw new Error("Fingerprint mismatch");
72
+ }
73
+ }
74
+ return payload;
75
+ }
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "secure-web-token",
3
+ "version": "1.0.0",
4
+ "description": "A secure web token utility",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build",
10
+ "test": "node test.js"
11
+ },
12
+ "keywords": [
13
+ "token",
14
+ "security"
15
+ ],
16
+ "author": "Znos",
17
+ "license": "MIT",
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "type": "commonjs",
22
+ "devDependencies": {
23
+ "@types/node": "^25.0.6",
24
+ "typescript": "^5.9.3"
25
+ }
26
+ }