jwt-flow 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 +282 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/jwt/access-token.d.ts +16 -0
- package/dist/lib/jwt/access-token.d.ts.map +1 -0
- package/dist/lib/jwt/access-token.js +24 -0
- package/dist/lib/jwt/access-token.js.map +1 -0
- package/dist/lib/jwt/refresh-token.d.ts +16 -0
- package/dist/lib/jwt/refresh-token.d.ts.map +1 -0
- package/dist/lib/jwt/refresh-token.js +24 -0
- package/dist/lib/jwt/refresh-token.js.map +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# jwt-flow
|
|
2
|
+
|
|
3
|
+
**jwt-flow** is a library for Node.js that simplifies JWT token management by generating and verifying **Access** and **Refresh** tokens with customizable payloads, expiration, and algorithms — all in a single unified auth flow.
|
|
4
|
+
|
|
5
|
+
It supports **HS256** (symmetric) and **RS256** (asymmetric) signing, allowing professional-grade JWT handling for Node.js applications.
|
|
6
|
+
|
|
7
|
+
- Fully compatible with **JavaScript** and **TypeScript**
|
|
8
|
+
- TypeScript users get **strongly typed payloads** with generics
|
|
9
|
+
- Works in any Node.js project without additional configuration
|
|
10
|
+
|
|
11
|
+
## Why Use **jwt-flow**? (Value Proposition)
|
|
12
|
+
|
|
13
|
+
`jsonwebtoken` already exists, but `jwt-flow` gives you ready-to-use patterns and features that save time and reduce mistakes:
|
|
14
|
+
|
|
15
|
+
| Feature / Benefit | jwt-flow | jsonwebtoken |
|
|
16
|
+
|------------------------------------|------------|--------------|
|
|
17
|
+
| **Dual Tokens (Access + Refresh)** | ✅ Built-in | ❌ Manual setup |
|
|
18
|
+
| **TypeScript Generics / Typed Payloads** | ✅ Fully typed | ⚠️ Manual / Partial |
|
|
19
|
+
| **HS256 & RS256 Support** | ✅ Ready-to-use | ✅ Only signing, manual patterns |
|
|
20
|
+
| **Production-Ready Recommendations**| ✅ Env variables, short/long expiry, RS256 patterns | ❌ Must implement yourself |
|
|
21
|
+
| **Module Compatibility** | ✅ CommonJS + ESM | ✅ Only what you configure |
|
|
22
|
+
| **Simple & Clean API** | ✅ `auth.create()` + `auth.verify()` | ⚠️ Needs multiple calls / custom wrapper |
|
|
23
|
+
|
|
24
|
+
> **In short:** Save time, avoid boilerplate, and implement secure JWT flows instantly.
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- Generate **Access tokens** and **Refresh tokens** with a single function
|
|
29
|
+
- Support **different secrets or keys** for access & refresh tokens
|
|
30
|
+
- Fully typed with **TypeScript generics** for **payload safety**
|
|
31
|
+
- **Custom payload fields** supported
|
|
32
|
+
- Works with **HS256** and **RS256** algorithms
|
|
33
|
+
- Supports **custom expiration times**
|
|
34
|
+
|
|
35
|
+
## Module Compatibility
|
|
36
|
+
|
|
37
|
+
**jwt-flow** works in **both CommonJS and ES Module projects**:
|
|
38
|
+
|
|
39
|
+
- **CommonJS:**
|
|
40
|
+
```js
|
|
41
|
+
const { auth } = require('jwt-flow');
|
|
42
|
+
```
|
|
43
|
+
- **ES Module:**
|
|
44
|
+
```js
|
|
45
|
+
import { auth } from 'jwt-flow';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This ensures the library works seamlessly in **any Node.js project**, whether using CommonJS or ES Module syntax.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
### Note:
|
|
53
|
+
- `jsonwebtoken` is a peer dependency, so you need to install it manually.
|
|
54
|
+
- This avoids version mismatches and ensures your project uses the correct version.
|
|
55
|
+
|
|
56
|
+
### Using npm:
|
|
57
|
+
```bash
|
|
58
|
+
# Install your library
|
|
59
|
+
npm install jwt-flow
|
|
60
|
+
|
|
61
|
+
# Install jsonwebtoken (if not installed)
|
|
62
|
+
npm install jsonwebtoken
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Using Yarn:
|
|
66
|
+
```bash
|
|
67
|
+
yarn add jwt-flow
|
|
68
|
+
yarn add jsonwebtoken
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Using pnpm:
|
|
72
|
+
```bash
|
|
73
|
+
pnpm add jwt-flow
|
|
74
|
+
pnpm add jsonwebtoken
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Basic Usage (Single token)
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
import { auth } from "jwt-flow";
|
|
81
|
+
|
|
82
|
+
// Create a single access token
|
|
83
|
+
const userPayload = { sub: "123", role: "user", email: 'example@gmail.com' };
|
|
84
|
+
|
|
85
|
+
const token = auth.create({
|
|
86
|
+
accessToken: {
|
|
87
|
+
payload: userPayload,
|
|
88
|
+
secret: 'access token secret',
|
|
89
|
+
expiresIn: "15m", // Token will expire in 15 minutes
|
|
90
|
+
algorithm: "HS256" // Optional (It's default)
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
console.log(token.accessToken);
|
|
95
|
+
|
|
96
|
+
// Verify the single access token
|
|
97
|
+
if (token.accessToken) {
|
|
98
|
+
const verifiedToken = auth.verify({
|
|
99
|
+
accessToken: {
|
|
100
|
+
token: token.accessToken,
|
|
101
|
+
secret: 'access token secret'
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
console.log(verifiedToken.accessToken);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Basic Usage (Dual tokens)
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
import { auth } from "jwt-flow";
|
|
113
|
+
|
|
114
|
+
// User payload
|
|
115
|
+
const userPayload = { sub: "123", role: "user", email: 'example@gmail.com' };
|
|
116
|
+
|
|
117
|
+
// Create both access and refresh tokens
|
|
118
|
+
const tokens = auth.create({
|
|
119
|
+
accessToken: {
|
|
120
|
+
payload: userPayload,
|
|
121
|
+
secret: 'access token secret',
|
|
122
|
+
expiresIn: "15m", // Token will expire in 15 minutes
|
|
123
|
+
algorithm: "HS256" // Optional (default HS256)
|
|
124
|
+
},
|
|
125
|
+
refreshToken: {
|
|
126
|
+
payload: userPayload,
|
|
127
|
+
secret: 'refresh token secret',
|
|
128
|
+
expiresIn: "7d", // Token will expire in 7 days
|
|
129
|
+
algorithm: "HS256" // Optional (default HS256)
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
console.log(tokens.accessToken);
|
|
134
|
+
console.log(tokens.refreshToken);
|
|
135
|
+
|
|
136
|
+
// Verify both tokens
|
|
137
|
+
const verifiedTokens = auth.verify({
|
|
138
|
+
accessToken: {
|
|
139
|
+
token: tokens.accessToken!,
|
|
140
|
+
secret: 'access token secret'
|
|
141
|
+
},
|
|
142
|
+
refreshToken: {
|
|
143
|
+
token: tokens.refreshToken!,
|
|
144
|
+
secret: 'refresh token secret'
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
console.log(verifiedTokens.accessToken);
|
|
149
|
+
console.log(verifiedTokens.refreshToken);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Algorithm Notes
|
|
153
|
+
|
|
154
|
+
| Algorithm | Type | Use Case |
|
|
155
|
+
|-----------|-----------|---------------------------------------------|
|
|
156
|
+
| HS256 | Symmetric | Simple apps, single secret for sign & verify |
|
|
157
|
+
| RS256 | Asymmetric | Production APIs, private/public key pair |
|
|
158
|
+
|
|
159
|
+
- **Default algorithm:** `"HS256"`
|
|
160
|
+
- **RS256:** Requires **private key** for signing and **public key** for verification
|
|
161
|
+
|
|
162
|
+
## RS256 Example (Advanced)
|
|
163
|
+
|
|
164
|
+
### Generate RSA Keys (Manually):
|
|
165
|
+
```bash
|
|
166
|
+
openssl genrsa -out private.key 2048
|
|
167
|
+
|
|
168
|
+
openssl rsa -in private.key -pubout -out public.key
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- private.key → Used for signing tokens
|
|
172
|
+
- public.key → Used for verifying tokens
|
|
173
|
+
- ⚠️ Never commit private.key to GitHub
|
|
174
|
+
|
|
175
|
+
### Usage Example:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
import fs from "fs";
|
|
179
|
+
import { auth } from "jwt-flow";
|
|
180
|
+
|
|
181
|
+
// Load keys
|
|
182
|
+
const PRIVATE_KEY = fs.readFileSync('./private.key', 'utf-8');
|
|
183
|
+
const PUBLIC_KEY = fs.readFileSync('./public.key', 'utf-8');
|
|
184
|
+
|
|
185
|
+
const tokens = auth.create({
|
|
186
|
+
accessToken: {
|
|
187
|
+
payload: { sub: "123", role: "admin" },
|
|
188
|
+
secret: PRIVATE_KEY,
|
|
189
|
+
expiresIn: "15m",
|
|
190
|
+
algorithm: "RS256"
|
|
191
|
+
},
|
|
192
|
+
refreshToken: {
|
|
193
|
+
payload: { sub: "123", role: "admin" },
|
|
194
|
+
secret: PRIVATE_KEY,
|
|
195
|
+
expiresIn: "7d",
|
|
196
|
+
algorithm: "RS256"
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
console.log(tokens.accessToken);
|
|
201
|
+
console.log(tokens.refreshToken);
|
|
202
|
+
|
|
203
|
+
// Verify using public key
|
|
204
|
+
const verified = auth.verify({
|
|
205
|
+
accessToken: {
|
|
206
|
+
token: tokens.accessToken!,
|
|
207
|
+
secret: PUBLIC_KEY,
|
|
208
|
+
algorithms: ["RS256"]
|
|
209
|
+
},
|
|
210
|
+
refreshToken: {
|
|
211
|
+
token: tokens.refreshToken!,
|
|
212
|
+
secret: PUBLIC_KEY,
|
|
213
|
+
algorithms: ["RS256"]
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
console.log(verified.accessToken);
|
|
218
|
+
console.log(verified.refreshToken);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Production Recommendation
|
|
222
|
+
|
|
223
|
+
Instead of loading keys from files, use `environment variables` to keep your private keys secure:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const PRIVATE_KEY = process.env.PRIVATE_KEY!;
|
|
227
|
+
const PUBLIC_KEY = process.env.PUBLIC_KEY!;
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## TypeScript Generics Example
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { auth } from "jwt-flow";
|
|
234
|
+
|
|
235
|
+
// Define your payload type
|
|
236
|
+
interface UserPayload {
|
|
237
|
+
sub: string;
|
|
238
|
+
role: "user" | "admin";
|
|
239
|
+
email: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Create an access token with typed payload
|
|
243
|
+
const token = auth.create<UserPayload>({
|
|
244
|
+
accessToken: {
|
|
245
|
+
payload: {
|
|
246
|
+
sub: "123",
|
|
247
|
+
role: "admin",
|
|
248
|
+
email: "admin@example.com",
|
|
249
|
+
},
|
|
250
|
+
secret: "my-secret",
|
|
251
|
+
expiresIn: "15m" // Token will expire in 15 minutes
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
console.log(token.accessToken);
|
|
256
|
+
|
|
257
|
+
// Verify the typed token
|
|
258
|
+
const verified = auth.verify<UserPayload>({
|
|
259
|
+
accessToken: {
|
|
260
|
+
token: token.accessToken!,
|
|
261
|
+
secret: "my-secret"
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
console.log(verified.accessToken);
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Notes & Tips
|
|
269
|
+
|
|
270
|
+
- Always keep your **secrets and private keys safe**.
|
|
271
|
+
- Use **short expiration** for access tokens and **longer** for refresh tokens.
|
|
272
|
+
- For TypeScript users, the payload is **fully typed** — generics ensure type safety.
|
|
273
|
+
- `auth.create()` and `auth.verify()` are synchronous. No `async/await` needed unless you implement RS256 async methods.
|
|
274
|
+
|
|
275
|
+
## Author
|
|
276
|
+
- Sejin Ahmed – [GitHub: mern-sejin2010](https://github.com/mern-sejin2010)
|
|
277
|
+
|
|
278
|
+
## License
|
|
279
|
+
|
|
280
|
+
This package is licensed under the ISC License
|
|
281
|
+
|
|
282
|
+
Copyright © 2026, Jupiter Programmer
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Algorithm, Secret } from "jsonwebtoken";
|
|
2
|
+
import { type AccessTokenOptions, type AccessTokenPayload } from "./lib/jwt/access-token.js";
|
|
3
|
+
import { type RefreshTokenOptions, type RefreshTokenPayload } from "./lib/jwt/refresh-token.js";
|
|
4
|
+
export interface CreateTokenOptions<T extends object = {}> {
|
|
5
|
+
accessToken?: AccessTokenOptions<T>;
|
|
6
|
+
refreshToken?: RefreshTokenOptions<T>;
|
|
7
|
+
}
|
|
8
|
+
export interface VerifySingleTokenOptions {
|
|
9
|
+
token: string;
|
|
10
|
+
secret: Secret;
|
|
11
|
+
algorithms?: Algorithm[];
|
|
12
|
+
}
|
|
13
|
+
export interface VerifyTokenOptions {
|
|
14
|
+
accessToken?: VerifySingleTokenOptions;
|
|
15
|
+
refreshToken?: VerifySingleTokenOptions;
|
|
16
|
+
}
|
|
17
|
+
export interface VerifiedTokens<T extends object = {}> {
|
|
18
|
+
accessToken?: AccessTokenPayload<T> | null;
|
|
19
|
+
refreshToken?: RefreshTokenPayload<T> | null;
|
|
20
|
+
}
|
|
21
|
+
export declare const auth: {
|
|
22
|
+
create<T extends object = {}>(options: CreateTokenOptions<T>): {
|
|
23
|
+
accessToken?: string;
|
|
24
|
+
refreshToken?: string;
|
|
25
|
+
};
|
|
26
|
+
verify<T extends object = {}>(options: VerifyTokenOptions): VerifiedTokens<T>;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAGH,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGH,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAC3B,MAAM,4BAA4B,CAAC;AAGpC,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE;IACrD,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;CAC5B;AACD,MAAM,WAAW,kBAAkB;IAC/B,WAAW,CAAC,EAAE,wBAAwB,CAAC;IACvC,YAAY,CAAC,EAAE,wBAAwB,CAAC;CAC3C;AACD,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE;IACjD,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAChD;AAED,eAAO,MAAM,IAAI;WACN,CAAC,SAAS,MAAM,gBACV,kBAAkB,CAAC,CAAC,CAAC;sBAEA,MAAM;uBAAiB,MAAM;;WAWxD,CAAC,SAAS,MAAM,gBACV,kBAAkB,GAC5B,cAAc,CAAC,CAAC,CAAC;CAavB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { generateAccessToken, verifyAccessToken } from "./lib/jwt/access-token.js";
|
|
2
|
+
import { generateRefreshToken, verifyRefreshToken } from "./lib/jwt/refresh-token.js";
|
|
3
|
+
;
|
|
4
|
+
;
|
|
5
|
+
;
|
|
6
|
+
;
|
|
7
|
+
// create and verify tokens
|
|
8
|
+
export const auth = {
|
|
9
|
+
create(options) {
|
|
10
|
+
const result = {};
|
|
11
|
+
if (options.accessToken) {
|
|
12
|
+
const { payload, secret, expiresIn, algorithm } = options.accessToken;
|
|
13
|
+
result.accessToken = generateAccessToken(payload, secret, expiresIn, algorithm);
|
|
14
|
+
}
|
|
15
|
+
if (options.refreshToken) {
|
|
16
|
+
const { payload, secret, expiresIn, algorithm } = options.refreshToken;
|
|
17
|
+
result.refreshToken = generateRefreshToken(payload, secret, expiresIn, algorithm);
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
},
|
|
21
|
+
verify(options) {
|
|
22
|
+
const { accessToken, refreshToken } = options;
|
|
23
|
+
const result = {};
|
|
24
|
+
if (accessToken) {
|
|
25
|
+
const { token, secret, algorithms } = accessToken;
|
|
26
|
+
result.accessToken = verifyAccessToken(token, secret, algorithms);
|
|
27
|
+
}
|
|
28
|
+
if (refreshToken) {
|
|
29
|
+
const { token, secret, algorithms } = refreshToken;
|
|
30
|
+
result.refreshToken = verifyRefreshToken(token, secret, algorithms);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,mBAAmB,EACnB,iBAAiB,EAGpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,oBAAoB,EACpB,kBAAkB,EAGrB,MAAM,4BAA4B,CAAC;AAMnC,CAAC;AAMD,CAAC;AAID,CAAC;AAID,CAAC;AACF,2BAA2B;AAC3B,MAAM,CAAC,MAAM,IAAI,GAAG;IAChB,MAAM,CACF,OAA8B;QAE9B,MAAM,MAAM,GAAoD,EAAE,CAAC;QACnE,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;YACtE,MAAM,CAAC,WAAW,GAAG,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;YACvE,MAAM,CAAC,YAAY,GAAG,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IACD,MAAM,CACF,OAA2B;QAE3B,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;QAC9C,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,IAAI,WAAW,EAAE,CAAC;YACd,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;YAClD,MAAM,CAAC,WAAW,GAAG,iBAAiB,CAAI,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,YAAY,EAAE,CAAC;YACf,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC;YACnD,MAAM,CAAC,YAAY,GAAG,kBAAkB,CAAI,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Algorithm, type Secret } from 'jsonwebtoken';
|
|
2
|
+
export interface BaseAccessTokenPayload {
|
|
3
|
+
sub: string;
|
|
4
|
+
role?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
}
|
|
7
|
+
export type AccessTokenPayload<T extends object = {}> = BaseAccessTokenPayload & T;
|
|
8
|
+
export interface AccessTokenOptions<T extends object = {}> {
|
|
9
|
+
payload: AccessTokenPayload<T>;
|
|
10
|
+
secret: Secret;
|
|
11
|
+
expiresIn?: `${number}${"s" | "m" | "h" | "d" | "w"}`;
|
|
12
|
+
algorithm?: Algorithm;
|
|
13
|
+
}
|
|
14
|
+
export declare function generateAccessToken<T extends object = {}>(payload: AccessTokenPayload<T>, secret: Secret, expiresIn?: `${number}${"s" | "m" | "h" | "d" | "w"}`, algorithm?: Algorithm): string;
|
|
15
|
+
export declare function verifyAccessToken<T extends object = {}>(token: string, secret: Secret, algorithms?: Algorithm[]): AccessTokenPayload<T> | null;
|
|
16
|
+
//# sourceMappingURL=access-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-token.d.ts","sourceRoot":"","sources":["../../../src/lib/jwt/access-token.ts"],"names":[],"mappings":"AAAA,OAAY,EACR,KAAK,SAAS,EACd,KAAK,MAAM,EAEd,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,sBAAsB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,IAAI,sBAAsB,GAAG,CAAC,CAAC;AAEnF,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE;IACrD,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC;IACtD,SAAS,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EACrD,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAU,EAC5D,SAAS,GAAE,SAAmB,GAC/B,MAAM,CAGR;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EACnD,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,SAAS,EAAc,GACpC,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAU9B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import jwt, {} from 'jsonwebtoken';
|
|
2
|
+
;
|
|
3
|
+
;
|
|
4
|
+
// generate access token
|
|
5
|
+
export function generateAccessToken(payload, secret, expiresIn = '15m', algorithm = 'HS256') {
|
|
6
|
+
const options = { expiresIn, algorithm };
|
|
7
|
+
return jwt.sign(payload, secret, options);
|
|
8
|
+
}
|
|
9
|
+
;
|
|
10
|
+
// verify access token
|
|
11
|
+
export function verifyAccessToken(token, secret, algorithms = ['HS256']) {
|
|
12
|
+
try {
|
|
13
|
+
const decoded = jwt.verify(token, secret, { algorithms });
|
|
14
|
+
if (typeof decoded === 'object' && decoded !== null) {
|
|
15
|
+
return decoded;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
;
|
|
24
|
+
//# sourceMappingURL=access-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access-token.js","sourceRoot":"","sources":["../../../src/lib/jwt/access-token.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,EAAE,EAIX,MAAM,cAAc,CAAC;AAMrB,CAAC;AAQD,CAAC;AACF,wBAAwB;AACxB,MAAM,UAAU,mBAAmB,CAC/B,OAA8B,EAC9B,MAAc,EACd,YAAuD,KAAK,EAC5D,YAAuB,OAAO;IAE9B,MAAM,OAAO,GAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IACtD,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAAA,CAAC;AACF,sBAAsB;AACtB,MAAM,UAAU,iBAAiB,CAC7B,KAAa,EACb,MAAc,EACd,aAA0B,CAAC,OAAO,CAAC;IAEnC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QAC1D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,OAAgC,CAAC;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAAA,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Algorithm, type Secret } from 'jsonwebtoken';
|
|
2
|
+
export interface BaseRefreshTokenPayload {
|
|
3
|
+
sub: string;
|
|
4
|
+
role?: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
}
|
|
7
|
+
export type RefreshTokenPayload<T extends object = {}> = BaseRefreshTokenPayload & T;
|
|
8
|
+
export interface RefreshTokenOptions<T extends object = {}> {
|
|
9
|
+
payload: RefreshTokenPayload<T>;
|
|
10
|
+
secret: Secret;
|
|
11
|
+
expiresIn?: `${number}${"s" | "m" | "h" | "d" | "w"}`;
|
|
12
|
+
algorithm?: Algorithm;
|
|
13
|
+
}
|
|
14
|
+
export declare function generateRefreshToken<T extends object = {}>(payload: RefreshTokenPayload<T>, secret: Secret, expiresIn?: `${number}${"s" | "m" | "h" | "d" | "w"}`, algorithm?: Algorithm): string;
|
|
15
|
+
export declare function verifyRefreshToken<T extends object = {}>(token: string, secret: Secret, algorithms?: Algorithm[]): RefreshTokenPayload<T> | null;
|
|
16
|
+
//# sourceMappingURL=refresh-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-token.d.ts","sourceRoot":"","sources":["../../../src/lib/jwt/refresh-token.ts"],"names":[],"mappings":"AAAA,OAAY,EACR,KAAK,SAAS,EACd,KAAK,MAAM,EAEd,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,uBAAuB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,IAAI,uBAAuB,GAAG,CAAC,CAAC;AAErF,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE;IACtD,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC;IACtD,SAAS,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EACtD,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAC/B,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAS,EAC3D,SAAS,GAAE,SAAmB,GAC/B,MAAM,CAGR;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,EACpD,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,SAAS,EAAc,GACpC,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAU/B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import jwt, {} from 'jsonwebtoken';
|
|
2
|
+
;
|
|
3
|
+
;
|
|
4
|
+
// generate refresh token
|
|
5
|
+
export function generateRefreshToken(payload, secret, expiresIn = '7d', algorithm = 'HS256') {
|
|
6
|
+
const options = { expiresIn, algorithm };
|
|
7
|
+
return jwt.sign(payload, secret, options);
|
|
8
|
+
}
|
|
9
|
+
;
|
|
10
|
+
// verify refresh token
|
|
11
|
+
export function verifyRefreshToken(token, secret, algorithms = ['HS256']) {
|
|
12
|
+
try {
|
|
13
|
+
const decoded = jwt.verify(token, secret, { algorithms });
|
|
14
|
+
if (typeof decoded === 'object' && decoded !== null) {
|
|
15
|
+
return decoded;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
;
|
|
24
|
+
//# sourceMappingURL=refresh-token.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-token.js","sourceRoot":"","sources":["../../../src/lib/jwt/refresh-token.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,EAAE,EAIX,MAAM,cAAc,CAAC;AAMrB,CAAC;AAQD,CAAC;AACF,yBAAyB;AACzB,MAAM,UAAU,oBAAoB,CAChC,OAA+B,EAC/B,MAAc,EACd,YAAuD,IAAI,EAC3D,YAAuB,OAAO;IAE9B,MAAM,OAAO,GAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;IACtD,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAAA,CAAC;AACF,uBAAuB;AACvB,MAAM,UAAU,kBAAkB,CAC9B,KAAa,EACb,MAAc,EACd,aAA0B,CAAC,OAAO,CAAC;IAEnC,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QAC1D,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,OAAiC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC;AAAA,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jwt-flow",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "jwt-flow is a library for Node.js that simplifies JWT token management by generating and verifying **Access** and **Refresh** tokens with customizable payloads, expiration, and algorithms — all in a single unified auth flow.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
10
|
+
},
|
|
11
|
+
"files": ["dist", "README.md"],
|
|
12
|
+
"keywords": [
|
|
13
|
+
"jwt",
|
|
14
|
+
"typescript",
|
|
15
|
+
"jsonwebtoken",
|
|
16
|
+
"ts-jwt",
|
|
17
|
+
"access token",
|
|
18
|
+
"refresh token",
|
|
19
|
+
"jwt helper",
|
|
20
|
+
"jwt manager",
|
|
21
|
+
"auth",
|
|
22
|
+
"authentication",
|
|
23
|
+
"auth flow",
|
|
24
|
+
"single auth",
|
|
25
|
+
"jwt rotation",
|
|
26
|
+
"security",
|
|
27
|
+
"secure jwt",
|
|
28
|
+
"token generation",
|
|
29
|
+
"token verification",
|
|
30
|
+
"jwt utils",
|
|
31
|
+
"typescript auth",
|
|
32
|
+
"typescript authentication",
|
|
33
|
+
"jwt library",
|
|
34
|
+
"jwt typescript",
|
|
35
|
+
"jwt access",
|
|
36
|
+
"jwt refresh",
|
|
37
|
+
"jwt create",
|
|
38
|
+
"jwt verify",
|
|
39
|
+
"jwt ts helper",
|
|
40
|
+
"node jwt",
|
|
41
|
+
"nodejs jwt",
|
|
42
|
+
"secure tokens",
|
|
43
|
+
"auth library",
|
|
44
|
+
"token manager",
|
|
45
|
+
"jwt workflow",
|
|
46
|
+
"jwt system",
|
|
47
|
+
"jwt solution"
|
|
48
|
+
],
|
|
49
|
+
"author": "Sejin Ahmed",
|
|
50
|
+
"license": "ISC",
|
|
51
|
+
"type": "module",
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "https://github.com/mern-sejin2010/npm-jwt-flow.git"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
58
|
+
"@types/node": "^25.3.0",
|
|
59
|
+
"jsonwebtoken": "^9.0.3",
|
|
60
|
+
"ts-node": "^10.9.2",
|
|
61
|
+
"typescript": "^5.9.3"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"jsonwebtoken": "^9.0.0"
|
|
65
|
+
}
|
|
66
|
+
}
|