@nitrotool/jwt 0.0.9 → 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,12 +1,13 @@
1
1
  # @nitrotool/jwt
2
2
 
3
- Lightweight JWT utilities for Nitro/UnJS environments with optional h3 helpers.
3
+ Lightweight JWT utilities for Nuxt/Nitro/UnJS environments **with built-in h3 helpers**.
4
4
 
5
5
  - Built on `@tsndr/cloudflare-worker-jwt`
6
6
  - Helpers that read `jwtSecret` from your Nitro runtime config
7
- - h3 utilities to extract tokens from requests and enforce authentication
7
+ - Batteries included with h3 utilities to extract tokens from requests and enforce authentication
8
+
9
+ Learn more about JWT and how it works:
8
10
 
9
- Learn more about JWT and how it works here:
10
11
  - [What is a JWT?](https://www.jwt.io/introduction#what-is-json-web-token)
11
12
  - [JWT.io](https://jwt.io/)
12
13
 
@@ -20,66 +21,129 @@ pnpm install @nitrotool/jwt
20
21
  npm install @nitrotool/jwt
21
22
  ```
22
23
 
23
- Peer dependency:
24
- - `h3` is required.
24
+ Required peer dependency:
25
+
26
+ - `h3` (this package expects `h3` to be present)
27
+
28
+ ## Nuxt setup
29
+
30
+ ```ts
31
+ export default defineNuxtConfig({
32
+ modules: ['@nitrotool/jwt'],
33
+ //You can also
34
+ jwt: {
35
+ //default secret (only use this locally, and override it in prod)
36
+ secret: 'some-random-secret-yes-it-is-not-very-secure',
37
+ // Alternatively also available as NUXT_JWT_SECRET env var
38
+ },
39
+ });
40
+
41
+ ```
42
+
43
+ ### Usage with Nuxt 3/4
44
+
45
+ > This is available all places where auto-imported can be used on the server-side.
46
+
47
+ ```ts
48
+ type MyClaims = { tenantId: string };
49
+
50
+ const token = await encodeJwt<MyClaims>({tenantId: '123', sub: '123'});
51
+
52
+ // Later…
53
+ const isValid = await verifyJwt(token);
54
+ const payload = await decodeJwt<MyClaims>(token);
55
+
56
+
57
+ // or
58
+ export default defineEventHandler(async (event) => {
59
+ const jwt = await requireJwt(event);
60
+ // you now have access to a required JWT token via Authorization bearer header.
61
+ })
62
+
63
+ ```
25
64
 
26
65
  ## Importing
27
66
 
28
- You can import from the main entry or subpath exports:
67
+ Import from the main entry or subpaths:
68
+
69
+ ```ts
70
+ // Node-only helpers
71
+ import {encodeJwtRaw, verifyJwtRaw, decodeJwtRaw} from '@nitrotool/jwt/core';
72
+
73
+ // h3-only helpers
74
+ import {extractApiToken, requireApiToken} from '@nitrotool/jwt/h3';
75
+ ```
76
+
77
+ ## Quick Start Nitro
78
+
79
+ ### 1. Create plugin to load secret.
29
80
 
30
81
  ```ts
31
- // Main (all helpers)
32
- import { encodeJwt, verifyJwt, decodeJwt } from '@nitrotool/jwt';
82
+ // plugins/0.jwt.ts
83
+ import { defineNitroPlugin, useRuntimeConfig } from 'nitropack/runtime';
84
+ import { configureJwtRuntime } from '@nitrotool/jwt';
33
85
 
34
- // Subpath (JWT-only)
35
- import { encodeJwtRaw, verifyJwtRaw, decodeJwtRaw } from '@nitrotool/jwt/core';
86
+ export default defineNitroPlugin(() => {
87
+ configureJwtRuntime(() => useRuntimeConfig() as any);
88
+ });
36
89
 
37
- // Subpath (h3 helpers)
38
- import { extractApiToken, requireApiToken } from '@nitrotool/jwt/h3';
39
90
  ```
40
91
 
41
- ## Quick Start
92
+ ### 2. Basic usage
42
93
 
43
94
  ```ts
44
- import { encodeJwt, verifyJwt, decodeJwt } from '@nitrotool/jwt';
95
+ import {encodeJwt, verifyJwt, decodeJwt} from '@nitrotool/jwt';
96
+
97
+ type MyClaims = { tenantId: string };
45
98
 
46
- type MyClaims = { userId: string };
99
+ const token = await encodeJwt<MyClaims>({tenantId: '123', sub: '123'});
47
100
 
48
- const token = await encodeJwt<MyClaims>({ userId: '123' });
49
101
  // Later…
50
102
  const isValid = await verifyJwt(token);
51
- const payload = await decodeJwt<MyClaims>(token); // { userId: '123', exp: ... }
103
+ const payload = await decodeJwt<MyClaims>(token); // { sub: '123', tenantId: '123', exp: ... }
52
104
  ```
53
105
 
54
106
  By default, non-`Raw` helpers read the secret from your runtime config:
107
+
55
108
  - `useRuntimeConfig().jwtSecret`
56
109
 
57
110
  If you need to pass a secret explicitly, use the `*Raw` variants.
58
111
 
59
- ## Usage with h3
112
+ ### 3. In a route handler
60
113
 
61
114
  Extract API tokens and enforce authentication in request handlers:
62
115
 
116
+ #### Require a JWT token
117
+ ```ts
118
+ import {defineEventHandler} from 'h3';
119
+ import {requireJwt} from '@nitrotool/jwt';
120
+
121
+ export default defineEventHandler(async (event) => {
122
+ const decodedJwt = await requireJwt(event)
123
+ })
124
+ ```
125
+
126
+ #### Extract a JWT token manually
63
127
  ```ts
64
128
  import { defineEventHandler } from 'h3';
65
- import { extractApiToken, requireApiToken } from '@nitrotool/jwt/h3';
66
- import { decodeJwt } from '@nitrotool/jwt';
129
+ import { extractApiToken, requireApiToken, decodeJwt } from '@nitrotool/jwt';
67
130
 
68
131
  export default defineEventHandler(async (event) => {
69
- // Try to read token (Authorization: Bearer <token> or ?token=<token>)
70
- const token = extractApiToken(event);
132
+ // Try to read token (Authorization: Bearer <token> or ?<queryKey>=<token>)
133
+ const token = extractApiToken(event, {queryKey: 'token'}); // queryKey defaults to 'token'
71
134
 
72
- // Or strictly require it (throws UnauthenticatedError if missing)
73
- const requiredToken = requireApiToken(event);
135
+ // Or strictly require it (throws UnauthenticatedError if missing)
136
+ const requiredToken = requireApiToken(event);
74
137
 
75
- // Optionally decode/verify
76
- const claims = await decodeJwt<{ userId: string }>(requiredToken);
138
+ // Optionally decode/verify
139
+ const claims = await decodeJwt<{ userId: string }>(requiredToken);
77
140
 
78
- return { ok: true, userId: claims.userId };
141
+ return { ok: true, userId: claims.userId };
79
142
  });
80
143
  ```
81
144
 
82
145
  Supported token locations:
146
+
83
147
  - Authorization header: `Authorization: Bearer <token>`
84
148
  - Query string: `?token=<token>`
85
149
 
@@ -88,11 +152,11 @@ Supported token locations:
88
152
  When using non-`Raw` helpers, ensure a secret is available at runtime:
89
153
 
90
154
  ```ts
91
- // Example: Nuxt/Nitro runtime config
155
+ // nuxt.config.ts (Nuxt/Nitro runtime config)
92
156
  export default defineNuxtConfig({
93
- runtimeConfig: {
94
- jwtSecret: process.env.JWT_SECRET || 'super-secret',
95
- },
157
+ runtimeConfig: {
158
+ jwtSecret: 'some-random-secret-yes-it-is-not-very-secure',
159
+ },
96
160
  });
97
161
  ```
98
162
 
@@ -101,27 +165,27 @@ export default defineNuxtConfig({
101
165
  Sign with custom TTL:
102
166
 
103
167
  ```ts
104
- import { encodeJwtRaw } from '@nitrotool/jwt';
168
+ import {encodeJwtRaw} from '@nitrotool/jwt';
105
169
 
106
170
  const token = await encodeJwtRaw(
107
- { userId: '123', role: 'admin' },
108
- process.env.JWT_SECRET!,
109
- 60 * 10 // 10 minutes
171
+ {userId: '123', role: 'admin'},
172
+ process.env.JWT_SECRET!,
173
+ 60 * 10 // 10 minutes
110
174
  );
111
175
  ```
112
176
 
113
177
  Decode without verifying signature (use only for non-sensitive scenarios):
114
178
 
115
179
  ```ts
116
- import { decodeJwt } from '@nitrotool/jwt';
180
+ import {decodeJwt} from '@nitrotool/jwt';
117
181
 
118
- const payload = await decodeJwt<{ userId: string }>(token, { verify: false });
182
+ const payload = await decodeJwt<{ userId: string }>(token, {verify: false});
119
183
  ```
120
184
 
121
185
  Verify with an explicit secret:
122
186
 
123
187
  ```ts
124
- import { verifyJwtRaw } from '@nitrotool/jwt';
188
+ import {verifyJwtRaw} from '@nitrotool/jwt';
125
189
 
126
190
  const ok = await verifyJwtRaw(token, process.env.JWT_SECRET!);
127
191
  ```
@@ -147,9 +211,9 @@ All helpers are asynchronous.
147
211
  - `encodeJwtRaw<T>(payload, secret, ttl = 60): Promise<string>`
148
212
  - Signs a token with the provided `secret`.
149
213
  - `ttl` is in seconds. Default: `60`.
150
- - `exp` is set automatically from `ttl`.
214
+ - `exp` is set **automagically** from `ttl`.
151
215
 
152
- - `encodeJwt<T>(payload): Promise<string>`
216
+ - `encodeJwt<T>(payload, ttl = 60): Promise<string>`
153
217
  - Same as `encodeJwtRaw`, but uses `useRuntimeConfig().jwtSecret`.
154
218
 
155
219
  - `verifyJwtRaw(token, secret): Promise<boolean>`
@@ -168,9 +232,10 @@ All helpers are asynchronous.
168
232
  - Throws `UnauthorizedError('Invalid JWT token.')` if verification fails.
169
233
 
170
234
  Types:
235
+
171
236
  - `ExtendableJwtPayload<T>` lets you define custom claims merged with standard JWT claims.
172
237
 
173
- ### h3 helpers
238
+ ### h3 helpers (required)
174
239
 
175
240
  - `extractBearerToken(event): string | undefined`
176
241
  - Reads `Authorization` header and returns the token without `Bearer `.
@@ -184,7 +249,6 @@ Types:
184
249
  - `requireApiToken(event): string`
185
250
  - Same as `extractApiToken`, but throws `UnauthenticatedError` if missing.
186
251
 
187
-
188
252
  ## License
189
253
 
190
- MIT
254
+ MIT
@@ -0,0 +1,11 @@
1
+ import { JwtPayload } from '@tsndr/cloudflare-worker-jwt';
2
+
3
+ type ExtendableJwtPayload<T extends Record<string, any> = {}> = Partial<JwtPayload> & T;
4
+ declare const encodeJwtRaw: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>, secret: string, ttlSec?: number) => Promise<string>;
5
+ declare const verifyJwtRaw: (token: string, secret: string) => Promise<boolean>;
6
+ declare const decodeJwtRaw: <T extends Record<string, any> = {}>(token: string, secret: string, opts?: {
7
+ verify?: boolean;
8
+ }) => Promise<ExtendableJwtPayload<T>>;
9
+
10
+ export { decodeJwtRaw, encodeJwtRaw, verifyJwtRaw };
11
+ export type { ExtendableJwtPayload };
@@ -0,0 +1,11 @@
1
+ import { JwtPayload } from '@tsndr/cloudflare-worker-jwt';
2
+
3
+ type ExtendableJwtPayload<T extends Record<string, any> = {}> = Partial<JwtPayload> & T;
4
+ declare const encodeJwtRaw: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>, secret: string, ttlSec?: number) => Promise<string>;
5
+ declare const verifyJwtRaw: (token: string, secret: string) => Promise<boolean>;
6
+ declare const decodeJwtRaw: <T extends Record<string, any> = {}>(token: string, secret: string, opts?: {
7
+ verify?: boolean;
8
+ }) => Promise<ExtendableJwtPayload<T>>;
9
+
10
+ export { decodeJwtRaw, encodeJwtRaw, verifyJwtRaw };
11
+ export type { ExtendableJwtPayload };
@@ -0,0 +1,26 @@
1
+ import jwt from '@tsndr/cloudflare-worker-jwt';
2
+ import { UnauthorizedError } from '@nitrotool/errors';
3
+
4
+ const encodeJwtRaw = async (payload, secret, ttlSec = 60) => {
5
+ return jwt.sign(
6
+ { exp: Math.floor(Date.now() / 1e3) + ttlSec, ...payload },
7
+ secret
8
+ );
9
+ };
10
+ const verifyJwtRaw = async (token, secret) => {
11
+ return new Promise(async (resolve) => {
12
+ if (await jwt.verify(token, secret, { throwError: false })) {
13
+ return resolve(true);
14
+ }
15
+ return resolve(false);
16
+ });
17
+ };
18
+ const decodeJwtRaw = async (token, secret, opts = { verify: true }) => {
19
+ if (opts.verify) {
20
+ const ok = await verifyJwtRaw(token, secret);
21
+ if (!ok) throw UnauthorizedError("Invalid JWT token.");
22
+ }
23
+ return jwt.decode(token).payload;
24
+ };
25
+
26
+ export { decodeJwtRaw, encodeJwtRaw, verifyJwtRaw };
@@ -1,8 +1,10 @@
1
1
  import { H3Event } from 'h3';
2
2
 
3
- declare const extractBearerToken: (event: H3Event) => string;
3
+ declare const extractBearerToken: (event: H3Event) => string | undefined;
4
4
  declare const extractQueryToken: (event: H3Event, key?: string) => string | undefined;
5
- declare const extractApiToken: (event: H3Event) => string | undefined;
5
+ declare const extractApiToken: (event: H3Event, opts?: {
6
+ queryKey: string;
7
+ }) => string | undefined;
6
8
  declare const requireApiToken: (event: H3Event) => string;
7
9
 
8
10
  export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken };
@@ -1,8 +1,10 @@
1
1
  import { H3Event } from 'h3';
2
2
 
3
- declare const extractBearerToken: (event: H3Event) => string;
3
+ declare const extractBearerToken: (event: H3Event) => string | undefined;
4
4
  declare const extractQueryToken: (event: H3Event, key?: string) => string | undefined;
5
- declare const extractApiToken: (event: H3Event) => string | undefined;
5
+ declare const extractApiToken: (event: H3Event, opts?: {
6
+ queryKey: string;
7
+ }) => string | undefined;
6
8
  declare const requireApiToken: (event: H3Event) => string;
7
9
 
8
10
  export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken };
@@ -1,9 +1,15 @@
1
- import { getRequestHeader, getQuery } from 'h3';
1
+ import { getQuery, getHeader } from 'h3';
2
2
  import { UnauthenticatedError } from '@nitrotool/errors';
3
3
 
4
- const extractBearerToken = (event) => getRequestHeader(event, "Authorization")?.replace("Bearer ", "") || void 0;
4
+ const extractBearerToken = (event) => {
5
+ const auth = getHeader(event, "authorization");
6
+ if (!auth?.startsWith("Bearer ")) {
7
+ return void 0;
8
+ }
9
+ return auth.slice(7);
10
+ };
5
11
  const extractQueryToken = (event, key = "token") => getQuery(event)?.[key] || void 0;
6
- const extractApiToken = (event) => extractBearerToken(event) || extractQueryToken(event);
12
+ const extractApiToken = (event, opts = { queryKey: "token" }) => extractBearerToken(event) || extractQueryToken(event, opts.queryKey);
7
13
  const requireApiToken = (event) => {
8
14
  const token = extractApiToken(event);
9
15
  if (!token) {
package/dist/index.d.mts CHANGED
@@ -1,4 +1,10 @@
1
- export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken } from './h3.mjs';
2
- export { ExtendableJwtPayload, decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw } from './jwt.mjs';
3
- import 'h3';
1
+ export { configureJwtRuntime, decodeJwt, encodeJwt, getJwtSecret, verifyJwt } from './runtime/server/index.mjs';
2
+ export { requireApiToken } from './h3/index.mjs';
3
+ import { H3Event } from 'h3';
4
+ import './core/index.mjs';
4
5
  import '@tsndr/cloudflare-worker-jwt';
6
+ import 'nitropack/types';
7
+
8
+ declare const requireJwt: <T extends Record<string, any> = {}>(event: H3Event) => Promise<any>;
9
+
10
+ export { requireJwt };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,10 @@
1
- export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken } from './h3.js';
2
- export { ExtendableJwtPayload, decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw } from './jwt.js';
3
- import 'h3';
1
+ export { configureJwtRuntime, decodeJwt, encodeJwt, getJwtSecret, verifyJwt } from './runtime/server/index.js';
2
+ export { requireApiToken } from './h3/index.js';
3
+ import { H3Event } from 'h3';
4
+ import './core/index.js';
4
5
  import '@tsndr/cloudflare-worker-jwt';
6
+ import 'nitropack/types';
7
+
8
+ declare const requireJwt: <T extends Record<string, any> = {}>(event: H3Event) => Promise<any>;
9
+
10
+ export { requireJwt };
package/dist/index.mjs CHANGED
@@ -1,5 +1,8 @@
1
- export { extractApiToken, extractBearerToken, extractQueryToken, requireApiToken } from './h3.mjs';
2
- export { decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw } from './jwt.mjs';
3
- import 'h3';
4
- import '@nitrotool/errors';
1
+ export { r as requireJwt } from './shared/jwt.Cd03UmUN.mjs';
2
+ export { decodeJwt, encodeJwt, verifyJwt } from './runtime/server/index.mjs';
3
+ export { requireApiToken } from './h3/index.mjs';
4
+ export { c as configureJwtRuntime, g as getJwtSecret } from './shared/jwt.ftBB7-nW.mjs';
5
+ import './core/index.mjs';
5
6
  import '@tsndr/cloudflare-worker-jwt';
7
+ import '@nitrotool/errors';
8
+ import 'h3';
@@ -0,0 +1,9 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ secret?: string;
5
+ }
6
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
7
+
8
+ export { _default as default };
9
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ secret?: string;
5
+ }
6
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
7
+
8
+ export { _default as default };
9
+ export type { ModuleOptions };
@@ -0,0 +1,72 @@
1
+ import fs from 'node:fs';
2
+ import { defineNuxtModule, createResolver, addServerScanDir, addServerPlugin, addServerTemplate } from '@nuxt/kit';
3
+ import { consola } from 'consola';
4
+ import { join } from 'pathe';
5
+
6
+ const version = "1.0.2";
7
+
8
+ async function getFilesInDirectory(dir) {
9
+ const files = await fs.promises.readdir(dir);
10
+ const filePaths = [];
11
+ for (const file of files) {
12
+ const fullPath = join(dir, file);
13
+ const stat = await fs.promises.stat(fullPath);
14
+ if (stat.isFile()) {
15
+ filePaths.push(fullPath);
16
+ }
17
+ }
18
+ return filePaths;
19
+ }
20
+ async function getFilesInDirectoryRecursive(dir) {
21
+ const files = await fs.promises.readdir(dir);
22
+ const filePaths = [];
23
+ for (const file of files) {
24
+ const fullPath = join(dir, file);
25
+ const stat = await fs.promises.stat(fullPath);
26
+ if (stat.isFile()) {
27
+ filePaths.push(fullPath);
28
+ } else if (stat.isDirectory()) {
29
+ const subdirectoryFiles = await getFilesInDirectory(fullPath);
30
+ filePaths.push(...subdirectoryFiles);
31
+ }
32
+ }
33
+ return filePaths;
34
+ }
35
+
36
+ const module = defineNuxtModule({
37
+ meta: {
38
+ name: "@nitrotool/jwt",
39
+ configKey: "jwt",
40
+ version
41
+ },
42
+ async setup(options, nuxt) {
43
+ const logger = consola.withTag("jwt");
44
+ const resolver = createResolver(import.meta.url);
45
+ if (nuxt.options._prepare) {
46
+ logger.debug("Skipping module init due to nuxt.options._prepare = true");
47
+ return;
48
+ }
49
+ if (nuxt.options.runtimeConfig.jwtSecret) {
50
+ options.secret = nuxt.options.runtimeConfig.jwtSecret;
51
+ }
52
+ addServerScanDir([resolver.resolve("./runtime/server/nitro")]);
53
+ addServerPlugin(resolver.resolve("./runtime/server/nitro/plugin"));
54
+ const runtimeFiles = await getFilesInDirectoryRecursive(
55
+ resolver.resolve("./runtime/server")
56
+ );
57
+ for (const file of runtimeFiles) {
58
+ const relativeName = file.replace(
59
+ resolver.resolve("./runtime/server"),
60
+ ""
61
+ );
62
+ logger.debug(`Adding server template: ${relativeName}`);
63
+ addServerTemplate({
64
+ filename: relativeName,
65
+ getContents: () => fs.readFileSync(file, "utf-8")
66
+ });
67
+ }
68
+ nuxt.options.runtimeConfig.jwtSecret = options.secret;
69
+ }
70
+ });
71
+
72
+ export { module as default };
@@ -0,0 +1,17 @@
1
+ import { ExtendableJwtPayload } from '../../core/index.mjs';
2
+ import { NitroRuntimeConfig } from 'nitropack/types';
3
+ import '@tsndr/cloudflare-worker-jwt';
4
+
5
+ type JwtRuntimeConfig = NitroRuntimeConfig & {
6
+ jwtSecret?: string;
7
+ };
8
+ declare const configureJwtRuntime: (getter: () => JwtRuntimeConfig) => void;
9
+ declare const getJwtSecret: () => string;
10
+
11
+ declare const encodeJwt: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>, ttlSec?: number) => Promise<any>;
12
+ declare const verifyJwt: (token: string) => Promise<any>;
13
+ declare const decodeJwt: <T extends Record<string, any> = {}>(token: string, opts?: {
14
+ verify?: boolean;
15
+ }) => Promise<ExtendableJwtPayload<T>>;
16
+
17
+ export { ExtendableJwtPayload, configureJwtRuntime, decodeJwt, encodeJwt, getJwtSecret, verifyJwt };
@@ -0,0 +1,17 @@
1
+ import { ExtendableJwtPayload } from '../../core/index.js';
2
+ import { NitroRuntimeConfig } from 'nitropack/types';
3
+ import '@tsndr/cloudflare-worker-jwt';
4
+
5
+ type JwtRuntimeConfig = NitroRuntimeConfig & {
6
+ jwtSecret?: string;
7
+ };
8
+ declare const configureJwtRuntime: (getter: () => JwtRuntimeConfig) => void;
9
+ declare const getJwtSecret: () => string;
10
+
11
+ declare const encodeJwt: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>, ttlSec?: number) => Promise<any>;
12
+ declare const verifyJwt: (token: string) => Promise<any>;
13
+ declare const decodeJwt: <T extends Record<string, any> = {}>(token: string, opts?: {
14
+ verify?: boolean;
15
+ }) => Promise<ExtendableJwtPayload<T>>;
16
+
17
+ export { ExtendableJwtPayload, configureJwtRuntime, decodeJwt, encodeJwt, getJwtSecret, verifyJwt };
@@ -0,0 +1,17 @@
1
+ import { g as getJwtSecret } from '../../shared/jwt.ftBB7-nW.mjs';
2
+ export { c as configureJwtRuntime } from '../../shared/jwt.ftBB7-nW.mjs';
3
+ import { encodeJwtRaw, decodeJwtRaw, verifyJwtRaw } from '../../core/index.mjs';
4
+ import '@tsndr/cloudflare-worker-jwt';
5
+ import '@nitrotool/errors';
6
+
7
+ const encodeJwt = async (payload, ttlSec = 60) => {
8
+ return encodeJwtRaw(payload, getJwtSecret(), ttlSec);
9
+ };
10
+ const verifyJwt = async (token) => {
11
+ return verifyJwtRaw(token, getJwtSecret());
12
+ };
13
+ const decodeJwt = async (token, opts = { verify: true }) => {
14
+ return decodeJwtRaw(token, getJwtSecret(), opts);
15
+ };
16
+
17
+ export { decodeJwt, encodeJwt, getJwtSecret, verifyJwt };
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+
3
+ export { _default as default };
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+
3
+ export { _default as default };
@@ -0,0 +1,10 @@
1
+ import { defineNitroPlugin, useRuntimeConfig } from 'nitropack/runtime';
2
+ import { c as configureJwtRuntime } from '../../../shared/jwt.ftBB7-nW.mjs';
3
+ import '@tsndr/cloudflare-worker-jwt';
4
+ import '@nitrotool/errors';
5
+
6
+ const plugin = defineNitroPlugin(() => {
7
+ configureJwtRuntime(() => useRuntimeConfig());
8
+ });
9
+
10
+ export { plugin as default };
@@ -0,0 +1,7 @@
1
+ export { requireJwt } from '../../../../index.mjs';
2
+ export { configureJwtRuntime, decodeJwt, encodeJwt, getJwtSecret, verifyJwt } from '../../index.mjs';
3
+ export { requireApiToken } from '../../../../h3/index.mjs';
4
+ import 'h3';
5
+ import '../../../../core/index.mjs';
6
+ import '@tsndr/cloudflare-worker-jwt';
7
+ import 'nitropack/types';
@@ -0,0 +1,7 @@
1
+ export { requireJwt } from '../../../../index.js';
2
+ export { configureJwtRuntime, decodeJwt, encodeJwt, getJwtSecret, verifyJwt } from '../../index.js';
3
+ export { requireApiToken } from '../../../../h3/index.js';
4
+ import 'h3';
5
+ import '../../../../core/index.js';
6
+ import '@tsndr/cloudflare-worker-jwt';
7
+ import 'nitropack/types';
@@ -0,0 +1,8 @@
1
+ export { r as requireJwt } from '../../../../shared/jwt.Cd03UmUN.mjs';
2
+ export { decodeJwt, encodeJwt, verifyJwt } from '../../index.mjs';
3
+ export { requireApiToken } from '../../../../h3/index.mjs';
4
+ export { c as configureJwtRuntime, g as getJwtSecret } from '../../../../shared/jwt.ftBB7-nW.mjs';
5
+ import '../../../../core/index.mjs';
6
+ import '@tsndr/cloudflare-worker-jwt';
7
+ import '@nitrotool/errors';
8
+ import 'h3';
@@ -0,0 +1,8 @@
1
+ import { decodeJwt } from '../runtime/server/index.mjs';
2
+ import { requireApiToken } from '../h3/index.mjs';
3
+
4
+ const requireJwt = async (event) => {
5
+ return decodeJwt(requireApiToken(event));
6
+ };
7
+
8
+ export { requireJwt as r };
@@ -0,0 +1,14 @@
1
+ let getRuntimeConfig = () => ({});
2
+ const configureJwtRuntime = (getter) => {
3
+ getRuntimeConfig = getter;
4
+ };
5
+ const getJwtSecret = () => {
6
+ const cfg = getRuntimeConfig();
7
+ if (cfg?.jwtSecret) return cfg.jwtSecret;
8
+ if (process?.env?.JWT_SECRET) return process.env.JWT_SECRET;
9
+ throw new Error(
10
+ "jwtSecret is not configured. configure using NUXT_JWT_SECRET or jwt.secret"
11
+ );
12
+ };
13
+
14
+ export { configureJwtRuntime as c, getJwtSecret as g };
package/package.json CHANGED
@@ -1,17 +1,35 @@
1
1
  {
2
2
  "name": "@nitrotool/jwt",
3
- "version": "0.0.9",
4
- "main": "dist/index.mjs",
3
+ "version": "1.0.2",
5
4
  "type": "module",
5
+ "main": "dist/index.mjs",
6
+ "types": "./dist/index.d.ts",
6
7
  "exports": {
7
- ".": "./dist/index.mjs",
8
- "./core": "./dist/jwt.mjs",
9
- "./h3": "./dist/h3.mjs"
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs"
11
+ },
12
+ "./module": {
13
+ "types": "./dist/module.d.ts",
14
+ "import": "./dist/module.mjs"
15
+ },
16
+ "./core": {
17
+ "types": "./dist/core/index.d.ts",
18
+ "import": "./dist/core/index.mjs"
19
+ },
20
+ "./h3": {
21
+ "types": "./dist/h3/index.d.ts",
22
+ "import": "./dist/h3/index.mjs"
23
+ }
10
24
  },
11
- "types": "./dist/index.d.ts",
12
25
  "dependencies": {
13
26
  "@tsndr/cloudflare-worker-jwt": "^3.2.0",
14
- "@nitrotool/errors": "0.0.9"
27
+ "@nitrotool/errors": "1.0.2",
28
+ "@nuxt/kit": "latest",
29
+ "pathe": "^2.0.3",
30
+ "@nuxt/schema": "^4.2.2",
31
+ "consola": "^3.4.2",
32
+ "nitropack": "^2.13.1"
15
33
  },
16
34
  "peerDependencies": {
17
35
  "h3": "^1.15.3"
@@ -19,6 +37,19 @@
19
37
  "devDependencies": {
20
38
  "unbuild": "^3.5.0"
21
39
  },
40
+ "unbuild": {
41
+ "entries": [
42
+ "src/index",
43
+ "src/module",
44
+ "src/core/index",
45
+ "src/h3/index",
46
+ "src/runtime/server/index",
47
+ "src/runtime/server/nitro/plugin",
48
+ "src/runtime/server/nitro/utils/index"
49
+ ],
50
+ "declaration": true,
51
+ "clean": true
52
+ },
22
53
  "scripts": {
23
54
  "build": "unbuild ."
24
55
  }
package/dist/jwt.d.mts DELETED
@@ -1,16 +0,0 @@
1
- import { JwtPayload } from '@tsndr/cloudflare-worker-jwt';
2
-
3
- type ExtendableJwtPayload<T extends Record<string, any> = {}> = Partial<JwtPayload> & T;
4
- declare const encodeJwtRaw: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>, secret: string, ttl?: number) => Promise<string>;
5
- declare const encodeJwt: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>) => Promise<string>;
6
- declare const verifyJwtRaw: (token: string, secret: string) => Promise<boolean>;
7
- declare const verifyJwt: (token: string) => Promise<boolean>;
8
- declare const decodeJwtRaw: <T extends Record<string, any> = {}>(token: string, secret: string, { verify }?: {
9
- verify?: boolean;
10
- }) => Promise<ExtendableJwtPayload<T>>;
11
- declare const decodeJwt: <T extends Record<string, any> = {}>(token: string, { verify }?: {
12
- verify?: boolean;
13
- }) => Promise<ExtendableJwtPayload<T>>;
14
-
15
- export { decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw };
16
- export type { ExtendableJwtPayload };
package/dist/jwt.d.ts DELETED
@@ -1,16 +0,0 @@
1
- import { JwtPayload } from '@tsndr/cloudflare-worker-jwt';
2
-
3
- type ExtendableJwtPayload<T extends Record<string, any> = {}> = Partial<JwtPayload> & T;
4
- declare const encodeJwtRaw: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>, secret: string, ttl?: number) => Promise<string>;
5
- declare const encodeJwt: <T extends Record<string, any> = {}>(payload: ExtendableJwtPayload<T>) => Promise<string>;
6
- declare const verifyJwtRaw: (token: string, secret: string) => Promise<boolean>;
7
- declare const verifyJwt: (token: string) => Promise<boolean>;
8
- declare const decodeJwtRaw: <T extends Record<string, any> = {}>(token: string, secret: string, { verify }?: {
9
- verify?: boolean;
10
- }) => Promise<ExtendableJwtPayload<T>>;
11
- declare const decodeJwt: <T extends Record<string, any> = {}>(token: string, { verify }?: {
12
- verify?: boolean;
13
- }) => Promise<ExtendableJwtPayload<T>>;
14
-
15
- export { decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw };
16
- export type { ExtendableJwtPayload };
package/dist/jwt.mjs DELETED
@@ -1,52 +0,0 @@
1
- import jwt from '@tsndr/cloudflare-worker-jwt';
2
- import { UnauthorizedError } from '@nitrotool/errors';
3
-
4
- const encodeJwtRaw = async (payload, secret, ttl = 60) => {
5
- return await jwt.sign(
6
- {
7
- exp: Date.now() / 1e3 + ttl,
8
- ...payload
9
- },
10
- secret
11
- );
12
- };
13
- const encodeJwt = async (payload) => {
14
- const secret = (
15
- //@ts-expect-error Expected.
16
- typeof useRuntimeConfig === "function" ? useRuntimeConfig()?.jwtSecret : ""
17
- );
18
- return encodeJwtRaw(payload, secret);
19
- };
20
- const verifyJwtRaw = async (token, secret) => {
21
- return new Promise(async (resolve) => {
22
- if (await jwt.verify(token, secret, { throwError: false })) {
23
- return resolve(true);
24
- }
25
- return resolve(false);
26
- });
27
- };
28
- const verifyJwt = async (token) => {
29
- const secret = (
30
- //@ts-expect-error Expected.
31
- typeof useRuntimeConfig === "function" ? useRuntimeConfig()?.jwtSecret : ""
32
- );
33
- return verifyJwtRaw(token, secret);
34
- };
35
- const decodeJwtRaw = async (token, secret, { verify } = { verify: true }) => {
36
- if (!secret && verify)
37
- throw new Error("Cannot check signature without secret.");
38
- if (secret && verify && !await verifyJwtRaw(token, secret)) {
39
- throw UnauthorizedError("Invalid JWT token.");
40
- }
41
- const { payload } = jwt.decode(token);
42
- return payload;
43
- };
44
- const decodeJwt = async (token, { verify } = { verify: true }) => {
45
- if (verify && !await verifyJwt(token)) {
46
- throw UnauthorizedError("Invalid JWT token.");
47
- }
48
- const { payload } = jwt.decode(token);
49
- return payload;
50
- };
51
-
52
- export { decodeJwt, decodeJwtRaw, encodeJwt, encodeJwtRaw, verifyJwt, verifyJwtRaw };