@sourceregistry/node-jwt 1.0.0 → 1.1.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 +78 -20
- package/dist/promises.cjs.js +2 -0
- package/dist/promises.cjs.js.map +1 -0
- package/dist/promises.d.ts +83 -0
- package/dist/promises.es.js +23 -0
- package/dist/promises.es.js.map +1 -0
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 🔐 node-jwt
|
|
1
|
+
# 🔐 @sourceregistry/node-jwt
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@sourceregistry/node-jwt)
|
|
4
4
|
[](LICENSE)
|
|
@@ -9,11 +9,12 @@ A **minimal**, **secure**, and **production-ready** JWT (JSON Web Token) library
|
|
|
9
9
|
|
|
10
10
|
> ✨ **Why another JWT library?**
|
|
11
11
|
> Most JWT libraries are bloated, have security pitfalls, or lack proper TypeScript support. This library is:
|
|
12
|
-
> - **Tiny**
|
|
12
|
+
> - **Tiny** (~150 LOC core)
|
|
13
13
|
> - **Secure by default** (correct ECDSA/RSA encoding, time validation)
|
|
14
14
|
> - **TypeScript-first** with full JSDoc
|
|
15
15
|
> - **No external dependencies**
|
|
16
16
|
> - **100% test coverage**
|
|
17
|
+
> - **Dual API**: Sync and Promise-based
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
@@ -29,35 +30,50 @@ npm install @sourceregistry/node-jwt
|
|
|
29
30
|
|
|
30
31
|
## 🚀 Quick Start
|
|
31
32
|
|
|
32
|
-
###
|
|
33
|
+
### Sync API (default)
|
|
33
34
|
```ts
|
|
34
|
-
import { sign } from '@sourceregistry/node-jwt';
|
|
35
|
+
import { sign, verify, decode } from '@sourceregistry/node-jwt';
|
|
35
36
|
|
|
37
|
+
// Sign
|
|
36
38
|
const token = sign(
|
|
37
39
|
{ sub: '1234567890', name: 'John Doe', iat: Math.floor(Date.now() / 1000) },
|
|
38
40
|
'your-secret-key',
|
|
39
41
|
{ alg: 'HS256' }
|
|
40
42
|
);
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Verify a token
|
|
44
|
-
```ts
|
|
45
|
-
import { verify } from '@sourceregistry/node-jwt';
|
|
46
43
|
|
|
44
|
+
// Verify
|
|
47
45
|
const result = verify(token, 'your-secret-key');
|
|
48
|
-
|
|
49
46
|
if (result.valid) {
|
|
50
47
|
console.log('Payload:', result.payload);
|
|
51
48
|
} else {
|
|
52
49
|
console.error('JWT Error:', result.error.code, result.error.reason);
|
|
53
50
|
}
|
|
51
|
+
|
|
52
|
+
// Decode (unsafe)
|
|
53
|
+
const { header, payload, signature } = decode(token);
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
###
|
|
56
|
+
### Promise API (`/promises`)
|
|
57
57
|
```ts
|
|
58
|
-
import { decode } from '@sourceregistry/node-jwt';
|
|
58
|
+
import { sign, verify, decode } from '@sourceregistry/node-jwt/promises';
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
// Sign
|
|
61
|
+
const token = await sign(
|
|
62
|
+
{ sub: '1234567890', name: 'John Doe', iat: Math.floor(Date.now() / 1000) },
|
|
63
|
+
'your-secret-key',
|
|
64
|
+
{ alg: 'HS256' }
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Verify
|
|
68
|
+
try {
|
|
69
|
+
const { payload, header, signature } = await verify(token, 'your-secret-key');
|
|
70
|
+
console.log('Payload:', payload);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error('JWT Error:', error.code, error.reason);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Decode (unsafe)
|
|
76
|
+
const { header, payload, signature } = await decode(token);
|
|
61
77
|
```
|
|
62
78
|
|
|
63
79
|
---
|
|
@@ -92,6 +108,16 @@ const { header, payload, signature } = decode(token);
|
|
|
92
108
|
|
|
93
109
|
## 📚 API Reference
|
|
94
110
|
|
|
111
|
+
### Sync vs Promise API
|
|
112
|
+
|
|
113
|
+
| Operation | Sync Return | Promise Behavior |
|
|
114
|
+
|----------|-------------|------------------|
|
|
115
|
+
| `sign()` | `string` | Resolves to `string` |
|
|
116
|
+
| `decode()` | `{ header, payload, signature }` | Resolves to same object |
|
|
117
|
+
| `verify()` | `{ valid: true, ... } \| { valid: false, error }` | **Resolves** on success<br>**Rejects** with `{ reason, code }` on failure |
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
95
121
|
### `sign(payload, secret, options?)`
|
|
96
122
|
Sign a JWT.
|
|
97
123
|
|
|
@@ -102,7 +128,7 @@ Sign a JWT.
|
|
|
102
128
|
- `kid`: Key ID
|
|
103
129
|
- `typ`: Token type (default: `'JWT'`)
|
|
104
130
|
|
|
105
|
-
Returns
|
|
131
|
+
**Returns**: `string` (JWT)
|
|
106
132
|
|
|
107
133
|
---
|
|
108
134
|
|
|
@@ -115,10 +141,24 @@ Verify and validate a JWT.
|
|
|
115
141
|
- `ignoreExpiration`: Skip `exp` check (default: `false`)
|
|
116
142
|
- `clockSkew`: Tolerance in seconds for time validation (default: `0`)
|
|
117
143
|
|
|
118
|
-
|
|
144
|
+
#### Sync Usage:
|
|
119
145
|
```ts
|
|
120
|
-
|
|
121
|
-
|
|
146
|
+
const result = verify(token, secret);
|
|
147
|
+
if (result.valid) {
|
|
148
|
+
// success
|
|
149
|
+
} else {
|
|
150
|
+
// handle error: result.error
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Promise Usage:
|
|
155
|
+
```ts
|
|
156
|
+
try {
|
|
157
|
+
const { header, payload, signature } = await verify(token, secret);
|
|
158
|
+
// success
|
|
159
|
+
} catch (error) {
|
|
160
|
+
// handle error: error.reason, error.code
|
|
161
|
+
}
|
|
122
162
|
```
|
|
123
163
|
|
|
124
164
|
**Error Codes**:
|
|
@@ -137,9 +177,8 @@ Decode a JWT without verification (use with caution!).
|
|
|
137
177
|
|
|
138
178
|
- `token`: JWT string
|
|
139
179
|
|
|
140
|
-
Returns
|
|
141
|
-
|
|
142
|
-
Throws on malformed tokens.
|
|
180
|
+
**Returns**: `{ header, payload, signature }`
|
|
181
|
+
**Throws** on malformed tokens (sync) / **Rejects** (promise)
|
|
143
182
|
|
|
144
183
|
---
|
|
145
184
|
|
|
@@ -158,6 +197,20 @@ Tests include:
|
|
|
158
197
|
- Malformed token handling
|
|
159
198
|
- Signature verification
|
|
160
199
|
- Custom claims
|
|
200
|
+
- **Both sync and promise APIs**
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 📦 Exports
|
|
205
|
+
|
|
206
|
+
This package provides **two entrypoints**:
|
|
207
|
+
|
|
208
|
+
| Import | Description |
|
|
209
|
+
|-------|-------------|
|
|
210
|
+
| `@sourceregistry/node-jwt` | **Sync API** (default) |
|
|
211
|
+
| `@sourceregistry/node-jwt/promises` | **Promise-based API** |
|
|
212
|
+
|
|
213
|
+
Both include full TypeScript types and JSDoc.
|
|
161
214
|
|
|
162
215
|
---
|
|
163
216
|
|
|
@@ -169,3 +222,8 @@ PRs welcome! Please:
|
|
|
169
222
|
3. Follow existing code style
|
|
170
223
|
|
|
171
224
|
Found a security issue? [Report it responsibly](mailto:a.p.a.slaa@projectsource.nl).
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
> 🔗 **GitHub**: [github.com/SourceRegistry/node-jwt](https://github.com/SourceRegistry/node-jwt)
|
|
229
|
+
> 📦 **npm**: [@sourceregistry/node-jwt](https://www.npmjs.com/package/@sourceregistry/node-jwt)
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index.cjs.js"),s=r=>Promise.resolve().then(()=>e.decode(r)),n=(r,o,t={})=>Promise.resolve().then(()=>e.sign(r,o,t)),g=(r,o,t={})=>Promise.resolve().then(()=>{const i=e.verify(r,o,t);if(!i.valid)throw i.error;const{header:l,payload:d,signature:c}=i;return{header:l,payload:d,signature:c}}),u={sign:n,verify:g,decode:s,algorithms:e.SignatureAlgorithm};exports.SignatureAlgorithm=e.SignatureAlgorithm;exports.SupportedAlgorithms=e.SupportedAlgorithms;exports.JWT=u;exports.decode=s;exports.sign=n;exports.verify=g;
|
|
2
|
+
//# sourceMappingURL=promises.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promises.cjs.js","sources":["../src/promises.ts"],"sourcesContent":["import type { KeyLike } from 'crypto';\nimport {\n type JWT as JSONWebToken,\n decode as decodeSync,\n sign as signSync,\n verify as verifySync,\n JWTPayload,\n type SupportedAlgorithm,\n JWTHeader,\n SignatureAlgorithm\n} from './index.js';\n\nexport { type SupportedAlgorithm, SupportedAlgorithms, SignatureAlgorithm, type JWTHeader, type JWTPayload } from './index.js';\n\n/**\n * Decode a JWT string into its parts (without verification)\n */\nexport const decode = (token: string): Promise<JSONWebToken> =>\n Promise.resolve().then(() => decodeSync(token));\n\n/**\n * Sign a JWT\n */\nexport const sign = (\n payload: JWTPayload,\n secret: KeyLike,\n options: {\n alg?: SupportedAlgorithm;\n kid?: string;\n typ?: string;\n } = {}\n): Promise<string> =>\n Promise.resolve().then(() => signSync(payload, secret, options));\n\n/**\n * Verify and validate a JWT\n *\n * @throws { { reason: string; code: string } } if invalid\n */\nexport const verify = (\n token: string,\n secret: KeyLike,\n options: {\n ignoreExpiration?: boolean;\n clockSkew?: number;\n } = {}\n): Promise<{ header: JWTHeader; payload: JWTPayload; signature: string }> =>\n Promise.resolve().then(() => {\n const result = verifySync(token, secret, options);\n if (!result.valid) {\n throw result.error;\n }\n const { header, payload, signature } = result;\n return { header, payload, signature };\n });\n\nexport type JWT = JSONWebToken;\n\nexport const JWT = {\n sign,\n verify,\n decode,\n algorithms: SignatureAlgorithm\n};\n"],"names":["decode","token","decodeSync","sign","payload","secret","options","signSync","verify","result","verifySync","header","signature","JWT","SignatureAlgorithm"],"mappings":"kHAiBaA,EAAUC,GACnB,QAAQ,QAAA,EAAU,KAAK,IAAMC,EAAAA,OAAWD,CAAK,CAAC,EAKrCE,EAAO,CAChBC,EACAC,EACAC,EAII,CAAA,IAEJ,QAAQ,QAAA,EAAU,KAAK,IAAMC,EAAAA,KAASH,EAASC,EAAQC,CAAO,CAAC,EAOtDE,EAAS,CAClBP,EACAI,EACAC,EAGI,CAAA,IAEJ,QAAQ,UAAU,KAAK,IAAM,CACzB,MAAMG,EAASC,EAAAA,OAAWT,EAAOI,EAAQC,CAAO,EAChD,GAAI,CAACG,EAAO,MACR,MAAMA,EAAO,MAEjB,KAAM,CAAE,OAAAE,EAAQ,QAAAP,EAAS,UAAAQ,CAAA,EAAcH,EACvC,MAAO,CAAE,OAAAE,EAAQ,QAAAP,EAAS,UAAAQ,CAAA,CAC9B,CAAC,EAIQC,EAAM,CACf,KAAAV,EACA,OAAAK,EACA,OAAAR,EACA,WAAYc,EAAAA,kBAChB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { KeyLike } from 'crypto';
|
|
2
|
+
import { JWT as JSONWebToken, JWTPayload, SupportedAlgorithm, JWTHeader } from './index.js';
|
|
3
|
+
export { type SupportedAlgorithm, SupportedAlgorithms, SignatureAlgorithm, type JWTHeader, type JWTPayload } from './index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Decode a JWT string into its parts (without verification)
|
|
6
|
+
*/
|
|
7
|
+
export declare const decode: (token: string) => Promise<JSONWebToken>;
|
|
8
|
+
/**
|
|
9
|
+
* Sign a JWT
|
|
10
|
+
*/
|
|
11
|
+
export declare const sign: (payload: JWTPayload, secret: KeyLike, options?: {
|
|
12
|
+
alg?: SupportedAlgorithm;
|
|
13
|
+
kid?: string;
|
|
14
|
+
typ?: string;
|
|
15
|
+
}) => Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Verify and validate a JWT
|
|
18
|
+
*
|
|
19
|
+
* @throws { { reason: string; code: string } } if invalid
|
|
20
|
+
*/
|
|
21
|
+
export declare const verify: (token: string, secret: KeyLike, options?: {
|
|
22
|
+
ignoreExpiration?: boolean;
|
|
23
|
+
clockSkew?: number;
|
|
24
|
+
}) => Promise<{
|
|
25
|
+
header: JWTHeader;
|
|
26
|
+
payload: JWTPayload;
|
|
27
|
+
signature: string;
|
|
28
|
+
}>;
|
|
29
|
+
export type JWT = JSONWebToken;
|
|
30
|
+
export declare const JWT: {
|
|
31
|
+
sign: (payload: JWTPayload, secret: KeyLike, options?: {
|
|
32
|
+
alg?: SupportedAlgorithm;
|
|
33
|
+
kid?: string;
|
|
34
|
+
typ?: string;
|
|
35
|
+
}) => Promise<string>;
|
|
36
|
+
verify: (token: string, secret: KeyLike, options?: {
|
|
37
|
+
ignoreExpiration?: boolean;
|
|
38
|
+
clockSkew?: number;
|
|
39
|
+
}) => Promise<{
|
|
40
|
+
header: JWTHeader;
|
|
41
|
+
payload: JWTPayload;
|
|
42
|
+
signature: string;
|
|
43
|
+
}>;
|
|
44
|
+
decode: (token: string) => Promise<JSONWebToken>;
|
|
45
|
+
algorithms: {
|
|
46
|
+
readonly HS256: {
|
|
47
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
48
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
49
|
+
};
|
|
50
|
+
readonly HS384: {
|
|
51
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
52
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
53
|
+
};
|
|
54
|
+
readonly HS512: {
|
|
55
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
56
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
57
|
+
};
|
|
58
|
+
readonly RS256: {
|
|
59
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
60
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
61
|
+
};
|
|
62
|
+
readonly RS384: {
|
|
63
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
64
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
65
|
+
};
|
|
66
|
+
readonly RS512: {
|
|
67
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
68
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
69
|
+
};
|
|
70
|
+
readonly ES256: {
|
|
71
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
72
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
73
|
+
};
|
|
74
|
+
readonly ES384: {
|
|
75
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
76
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
77
|
+
};
|
|
78
|
+
readonly ES512: {
|
|
79
|
+
readonly sign: (data: import('crypto').BinaryLike, secret: KeyLike) => string;
|
|
80
|
+
readonly verify: (data: import('crypto').BinaryLike, secret: KeyLike, signature: string) => boolean;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SignatureAlgorithm as a, decode as d, sign as c, verify as l } from "./index.es.js";
|
|
2
|
+
import { SupportedAlgorithms as y } from "./index.es.js";
|
|
3
|
+
const m = (e) => Promise.resolve().then(() => d(e)), g = (e, r, o = {}) => Promise.resolve().then(() => c(e, r, o)), h = (e, r, o = {}) => Promise.resolve().then(() => {
|
|
4
|
+
const s = l(e, r, o);
|
|
5
|
+
if (!s.valid)
|
|
6
|
+
throw s.error;
|
|
7
|
+
const { header: t, payload: i, signature: n } = s;
|
|
8
|
+
return { header: t, payload: i, signature: n };
|
|
9
|
+
}), f = {
|
|
10
|
+
sign: g,
|
|
11
|
+
verify: h,
|
|
12
|
+
decode: m,
|
|
13
|
+
algorithms: a
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
f as JWT,
|
|
17
|
+
a as SignatureAlgorithm,
|
|
18
|
+
y as SupportedAlgorithms,
|
|
19
|
+
m as decode,
|
|
20
|
+
g as sign,
|
|
21
|
+
h as verify
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=promises.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promises.es.js","sources":["../src/promises.ts"],"sourcesContent":["import type { KeyLike } from 'crypto';\nimport {\n type JWT as JSONWebToken,\n decode as decodeSync,\n sign as signSync,\n verify as verifySync,\n JWTPayload,\n type SupportedAlgorithm,\n JWTHeader,\n SignatureAlgorithm\n} from './index.js';\n\nexport { type SupportedAlgorithm, SupportedAlgorithms, SignatureAlgorithm, type JWTHeader, type JWTPayload } from './index.js';\n\n/**\n * Decode a JWT string into its parts (without verification)\n */\nexport const decode = (token: string): Promise<JSONWebToken> =>\n Promise.resolve().then(() => decodeSync(token));\n\n/**\n * Sign a JWT\n */\nexport const sign = (\n payload: JWTPayload,\n secret: KeyLike,\n options: {\n alg?: SupportedAlgorithm;\n kid?: string;\n typ?: string;\n } = {}\n): Promise<string> =>\n Promise.resolve().then(() => signSync(payload, secret, options));\n\n/**\n * Verify and validate a JWT\n *\n * @throws { { reason: string; code: string } } if invalid\n */\nexport const verify = (\n token: string,\n secret: KeyLike,\n options: {\n ignoreExpiration?: boolean;\n clockSkew?: number;\n } = {}\n): Promise<{ header: JWTHeader; payload: JWTPayload; signature: string }> =>\n Promise.resolve().then(() => {\n const result = verifySync(token, secret, options);\n if (!result.valid) {\n throw result.error;\n }\n const { header, payload, signature } = result;\n return { header, payload, signature };\n });\n\nexport type JWT = JSONWebToken;\n\nexport const JWT = {\n sign,\n verify,\n decode,\n algorithms: SignatureAlgorithm\n};\n"],"names":["decode","token","decodeSync","sign","payload","secret","options","signSync","verify","result","verifySync","header","signature","JWT","SignatureAlgorithm"],"mappings":";;AAiBO,MAAMA,IAAS,CAACC,MACnB,QAAQ,QAAA,EAAU,KAAK,MAAMC,EAAWD,CAAK,CAAC,GAKrCE,IAAO,CAChBC,GACAC,GACAC,IAII,CAAA,MAEJ,QAAQ,QAAA,EAAU,KAAK,MAAMC,EAASH,GAASC,GAAQC,CAAO,CAAC,GAOtDE,IAAS,CAClBP,GACAI,GACAC,IAGI,CAAA,MAEJ,QAAQ,UAAU,KAAK,MAAM;AACzB,QAAMG,IAASC,EAAWT,GAAOI,GAAQC,CAAO;AAChD,MAAI,CAACG,EAAO;AACR,UAAMA,EAAO;AAEjB,QAAM,EAAE,QAAAE,GAAQ,SAAAP,GAAS,WAAAQ,EAAA,IAAcH;AACvC,SAAO,EAAE,QAAAE,GAAQ,SAAAP,GAAS,WAAAQ,EAAA;AAC9B,CAAC,GAIQC,IAAM;AAAA,EACf,MAAAV;AAAA,EACA,QAAAK;AAAA,EACA,QAAAR;AAAA,EACA,YAAYc;AAChB;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sourceregistry/node-jwt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A lightweight, zero-dependency TypeScript library for creating, verifying and decoding JSON Web Tokens (JWT).",
|
|
5
5
|
"main": "./dist/index.cjs.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.es.js",
|
|
12
12
|
"require": "./dist/index.cjs.js"
|
|
13
|
+
},
|
|
14
|
+
"./promises": {
|
|
15
|
+
"types": "./dist/promises.d.ts",
|
|
16
|
+
"import": "./dist/promises.es.js",
|
|
17
|
+
"require": "./dist/promises.cjs.js"
|
|
13
18
|
}
|
|
14
19
|
},
|
|
15
20
|
"files": [
|