@xenterprises/fastify-xauth-jwks 1.1.1 ā 1.1.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/package.json +1 -1
- package/server/app.js +0 -370
- package/server/example-jwks.json +0 -12
- package/server/generate-demo-token.js +0 -232
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenterprises/fastify-xauth-jwks",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"description": "Fastify plugin for path-based JWT/JWKS validation. Protect multiple paths with independent JWKS providers.",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"exports": {
|
package/server/app.js
DELETED
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* xAuthJWSK Demo Server
|
|
3
|
-
*
|
|
4
|
-
* Shows path-based JWT/JWKS validation with flexible configuration:
|
|
5
|
-
* - Development: Local JWKS data (example-jwks.json)
|
|
6
|
-
* - Production: Remote JWKS URLs (via environment variables)
|
|
7
|
-
*
|
|
8
|
-
* Environment Variables:
|
|
9
|
-
* USE_LOCAL_JWKS=true - Force local JWKS (dev mode)
|
|
10
|
-
* ADMIN_JWKS_URL=https://... - Admin path JWKS endpoint
|
|
11
|
-
* PORTAL_JWKS_URL=https://... - Portal path JWKS endpoint
|
|
12
|
-
* PARTNER_JWKS_URL=https://... - Partner path JWKS endpoint
|
|
13
|
-
* PORT=3000 - Server port (default: 3000)
|
|
14
|
-
*
|
|
15
|
-
* Quick Start (Development):
|
|
16
|
-
* npm run dev
|
|
17
|
-
* node server/generate-demo-token.js admin user-123 admin
|
|
18
|
-
* curl -H "Authorization: Bearer <TOKEN>" http://localhost:3000/admin/dashboard
|
|
19
|
-
*
|
|
20
|
-
* Production Setup:
|
|
21
|
-
* export ADMIN_JWKS_URL="https://auth.example.com/.well-known/jwks.json"
|
|
22
|
-
* export PORTAL_JWKS_URL="https://auth.example.com/.well-known/jwks.json"
|
|
23
|
-
* npm start
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
import Fastify from "fastify";
|
|
27
|
-
import xAuthJWSK from "../src/xAuth.js";
|
|
28
|
-
import { extractToken, decodeToken, decodeHeader, requireRole } from "../src/utils/index.js";
|
|
29
|
-
import exampleJwks from "./example-jwks.json" assert { type: "json" };
|
|
30
|
-
|
|
31
|
-
const fastify = Fastify({
|
|
32
|
-
logger: true,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// ============================================================================
|
|
36
|
-
// Configuration Strategy
|
|
37
|
-
// ============================================================================
|
|
38
|
-
// Flexible configuration for both development and production:
|
|
39
|
-
// - Development: Use local JWKS (example-jwks.json) - no external calls
|
|
40
|
-
// - Production: Use remote JWKS URLs from environment variables
|
|
41
|
-
const useLocalJwks = process.env.USE_LOCAL_JWKS === "true" || !process.env.ADMIN_JWKS_URL;
|
|
42
|
-
|
|
43
|
-
// ============================================================================
|
|
44
|
-
// Register xAuthJWSK Plugin
|
|
45
|
-
// ============================================================================
|
|
46
|
-
// Protect multiple API paths with independent JWKS providers
|
|
47
|
-
// Each path can have different JWKS source, caching strategy, excluded paths
|
|
48
|
-
// See CONFIGURATION.md for complete reference
|
|
49
|
-
await fastify.register(xAuthJWSK, {
|
|
50
|
-
paths: {
|
|
51
|
-
// ========================================================================
|
|
52
|
-
// ADMIN API - Strict authentication (e.g., internal admin panel)
|
|
53
|
-
// ========================================================================
|
|
54
|
-
// Protected: /admin/*
|
|
55
|
-
// Excluded: /admin/health, /admin/status
|
|
56
|
-
// Use case: Internal dashboards, user management, sensitive operations
|
|
57
|
-
admin: {
|
|
58
|
-
pathPattern: "/admin",
|
|
59
|
-
// JWKS: Local OR remote (not both) - choose one
|
|
60
|
-
...(useLocalJwks
|
|
61
|
-
? { jwksData: exampleJwks } // Development: local file
|
|
62
|
-
: { jwksUrl: process.env.ADMIN_JWKS_URL || "https://example.com/admin/.well-known/jwks.json" }), // Production: env var
|
|
63
|
-
// Paths that don't require authentication (health checks, etc)
|
|
64
|
-
excludedPaths: ["/health", "/status"],
|
|
65
|
-
// Caching: Strict cache - refresh every 5 minutes
|
|
66
|
-
enablePayloadCache: true,
|
|
67
|
-
payloadCacheTTL: 300000, // 5 min token payload cache
|
|
68
|
-
jwksCacheMaxAge: 1800000, // 30 min JWKS cache (production keys rarely change)
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
// ========================================================================
|
|
72
|
-
// PORTAL API - User-facing (e.g., SaaS application)
|
|
73
|
-
// ========================================================================
|
|
74
|
-
// Protected: /portal/*
|
|
75
|
-
// Excluded: /portal/public/*, /portal/docs
|
|
76
|
-
// Use case: User dashboards, API access, profile management
|
|
77
|
-
portal: {
|
|
78
|
-
pathPattern: "/portal",
|
|
79
|
-
...(useLocalJwks
|
|
80
|
-
? { jwksData: exampleJwks }
|
|
81
|
-
: { jwksUrl: process.env.PORTAL_JWKS_URL || "https://example.com/portal/.well-known/jwks.json" }),
|
|
82
|
-
// Public endpoints (marketing pages, documentation)
|
|
83
|
-
excludedPaths: ["/public", "/docs"],
|
|
84
|
-
// Caching: Standard cache - balance performance and freshness
|
|
85
|
-
enablePayloadCache: true,
|
|
86
|
-
payloadCacheTTL: 300000, // 5 min
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
// ========================================================================
|
|
90
|
-
// PARTNER API - Integration endpoint (e.g., webhooks, B2B integrations)
|
|
91
|
-
// ========================================================================
|
|
92
|
-
// Protected: /partner/*
|
|
93
|
-
// No excluded paths - all routes require authentication
|
|
94
|
-
// Use case: Partner integrations, webhooks, third-party API access
|
|
95
|
-
partner: {
|
|
96
|
-
pathPattern: "/partner",
|
|
97
|
-
...(useLocalJwks
|
|
98
|
-
? { jwksData: exampleJwks }
|
|
99
|
-
: { jwksUrl: process.env.PARTNER_JWKS_URL || "https://example.com/partner/.well-known/jwks.json" }),
|
|
100
|
-
// All routes require authentication - no exclusions
|
|
101
|
-
// Longer cache TTL - partner tokens typically valid longer
|
|
102
|
-
enablePayloadCache: true,
|
|
103
|
-
payloadCacheTTL: 600000, // 10 min - partners have longer-lived tokens
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// ============================================================================
|
|
109
|
-
// Public Routes (No Authentication Required)
|
|
110
|
-
// ============================================================================
|
|
111
|
-
|
|
112
|
-
fastify.get("/", async () => {
|
|
113
|
-
return {
|
|
114
|
-
service: "xAuthJWSK Demo",
|
|
115
|
-
version: "1.0.0",
|
|
116
|
-
protectedPaths: Object.keys(fastify.xAuth.validators),
|
|
117
|
-
docs: "https://github.com/xenterprises/fastify-xauth-jwks",
|
|
118
|
-
};
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
fastify.get("/health", async () => {
|
|
122
|
-
return { status: "ok", timestamp: new Date().toISOString() };
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// ============================================================================
|
|
126
|
-
// Admin Routes (Protected by /admin)
|
|
127
|
-
// ============================================================================
|
|
128
|
-
|
|
129
|
-
fastify.get("/admin/health", async () => {
|
|
130
|
-
return { status: "healthy", service: "admin-api" };
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
fastify.get("/admin/status", async () => {
|
|
134
|
-
return { status: "operational", uptime: process.uptime() };
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
fastify.get("/admin/dashboard", async (request) => {
|
|
138
|
-
return {
|
|
139
|
-
message: "Admin Dashboard",
|
|
140
|
-
userId: request.auth.userId,
|
|
141
|
-
user: request.auth.payload,
|
|
142
|
-
authenticatedVia: request.auth.path,
|
|
143
|
-
};
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
fastify.get("/admin/users", async (request) => {
|
|
147
|
-
return {
|
|
148
|
-
message: "List of users",
|
|
149
|
-
adminId: request.auth.userId,
|
|
150
|
-
users: [
|
|
151
|
-
{ id: "user_1", name: "John Doe", email: "john@example.com" },
|
|
152
|
-
{ id: "user_2", name: "Jane Smith", email: "jane@example.com" },
|
|
153
|
-
],
|
|
154
|
-
};
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
fastify.get("/admin/settings", {
|
|
158
|
-
preHandler: requireRole("admin"),
|
|
159
|
-
handler: async (request) => {
|
|
160
|
-
return {
|
|
161
|
-
message: "Admin settings (admin role required)",
|
|
162
|
-
adminId: request.auth.userId,
|
|
163
|
-
roles: request.user?.roles || [],
|
|
164
|
-
};
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// Cache management endpoint
|
|
169
|
-
fastify.post("/admin/cache/clear", async (request) => {
|
|
170
|
-
const validator = fastify.xAuth.validators.admin;
|
|
171
|
-
validator.clearPayloadCache();
|
|
172
|
-
return {
|
|
173
|
-
message: "Cache cleared",
|
|
174
|
-
stats: validator.getPayloadCacheStats(),
|
|
175
|
-
};
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
fastify.get("/admin/cache/stats", async (request) => {
|
|
179
|
-
const stats = {};
|
|
180
|
-
for (const [name, validator] of Object.entries(fastify.xAuth.validators)) {
|
|
181
|
-
stats[name] = validator.getPayloadCacheStats();
|
|
182
|
-
}
|
|
183
|
-
return { cacheStats: stats };
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// ============================================================================
|
|
187
|
-
// Portal Routes (Protected by /portal)
|
|
188
|
-
// ============================================================================
|
|
189
|
-
|
|
190
|
-
fastify.get("/portal/dashboard", async (request) => {
|
|
191
|
-
return {
|
|
192
|
-
message: "Portal Dashboard",
|
|
193
|
-
userId: request.auth.userId,
|
|
194
|
-
user: request.auth.payload,
|
|
195
|
-
};
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
fastify.get("/portal/profile", async (request) => {
|
|
199
|
-
return {
|
|
200
|
-
message: "User Profile",
|
|
201
|
-
userId: request.auth.userId,
|
|
202
|
-
email: request.user?.email,
|
|
203
|
-
name: request.user?.name,
|
|
204
|
-
};
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
fastify.get("/portal/public/docs", async () => {
|
|
208
|
-
return {
|
|
209
|
-
message: "API Documentation",
|
|
210
|
-
endpoints: ["GET /portal/dashboard", "GET /portal/profile", "POST /portal/update"],
|
|
211
|
-
};
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
fastify.get("/portal/public/pricing", async () => {
|
|
215
|
-
return {
|
|
216
|
-
plans: [
|
|
217
|
-
{ tier: "free", price: 0 },
|
|
218
|
-
{ tier: "pro", price: 29 },
|
|
219
|
-
{ tier: "enterprise", price: 299 },
|
|
220
|
-
],
|
|
221
|
-
};
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
// ============================================================================
|
|
225
|
-
// Partner Routes (Protected by /partner)
|
|
226
|
-
// ============================================================================
|
|
227
|
-
|
|
228
|
-
fastify.get("/partner/api/data", async (request) => {
|
|
229
|
-
return {
|
|
230
|
-
message: "Partner API Data",
|
|
231
|
-
partnerId: request.auth.userId,
|
|
232
|
-
data: { status: "connected", lastSync: new Date().toISOString() },
|
|
233
|
-
};
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
fastify.get("/partner/api/webhooks", async (request) => {
|
|
237
|
-
return {
|
|
238
|
-
message: "Partner Webhooks",
|
|
239
|
-
partnerId: request.auth.userId,
|
|
240
|
-
webhooks: [
|
|
241
|
-
{ id: "wh_1", event: "user.created", url: "https://partner.example.com/webhooks" },
|
|
242
|
-
],
|
|
243
|
-
};
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
// ============================================================================
|
|
247
|
-
// Token Inspection Endpoints (No Auth Required - for debugging)
|
|
248
|
-
// ============================================================================
|
|
249
|
-
|
|
250
|
-
fastify.post("/debug/decode-token", async (request, reply) => {
|
|
251
|
-
const { token } = request.body;
|
|
252
|
-
|
|
253
|
-
if (!token) {
|
|
254
|
-
return reply.code(400).send({ error: "Token required" });
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
try {
|
|
258
|
-
const header = decodeHeader(token);
|
|
259
|
-
const payload = decodeToken(token);
|
|
260
|
-
|
|
261
|
-
return {
|
|
262
|
-
header,
|
|
263
|
-
payload,
|
|
264
|
-
warning: "ā ļø This is UNVERIFIED token data. Only for debugging. Do NOT trust in production.",
|
|
265
|
-
};
|
|
266
|
-
} catch (error) {
|
|
267
|
-
return reply.code(400).send({ error: "Invalid token format" });
|
|
268
|
-
}
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
fastify.post("/debug/extract-token", async (request, reply) => {
|
|
272
|
-
const authHeader = request.headers.authorization;
|
|
273
|
-
|
|
274
|
-
if (!authHeader) {
|
|
275
|
-
return reply.code(400).send({ error: "Authorization header required" });
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
const token = extractToken(request);
|
|
279
|
-
|
|
280
|
-
if (!token) {
|
|
281
|
-
return reply.code(400).send({ error: "Invalid Bearer token format" });
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
try {
|
|
285
|
-
const payload = decodeToken(token);
|
|
286
|
-
return {
|
|
287
|
-
extracted: true,
|
|
288
|
-
userId: payload.sub,
|
|
289
|
-
expiresAt: new Date(payload.exp * 1000).toISOString(),
|
|
290
|
-
payload,
|
|
291
|
-
};
|
|
292
|
-
} catch (error) {
|
|
293
|
-
return reply.code(400).send({ error: "Failed to decode token" });
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
// ============================================================================
|
|
298
|
-
// Validator Inspection Endpoint
|
|
299
|
-
// ============================================================================
|
|
300
|
-
|
|
301
|
-
fastify.get("/admin/validators", async (request) => {
|
|
302
|
-
const validators = {};
|
|
303
|
-
for (const [name, validator] of Object.entries(fastify.xAuth.validators)) {
|
|
304
|
-
validators[name] = {
|
|
305
|
-
name: validator.name,
|
|
306
|
-
pathPattern: validator.pathPattern,
|
|
307
|
-
jwksUrl: validator.jwksUrl,
|
|
308
|
-
config: validator.config,
|
|
309
|
-
cacheStats: validator.getPayloadCacheStats(),
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
return { validators };
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
// ============================================================================
|
|
316
|
-
// Server Startup
|
|
317
|
-
// ============================================================================
|
|
318
|
-
|
|
319
|
-
const start = async () => {
|
|
320
|
-
try {
|
|
321
|
-
await fastify.listen({ port: process.env.PORT || 3000, host: "0.0.0.0" });
|
|
322
|
-
|
|
323
|
-
console.log("\nš xAuthJWSK Demo Server Started!\n");
|
|
324
|
-
console.log(`Mode: ${useLocalJwks ? "š LOCAL (Development)" : "āļø REMOTE (Production)"}`);
|
|
325
|
-
if (useLocalJwks) {
|
|
326
|
-
console.log(" Using example-jwks.json - perfect for testing!");
|
|
327
|
-
console.log(" Generate test tokens: node server/generate-demo-token.js [path] [userId] [role]");
|
|
328
|
-
}
|
|
329
|
-
console.log("\nProtected Paths:");
|
|
330
|
-
for (const [name, validator] of Object.entries(fastify.xAuth.validators)) {
|
|
331
|
-
console.log(`\n š ${name.toUpperCase()}`);
|
|
332
|
-
console.log(` Path: ${validator.pathPattern}`);
|
|
333
|
-
console.log(` JWKS: ${useLocalJwks ? "local (example-jwks.json)" : validator.jwksUrl}`);
|
|
334
|
-
console.log(` Cache: ${validator.config.enablePayloadCache ? "enabled" : "disabled"}`);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
console.log("\n\nPublic Endpoints:");
|
|
338
|
-
console.log(" GET / - API info");
|
|
339
|
-
console.log(" GET /health - Health check");
|
|
340
|
-
console.log(" POST /debug/decode-token - Decode JWT (debug only)");
|
|
341
|
-
console.log(" POST /debug/extract-token - Extract token from header");
|
|
342
|
-
console.log(" GET /admin/validators - View validator configs");
|
|
343
|
-
|
|
344
|
-
console.log("\n\nProtected Endpoints (require Bearer token):");
|
|
345
|
-
console.log(" GET /admin/dashboard - Admin dashboard");
|
|
346
|
-
console.log(" GET /admin/users - List users");
|
|
347
|
-
console.log(" GET /admin/settings - Settings (requires 'admin' role)");
|
|
348
|
-
console.log(" POST /admin/cache/clear - Clear auth cache");
|
|
349
|
-
console.log(" GET /admin/cache/stats - View cache statistics");
|
|
350
|
-
console.log(" GET /portal/dashboard - Portal dashboard");
|
|
351
|
-
console.log(" GET /portal/profile - User profile");
|
|
352
|
-
console.log(" GET /partner/api/data - Partner data");
|
|
353
|
-
|
|
354
|
-
if (useLocalJwks) {
|
|
355
|
-
console.log("\n\nš§Ŗ Testing with Local JWKS:");
|
|
356
|
-
console.log(" 1. Generate a test token:");
|
|
357
|
-
console.log(" node server/generate-demo-token.js admin user-123 admin");
|
|
358
|
-
console.log(" 2. Copy the token and test a protected endpoint:");
|
|
359
|
-
console.log(" curl -H \"Authorization: Bearer <TOKEN>\" http://localhost:3000/admin/dashboard");
|
|
360
|
-
console.log(" 3. For more info, see KEYS_GENERATION.md and QUICK_START.md");
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
console.log("\nš” Tip: Add '-H \"Authorization: Bearer YOUR_TOKEN\"' to protected requests\n");
|
|
364
|
-
} catch (err) {
|
|
365
|
-
fastify.log.error(err);
|
|
366
|
-
process.exit(1);
|
|
367
|
-
}
|
|
368
|
-
};
|
|
369
|
-
|
|
370
|
-
start();
|
package/server/example-jwks.json
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"keys": [
|
|
3
|
-
{
|
|
4
|
-
"kty": "RSA",
|
|
5
|
-
"use": "sig",
|
|
6
|
-
"alg": "RS256",
|
|
7
|
-
"kid": "demo-key-admin",
|
|
8
|
-
"n": "xjlCRBqkQWeBpaMWV2E2h6L1zcqmxm0W3Z5BbMwP9jfYEJ_ZHvMdV8fYaWDV8xzGqL7Z9fQaL7bXmVzYcPz0Xq5L_VmE8V7K0L1M2N3O4P5Q6R7S8T9U0V1W2X3Y4Z5A6B7C8D9E0F1G2H3I4J5K6L7M8N9O0P1Q2R3S4T5U6V7W8X9Y0Z1A2B3C4D5E6F7G8H9I0J1K2L3M4N5O6P7Q8R9S0T1U2V3W4X5Y6Z7A8B9C0D1E2F3G4H5I6J7K8L9M0N1O2P3Q4R5S6T7U8V9W0X1Y2Z3A4B5C6D7E8F9G0H1I2J3K4L5M6N7O8P9Q0R1S2T3U4V5W6X7Y8Z9",
|
|
9
|
-
"e": "AQAB"
|
|
10
|
-
}
|
|
11
|
-
]
|
|
12
|
-
}
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate demo JWT tokens for testing xAuthJWSK
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* node generate-demo-token.js [pathName] [userId] [role]
|
|
8
|
-
*
|
|
9
|
-
* Examples:
|
|
10
|
-
* node generate-demo-token.js admin user-123 admin
|
|
11
|
-
* node generate-demo-token.js portal user-456 user
|
|
12
|
-
* node generate-demo-token.js partner partner-789
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import * as jose from 'jose';
|
|
16
|
-
|
|
17
|
-
// Demo JWKS keys - these are public keys only
|
|
18
|
-
// In production, private keys would be stored securely
|
|
19
|
-
const demoKeys = {
|
|
20
|
-
admin: {
|
|
21
|
-
kid: 'demo-key-admin',
|
|
22
|
-
// This is a demo key for testing ONLY - never use in production
|
|
23
|
-
privateKeyPem: `-----BEGIN PRIVATE KEY-----
|
|
24
|
-
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDGOUJEGqRBZ4Gl
|
|
25
|
-
oxZXYTaHovXNyqbGbRbdnkFszA/2N9gQn9ke8x1Xx9hpYNXzHMaovtn19BovttmZ
|
|
26
|
-
XNhw/PRerkv9WYTxXsrQnUjczUjczVTNzNT0xM01M1MzQzM1M9T1M9M1TzU0MzU0
|
|
27
|
-
M1MzQzMzQ0M1MzMzM1M1QzMzMzM1RDMzM1M1QzMzM1M1QzMzM1M1M1MzMzM1M1Mz
|
|
28
|
-
MzM1M1MzMzM1M1MzMzMzUzMzMzM1M1MzMzMzUzMzMzM1M1MzMzMzUzMzMzM1M1Mz
|
|
29
|
-
MzMzUzMzMzM1M1MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz
|
|
30
|
-
MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz
|
|
31
|
-
MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMz
|
|
32
|
-
AgMBAAECggEAQQECDQwVFBcWGRgbHBwdHR4eHx8gICEhISIiIiIjIyMjIyMkJCQk
|
|
33
|
-
JCQlJSUlJSUlJSYmJiYmJiYmJiYnJycnJycnJycnJycnJycnJycnJycnJycnJycnJ
|
|
34
|
-
yckJycnJycnJycoJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJyc
|
|
35
|
-
nJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
36
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
37
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
38
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
39
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
40
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
41
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
42
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
43
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
44
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
45
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
46
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
47
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
48
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
49
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
50
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
51
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
52
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
53
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
54
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
55
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
56
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
57
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
58
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
59
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
60
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
61
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
62
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
63
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
64
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
65
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
66
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
67
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
68
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
69
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
70
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
71
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
72
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
73
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
74
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
75
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
76
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
77
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
78
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
79
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
80
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
81
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
82
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
83
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
84
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
85
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
86
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
87
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
88
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
89
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
90
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
91
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
92
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
93
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
94
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
95
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
96
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
97
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
98
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
99
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
100
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
101
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
102
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
103
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
104
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
105
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
106
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
107
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
108
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
109
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
110
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
111
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
112
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
113
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
114
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
115
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
116
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
117
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
118
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
119
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
120
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
121
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
122
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
123
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
124
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
125
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
126
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
127
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
128
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
129
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
130
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
131
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
132
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
133
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
134
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
135
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
136
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
137
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
138
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
139
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
140
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
141
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
142
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
143
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
144
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
145
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
146
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
147
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
148
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
149
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
150
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
151
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
152
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
153
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
154
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
155
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
156
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
157
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
158
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
159
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
160
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
161
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
162
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
163
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
164
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
165
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
166
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
167
|
-
cnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJy
|
|
168
|
-
-----END PRIVATE KEY-----`,
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
async function generateToken() {
|
|
173
|
-
const args = process.argv.slice(2);
|
|
174
|
-
const pathName = args[0] || 'admin';
|
|
175
|
-
const userId = args[1] || 'user-' + Math.random().toString(36).substring(7);
|
|
176
|
-
const role = args[2] || 'user';
|
|
177
|
-
|
|
178
|
-
const keyConfig = demoKeys[pathName];
|
|
179
|
-
if (!keyConfig) {
|
|
180
|
-
console.error(`ā No demo key for path: ${pathName}`);
|
|
181
|
-
console.error(` Available paths: ${Object.keys(demoKeys).join(', ')}`);
|
|
182
|
-
process.exit(1);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
// Import private key
|
|
187
|
-
const privateKey = await jose.importPKCS8(
|
|
188
|
-
keyConfig.privateKeyPem,
|
|
189
|
-
'RS256'
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
// Create JWT
|
|
193
|
-
const token = await new jose.SignJWT({
|
|
194
|
-
sub: userId,
|
|
195
|
-
userId: userId,
|
|
196
|
-
name: `Test User (${pathName})`,
|
|
197
|
-
email: `${userId}@example.com`,
|
|
198
|
-
roles: [role],
|
|
199
|
-
iat: Math.floor(Date.now() / 1000),
|
|
200
|
-
exp: Math.floor(Date.now() / 1000) + 3600, // 1 hour
|
|
201
|
-
})
|
|
202
|
-
.setProtectedHeader({
|
|
203
|
-
alg: 'RS256',
|
|
204
|
-
kid: `demo-key-${pathName}`,
|
|
205
|
-
typ: 'JWT',
|
|
206
|
-
})
|
|
207
|
-
.sign(privateKey);
|
|
208
|
-
|
|
209
|
-
console.log('š« Generated Test Token:\n');
|
|
210
|
-
console.log(token);
|
|
211
|
-
console.log('\nš Token Details:');
|
|
212
|
-
console.log(` Path: ${pathName}`);
|
|
213
|
-
console.log(` User ID: ${userId}`);
|
|
214
|
-
console.log(` Role: ${role}`);
|
|
215
|
-
console.log(` Expires: 1 hour`);
|
|
216
|
-
console.log('\nš Usage Examples:\n');
|
|
217
|
-
console.log('# cURL:');
|
|
218
|
-
console.log(`curl -H "Authorization: Bearer ${token}" \\`);
|
|
219
|
-
console.log(` http://localhost:3000/${pathName}/dashboard\n`);
|
|
220
|
-
console.log('# JavaScript fetch:');
|
|
221
|
-
console.log(`fetch('http://localhost:3000/${pathName}/dashboard', {`);
|
|
222
|
-
console.log(` headers: { Authorization: 'Bearer ${token}' }`);
|
|
223
|
-
console.log(`})\n`);
|
|
224
|
-
console.log('# Decode token (for inspection):');
|
|
225
|
-
console.log(`node -e "console.log(JSON.stringify(JSON.parse(Buffer.from('${token}'.split('.')[1], 'base64').toString()), null, 2))"\n`);
|
|
226
|
-
} catch (error) {
|
|
227
|
-
console.error('ā Error generating token:', error.message);
|
|
228
|
-
process.exit(1);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
generateToken();
|