secure-web-token 1.0.1 β†’ 1.0.2

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 CHANGED
@@ -1,18 +1,22 @@
1
- # πŸ” Secure Web Token (Fingerprint Based)
1
+ # πŸ” Secure Web Token (SWT)
2
2
 
3
- A lightweight Node.js authentication package that allows you to **sign and verify tokens using one or more device fingerprints**.
3
+ **Secure Web Token (SWT)** is a lightweight Node.js authentication package designed to make token-based authentication **more secure than traditional JWTs** by binding tokens to **device fingerprints**.
4
4
 
5
- This helps prevent token misuse across different devices.
5
+ Unlike JWTs, SWT:
6
+ - **Encrypts the payload** (can’t be decoded without the secret)
7
+ - Allows **device-level access control**
8
+ - Prevents token misuse across multiple devices
6
9
 
7
10
  ---
8
11
 
9
12
  ## ✨ Features
10
13
 
11
- - Supports **single or multiple fingerprints**
12
- - Simple `sign()` and `verify()` API
13
- - CommonJS compatible
14
- - Editor IntelliSense support
15
- - No heavy dependencies
14
+ - πŸ” Encrypted payload (AES-256-GCM)
15
+ - πŸ“± Device fingerprint support (single or multiple)
16
+ - ⏱ Token expiration
17
+ - ⚑ Lightweight & fast
18
+ - 🧠 TypeScript + IntelliSense support
19
+ - βœ… CommonJS compatible
16
20
 
17
21
  ---
18
22
 
@@ -32,144 +36,88 @@ const { sign, verify } = require("secure-web-token");
32
36
 
33
37
  ---
34
38
 
35
- ## 🧠 What is Fingerprint?
39
+ ## 🧠 What is a Fingerprint?
36
40
 
37
- A fingerprint is any unique identifier of a device, for example:
41
+ A fingerprint is any identifier that represents a device.
42
+
43
+ Examples:
38
44
  - Browser + OS (`Chrome-Linux`)
39
- - Device name
45
+ - Device ID
40
46
  - IP address
41
- - Custom string
47
+ - Any custom unique string
42
48
 
43
- You can pass **one or multiple fingerprints**.
49
+ You can allow **one or multiple fingerprints** per token.
44
50
 
45
51
  ---
46
52
 
47
53
  ## ✍️ sign()
48
54
 
49
- Creates a secure token with fingerprint validation.
55
+ Creates a secure encrypted token.
50
56
 
51
57
  ### Syntax
52
58
 
53
59
  ```js
54
- sign(payload, secret, options)
60
+ sign(data, secret, options)
55
61
  ```
56
62
 
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) |
63
+ ### Options
65
64
 
66
- ---
65
+ | Option | Type | Description |
66
+ |------|------|------------|
67
+ | expiresIn | number | Token expiry (seconds) |
68
+ | fingerprint | true \| string \| string[] | Device fingerprint(s) |
67
69
 
68
- ### Example: Single Fingerprint
70
+ ### Payload Structure
69
71
 
70
72
  ```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);
73
+ {
74
+ data: { ... },
75
+ iat: number,
76
+ exp: number,
77
+ fp: string[]
78
+ }
81
79
  ```
82
80
 
83
- ---
84
-
85
- ### Example: Multiple Fingerprints
81
+ ### Example (Auto Device ID)
86
82
 
87
83
  ```js
88
- const token = sign(
89
- { userId: 1 },
84
+ const { token, deviceId } = sign(
85
+ { userId: 1, role: "admin" },
90
86
  "my-secret",
91
- {
92
- expiresIn: 60,
93
- fingerprint: ["Chrome-Linux", "Windows"]
94
- }
87
+ { fingerprint: true }
95
88
  );
89
+
90
+ console.log(token, deviceId);
96
91
  ```
97
92
 
98
93
  ---
99
94
 
100
95
  ## βœ… verify()
101
96
 
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
97
+ Verifies token integrity, expiry, and fingerprint.
121
98
 
122
99
  ```js
123
- const payload = verify(token, "my-secret", {
124
- fingerprint: "Chrome-Linux"
125
- });
126
-
127
- console.log("PAYLOAD:", payload);
100
+ verify(token, secret, { fingerprint })
128
101
  ```
129
102
 
130
- ---
131
-
132
- ### Example: Multiple Fingerprints Verification
103
+ ### Example
133
104
 
