secure-web-token 1.0.2 β 1.0.4
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 +76 -73
- package/dist/sign.d.ts +1 -1
- package/dist/sign.d.ts.map +1 -1
- package/dist/sign.js +0 -5
- package/dist/verify.d.ts +1 -1
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +3 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,126 +1,129 @@
|
|
|
1
1
|
# π Secure Web Token (SWT)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 1. About the Package
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- Prevents token misuse across multiple devices
|
|
5
|
+
**Secure Web Token (SWT)** operates on a strict **Device Registration Model**, providing a significant security upgrade over traditional JWTs. Through **AES-256-GCM encryption** and enforced **device-fingerprint binding**, SWT ensures that authentication tokens are intrinsically locked to specific devices, effectively neutralizing risks associated with token leakage and unauthorized access.
|
|
6
|
+
|
|
7
|
+
It is designed for mission-critical applications where security and strictly controlled access are paramount.
|
|
9
8
|
|
|
10
9
|
---
|
|
11
10
|
|
|
12
|
-
##
|
|
11
|
+
## 2. What Problem Does It Solve?
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
- π± Device fingerprint support (single or multiple)
|
|
16
|
-
- β± Token expiration
|
|
17
|
-
- β‘ Lightweight & fast
|
|
18
|
-
- π§ TypeScript + IntelliSense support
|
|
19
|
-
- β
CommonJS compatible
|
|
13
|
+
Traditional JWT has some well-known issues:
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
- JWT payloads are **Base64 encoded**, not encrypted
|
|
16
|
+
- Anyone can decode the payload using online tools without the secret
|
|
17
|
+
- If a token leaks, it can be reused on **any device**
|
|
18
|
+
- No built-in way to restrict tokens to a specific device
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
**Secure Web Token (SWT)** solves these problems by:
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
- Encrypting the payload using **AES-256-GCM**
|
|
23
|
+
- Making payload data **completely unreadable without the secret**
|
|
24
|
+
- Allowing tokens to be bound to **one or more device fingerprints**
|
|
25
|
+
- Preventing token reuse from unauthorized devices
|
|
26
|
+
- Supporting auto-generated device IDs for stronger protection
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
This makes SWT especially useful for:
|
|
29
|
+
- Course platforms (anti-piracy)
|
|
30
|
+
- SaaS dashboards
|
|
31
|
+
- Admin panels
|
|
32
|
+
- Device-restricted systems
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
---
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
const { sign, verify } = require("secure-web-token");
|
|
35
|
-
```
|
|
36
|
+
## 3. Available Functions
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
### `sign()`
|
|
39
|
+
Creates an encrypted and signed token.
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
**Features:**
|
|
42
|
+
- Encrypts payload
|
|
43
|
+
- Adds expiry (`iat`, `exp`)
|
|
44
|
+
- Supports device fingerprint binding
|
|
45
|
+
- Can auto-generate a device ID
|
|
40
46
|
|
|
41
|
-
|
|
47
|
+
---
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- Device ID
|
|
46
|
-
- IP address
|
|
47
|
-
- Any custom unique string
|
|
49
|
+
### `verify()`
|
|
50
|
+
Verifies and decrypts a token.
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
**Checks performed:**
|
|
53
|
+
- Token format
|
|
54
|
+
- Signature integrity
|
|
55
|
+
- Token expiry
|
|
56
|
+
- Device fingerprint validation
|
|
50
57
|
|
|
51
58
|
---
|
|
52
59
|
|
|
53
|
-
##
|
|
60
|
+
## 4. Sample Code
|
|
54
61
|
|
|
55
|
-
|
|
62
|
+
### Installation
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
```js
|
|
60
|
-
sign(data, secret, options)
|
|
64
|
+
```bash
|
|
65
|
+
npm install secure-web-token
|
|
61
66
|
```
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
| Option | Type | Description |
|
|
66
|
-
|------|------|------------|
|
|
67
|
-
| expiresIn | number | Token expiry (seconds) |
|
|
68
|
-
| fingerprint | true \| string \| string[] | Device fingerprint(s) |
|
|
68
|
+
---
|
|
69
69
|
|
|
70
|
-
###
|
|
70
|
+
### Import
|
|
71
71
|
|
|
72
72
|
```js
|
|
73
|
-
{
|
|
74
|
-
data: { ... },
|
|
75
|
-
iat: number,
|
|
76
|
-
exp: number,
|
|
77
|
-
fp: string[]
|
|
78
|
-
}
|
|
73
|
+
const { sign, verify } = require("secure-web-token");
|
|
79
74
|
```
|
|
80
75
|
|
|
81
|
-
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### Signing a Token (Auto Device Registration)
|
|
82
79
|
|
|
83
80
|
```js
|
|
81
|
+
const secret = "my-super-secret";
|
|
82
|
+
|
|
84
83
|
const { token, deviceId } = sign(
|
|
85
84
|
{ userId: 1, role: "admin" },
|
|
86
|
-
|
|
85
|
+
secret,
|
|
87
86
|
{ fingerprint: true }
|
|
88
87
|
);
|
|
89
88
|
|
|
90
|
-
console.log(
|
|
89
|
+
console.log("TOKEN:", token);
|
|
90
|
+
console.log("DEVICE ID:", deviceId);
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Verifies token integrity, expiry, and fingerprint.
|
|
95
|
+
### Verifying the Token
|
|
98
96
|
|
|
99
97
|
```js
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
console.log(payload.data);
|
|
98
|
+
try {
|
|
99
|
+
const payload = verify(token, secret, {
|
|
100
|
+
fingerprint: deviceId
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
console.log("USER DATA:", payload.data);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error("AUTH ERROR:", err.message);
|
|
106
|
+
}
|
|
111
107
|
```
|
|
112
108
|
|
|
113
109
|
---
|
|
114
110
|
|
|
115
|
-
##
|
|
111
|
+
## Payload Structure (Internal)
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
113
|
+
```js
|
|
114
|
+
{
|
|
115
|
+
data: {
|
|
116
|
+
userId: 1,
|
|
117
|
+
role: "admin"
|
|
118
|
+
},
|
|
119
|
+
iat: 1768368114,
|
|
120
|
+
exp: 1768369014,
|
|
121
|
+
fp: ["device-id"]
|
|
122
|
+
}
|
|
123
|
+
```
|
|
121
124
|
|
|
122
125
|
---
|
|
123
126
|
|
|
124
|
-
##
|
|
127
|
+
## License
|
|
125
128
|
|
|
126
129
|
MIT License
|
package/dist/sign.d.ts
CHANGED
package/dist/sign.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,CAAC;CACpB;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,CA4CtC"}
|
package/dist/sign.js
CHANGED
|
@@ -64,11 +64,6 @@ function sign(data, secret, options = {}) {
|
|
|
64
64
|
deviceId = (0, device_1.generateDeviceId)();
|
|
65
65
|
payload.fp = [deviceId];
|
|
66
66
|
}
|
|
67
|
-
else if (options.fingerprint) {
|
|
68
|
-
payload.fp = Array.isArray(options.fingerprint)
|
|
69
|
-
? options.fingerprint
|
|
70
|
-
: [options.fingerprint];
|
|
71
|
-
}
|
|
72
67
|
const header = {
|
|
73
68
|
alg: "AES-256-GCM+HMAC",
|
|
74
69
|
typ: "SWT",
|
package/dist/verify.d.ts
CHANGED
package/dist/verify.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,CAAC;CACtB;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,CAmDrB"}
|
package/dist/verify.js
CHANGED
|
@@ -69,13 +69,9 @@ function verify(token, secret, options = {}) {
|
|
|
69
69
|
throw new Error("Invalid payload structure");
|
|
70
70
|
}
|
|
71
71
|
if (options.fingerprint) {
|
|
72
|
-
const provided =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const stored = Array.isArray(payload.fp)
|
|
76
|
-
? payload.fp
|
|
77
|
-
: [];
|
|
78
|
-
const matched = provided.some(fp => stored.includes(fp));
|
|
72
|
+
const provided = options.fingerprint;
|
|
73
|
+
const stored = payload.fp;
|
|
74
|
+
const matched = provided === stored;
|
|
79
75
|
if (!matched) {
|
|
80
76
|
throw new Error("Fingerprint mismatch");
|
|
81
77
|
}
|