134
105
  ```js
135
106
  const payload = verify(token, "my-secret", {
136
- fingerprint: ["Chrome-Linux", "monjal"]
107
+ fingerprint: deviceId
137
108
  });
138
- ```
139
-
140
- ---
141
-
142
- ## ❌ Invalid Fingerprint Example
143
109
 
144
- ```js
145
- try {
146
- verify(token, "my-secret", {
147
- fingerprint: "Unknown-Device"
148
- });
149
- } catch (err) {
150
- console.error(err.message);
151
- }
110
+ console.log(payload.data);
152
111
  ```
153
112
 
154
113
  ---
155
114
 
156
- ## ⏰ Token Expiry Example
115
+ ## πŸ” Use Cases
157
116
 
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
- ```
117
+ - Prevent account sharing
118
+ - Device-restricted access
119
+ - Secure SaaS authentication
120
+ - Course/content protection
173
121
 
174
122
  ---
175
123
 
package/dist/decrypt.d.ts CHANGED
@@ -1,2 +1,9 @@
1
+ /**
2
+ * Decrypts an encrypted SWT payload.
3
+ *
4
+ * @param encryptedPayload - Encrypted Base64URL payload
5
+ * @param secret - Secret key
6
+ * @returns Decrypted payload object
7
+ */
1
8
  export default function decrypt(encryptedPayload: string, secret: string): Record<string, any>;
2
9
  //# sourceMappingURL=decrypt.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../src/decrypt.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAqBrB"}
package/dist/decrypt.js CHANGED
@@ -36,6 +36,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.default = decrypt;
37
37
  const crypto = __importStar(require("crypto"));
38
38
  const utils_1 = require("./utils");
39
+ /**
40
+ * Decrypts an encrypted SWT payload.
41
+ *
42
+ * @param encryptedPayload - Encrypted Base64URL payload
43
+ * @param secret - Secret key
44
+ * @returns Decrypted payload object
45
+ */
39
46
  function decrypt(encryptedPayload, secret) {
40
47
  const data = (0, utils_1.base64urlDecode)(encryptedPayload);
41
48
  const iv = data.subarray(0, 12);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Generate a secure, random device ID.
3
+ * Used for Device Registration Model.
4
+ *
5
+ * @returns UUID v4 string
6
+ */
7
+ export declare function generateDeviceId(): string;
8
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../src/device.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
package/dist/device.js ADDED
@@ -0,0 +1,46 @@
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.generateDeviceId = generateDeviceId;
37
+ const crypto = __importStar(require("crypto"));
38
+ /**
39
+ * Generate a secure, random device ID.
40
+ * Used for Device Registration Model.
41
+ *
42
+ * @returns UUID v4 string
43
+ */
44
+ function generateDeviceId() {
45
+ return crypto.randomUUID();
46
+ }
package/dist/encrypt.d.ts CHANGED
@@ -1,2 +1,10 @@
1
+ /**
2
+ * Encrypts payload using AES-256-GCM.
3
+ * Payload is fully encrypted (unlike JWT).
4
+ *
5
+ * @param payload - Object to encrypt
6
+ * @param secret - Secret key
7
+ * @returns Encrypted Base64URL string
8
+ */
1
9
  export default function encrypt(payload: Record<string, any>, secret: string): string;
2
10
  //# sourceMappingURL=encrypt.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../src/encrypt.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,MAAM,EAAE,MAAM,GACb,MAAM,CAkBR"}
package/dist/encrypt.js CHANGED
@@ -36,6 +36,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.default = encrypt;
37
37
  const crypto = __importStar(require("crypto"));
38
38
  const utils_1 = require("./utils");
39
+ /**
40
+ * Encrypts payload using AES-256-GCM.
41
+ * Payload is fully encrypted (unlike JWT).
42
+ *
43
+ * @param payload - Object to encrypt
44
+ * @param secret - Secret key
45
+ * @returns Encrypted Base64URL string
46
+ */
39
47
  function encrypt(payload, secret) {
40
48
  const iv = crypto.randomBytes(12);
41
49
  const key = crypto
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Secure Web Token (SWT)
3
+ * Encrypted, device-bound alternative to JWT
4
+ */
1
5
  export { default as sign } from "./sign";
2
6
  export { default as verify } from "./verify";
3
7
  export type { SignOptions } from "./sign";
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,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 CHANGED
@@ -1,4 +1,8 @@
1
1
  "use strict";
2
+ /**
3
+ * Secure Web Token (SWT)
4
+ * Encrypted, device-bound alternative to JWT
5
+ */
2
6
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
7
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
8
  };
package/dist/sign.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Options for signing a secure token
2
+ * Options for signing a Secure Web Token (SWT)
3
3
  */
4
4
  export interface SignOptions {
5
5
  /**
@@ -8,22 +8,17 @@ export interface SignOptions {
8
8
  */
9
9
  expiresIn?: number;
10
10
  /**
11
- * One or more fingerprints allowed to use this token
12
- * Example: device hash, IP hash, browser hash
11
+ * true β†’ auto-generate device ID
12
+ * string | string[] β†’ custom fingerprints
13
13
  */
14
- fingerprint?: string | string[];
14
+ fingerprint?: true | string | string[];
15
15
  }
16
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 })
17
+ * Creates a Secure Web Token (SWT).
18
+ * User data is stored inside `payload.data`.
27
19
  */
28
- export default function sign(payload: Record<string, any>, secret: string, options?: SignOptions): string;
20
+ export default function sign(data: Record<string, any>, secret: string, options?: SignOptions): {
21
+ token: string;
22
+ deviceId?: string;
23
+ };
29
24
  //# sourceMappingURL=sign.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../src/sign.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,IAAI,CAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,WAAgB,GACxB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAgDtC"}
package/dist/sign.js CHANGED
@@ -40,31 +40,39 @@ exports.default = sign;
40
40
  const crypto = __importStar(require("crypto"));
41
41
  const encrypt_1 = __importDefault(require("./encrypt"));
42
42
  const utils_1 = require("./utils");
43
+ const device_1 = require("./device");
43
44
  /**
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 })
45
+ * Creates a Secure Web Token (SWT).
46
+ * User data is stored inside `payload.data`.
54
47
  */
55
- function sign(payload, secret, options = {}) {
56
- const header = {
57
- alg: "AES-256-GCM+HMAC",
58
- typ: "STK",
59
- };
48
+ function sign(data, secret, options = {}) {
49
+ if (!secret || typeof secret !== "string") {
50
+ throw new Error("Secret must be a non-empty string");
51
+ }
52
+ if (!data || typeof data !== "object") {
53
+ throw new Error("Data must be an object");
54
+ }
60
55
  const now = Math.floor(Date.now() / 1000);
61
- payload.iat = now;
62
- payload.exp = now + (options.expiresIn ?? 900);
63
- if (options.fingerprint) {
56
+ const payload = {
57
+ data, // πŸ‘ˆ user data lives here
58
+ iat: now,
59
+ exp: now + (options.expiresIn ?? 900),
60
+ };
61
+ let deviceId;
62
+ // πŸ” Device Registration Model
63
+ if (options.fingerprint === true) {
64
+ deviceId = (0, device_1.generateDeviceId)();
65
+ payload.fp = [deviceId];
66
+ }
67
+ else if (options.fingerprint) {
64
68
  payload.fp = Array.isArray(options.fingerprint)
65
69
  ? options.fingerprint
66
70
  : [options.fingerprint];
67
71
  }
72
+ const header = {
73
+ alg: "AES-256-GCM+HMAC",
74
+ typ: "SWT",
75
+ };
68
76
  const encodedHeader = (0, utils_1.base64urlEncode)(JSON.stringify(header));
69
77
  const encryptedPayload = (0, encrypt_1.default)(payload, secret);
70
78
  const dataToSign = `${encodedHeader}.${encryptedPayload}`;
@@ -72,5 +80,8 @@ function sign(payload, secret, options = {}) {
72
80
  .createHmac("sha256", secret)
73
81
  .update(dataToSign)
74
82
  .digest("base64url");
75
- return `${dataToSign}.${signature}`;
83
+ return {
84
+ token: `${dataToSign}.${signature}`,
85
+ deviceId,
86
+ };
76
87
  }
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,33 @@
1
+ /**
2
+ * Encode data into Base64URL format.
3
+ * Used to make tokens URL-safe.
4
+ *
5
+ * @param input - Buffer or string to encode
6
+ * @returns Base64URL encoded string
7
+ */
1
8
  export declare function base64urlEncode(input: Buffer | string): string;
9
+ /**
10
+ * Decode Base64URL encoded data back into Buffer.
11
+ *
12
+ * @param input - Base64URL string
13
+ * @returns Decoded Buffer
14
+ */
2
15
  export declare function base64urlDecode(input: string): Buffer;
16
+ /**
17
+ * Create a SHA-256 hash.
18
+ * Useful for hashing fingerprints or secrets.
19
+ *
20
+ * @param data - String or Buffer to hash
21
+ * @returns SHA-256 hash Buffer
22
+ */
3
23
  export declare function hash(data: string | Buffer): Buffer;
24
+ /**
25
+ * Compare two buffers in constant time.
26
+ * Prevents timing attacks.
27
+ *
28
+ * @param a - First buffer
29
+ * @param b - Second buffer
30
+ * @returns True if equal, false otherwise
31
+ */
4
32
  export declare function timingSafeEqual(a: Buffer, b: Buffer): boolean;
5
33
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAG7D"}
package/dist/utils.js CHANGED
@@ -38,15 +38,43 @@ exports.base64urlDecode = base64urlDecode;
38
38
  exports.hash = hash;
39
39
  exports.timingSafeEqual = timingSafeEqual;
40
40
  const crypto = __importStar(require("crypto"));
41
+ /**
42
+ * Encode data into Base64URL format.
43
+ * Used to make tokens URL-safe.
44
+ *
45
+ * @param input - Buffer or string to encode
46
+ * @returns Base64URL encoded string
47
+ */
41
48
  function base64urlEncode(input) {
42
49
  return Buffer.from(input).toString("base64url");
43
50
  }
51
+ /**
52
+ * Decode Base64URL encoded data back into Buffer.
53
+ *
54
+ * @param input - Base64URL string
55
+ * @returns Decoded Buffer
56
+ */
44
57
  function base64urlDecode(input) {
45
58
  return Buffer.from(input, "base64url");
46
59
  }
60
+ /**
61
+ * Create a SHA-256 hash.
62
+ * Useful for hashing fingerprints or secrets.
63
+ *
64
+ * @param data - String or Buffer to hash
65
+ * @returns SHA-256 hash Buffer
66
+ */
47
67
  function hash(data) {
48
68
  return crypto.createHash("sha256").update(data).digest();
49
69
  }
70
+ /**
71
+ * Compare two buffers in constant time.
72
+ * Prevents timing attacks.
73
+ *
74
+ * @param a - First buffer
75
+ * @param b - Second buffer
76
+ * @returns True if equal, false otherwise
77
+ */
50
78
  function timingSafeEqual(a, b) {
51
79
  if (a.length !== b.length)
52
80
  return false;
package/dist/verify.d.ts CHANGED
@@ -1,5 +1,14 @@
1
+ /**
2
+ * Options for verifying a Secure Web Token
3
+ */
1
4
  export interface VerifyOptions {
5
+ /**
6
+ * Device fingerprint(s) allowed to verify token
7
+ */
2
8
  fingerprint?: string | string[];
3
9
  }
10
+ /**
11
+ * Verifies and decrypts a Secure Web Token.
12
+ */
4
13
  export default function verify(token: string, secret: string, options?: VerifyOptions): Record<string, any>;
5
14
  //# sourceMappingURL=verify.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC1B,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAuDrB"}
package/dist/verify.js CHANGED
@@ -40,7 +40,13 @@ exports.default = verify;
40
40
  const crypto = __importStar(require("crypto"));
41
41
  const decrypt_1 = __importDefault(require("./decrypt"));
42
42
  const utils_1 = require("./utils");
43
+ /**
44
+ * Verifies and decrypts a Secure Web Token.
45
+ */
43
46
  function verify(token, secret, options = {}) {
47
+ if (!token || typeof token !== "string") {
48
+ throw new Error("Token must be a string");
49
+ }
44
50
  const parts = token.split(".");
45
51
  if (parts.length !== 3) {
46
52
  throw new Error("Invalid token format");
@@ -59,6 +65,9 @@ function verify(token, secret, options = {}) {
59
65
  if (payload.exp < now) {
60
66
  throw new Error("Token expired");
61
67
  }
68
+ if (!payload.data || typeof payload.data !== "object") {
69
+ throw new Error("Invalid payload structure");
70
+ }
62
71
  if (options.fingerprint) {
63
72
  const provided = Array.isArray(options.fingerprint)
64
73
  ? options.fingerprint
@@ -71,5 +80,5 @@ function verify(token, secret, options = {}) {
71
80
  throw new Error("Fingerprint mismatch");
72
81
  }
73
82
  }
74
- return payload;
83
+ return payload; // { data, iat, exp, fp }
75
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secure-web-token",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A secure web token utility",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",