@elysiajs/jwt 1.3.2 → 1.3.3

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,4 +1,4 @@
1
- # @elysiajs/static
1
+ # @elysiajs/jwt
2
2
 
3
3
  Plugin for [Elysia](https://github.com/elysiajs/elysia) for using JWT Authentication.
4
4
 
@@ -13,7 +13,6 @@ bun add @elysiajs/jwt
13
13
  ```typescript
14
14
  import { Elysia, t } from 'elysia';
15
15
  import { jwt } from '@elysiajs/jwt';
16
- import { cookie } from '@elysiajs/cookie';
17
16
 
18
17
  const app = new Elysia()
19
18
  .use(
@@ -23,9 +22,9 @@ const app = new Elysia()
23
22
  secret: 'MY_SECRETS',
24
23
  })
25
24
  )
26
- .use(cookie())
27
- .get('/sign/:name', async ({ jwt, cookie, setCookie, params }) => {
28
- setCookie('auth', await jwt.sign(params), {
25
+ .get('/sign/:name', async ({ jwt, cookie: { auth }, params }) => {
26
+ auth.set({
27
+ value: await jwt.sign(params),
29
28
  httpOnly: true,
30
29
  });
31
30
 
@@ -1,6 +1,11 @@
1
1
  import { Elysia, type TSchema, type UnwrapSchema as Static } from 'elysia';
2
- import { type CryptoKey, type JWK, type KeyObject, type JoseHeaderParameters } from 'jose';
2
+ import { type CryptoKey, type JWK, type KeyObject, type JoseHeaderParameters, type JWTVerifyOptions } from 'jose';
3
3
  type UnwrapSchema<Schema extends TSchema | undefined, Fallback = unknown> = Schema extends TSchema ? Static<NonNullable<Schema>> : Fallback;
4
+ type NormalizedClaim = 'nbf' | 'exp' | 'iat';
5
+ type AllowClaimValue = string | number | boolean | null | undefined | AllowClaimValue[] | {
6
+ [key: string]: AllowClaimValue;
7
+ };
8
+ type ClaimType = Record<string, AllowClaimValue>;
4
9
  /**
5
10
  * This interface is a specific, strongly-typed representation of the
6
11
  * standard claims found in a JWT payload.
@@ -36,6 +41,36 @@ export interface JWTPayloadSpec {
36
41
  * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7 RFC7519#section-4.1.7}
37
42
  */
38
43
  jti?: string;
44
+ /**
45
+ * JWT Not Before
46
+ *
47
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5 RFC7519#section-4.1.5}
48
+ */
49
+ nbf?: number;
50
+ /**
51
+ * JWT Expiration Time
52
+ *
53
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4 RFC7519#section-4.1.4}
54
+ */
55
+ exp?: number;
56
+ /**
57
+ * JWT Issued At
58
+ *
59
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 RFC7519#section-4.1.6}
60
+ */
61
+ iat?: number;
62
+ }
63
+ /**
64
+ * This interface defines the shape of JWT payload fields that can be
65
+ * provided as input when creating or signing a token.
66
+ *
67
+ * Unlike `JWTPayloadSpec`, values here may be expressed in more flexible forms,
68
+ * such as relative time strings or control flags (e.g., `iat: true`).
69
+ *
70
+ * This interface is parsed and normalized by the plugin before becoming part
71
+ * of the final JWT payload.
72
+ */
73
+ export interface JWTPayloadInput extends Omit<JWTPayloadSpec, NormalizedClaim> {
39
74
  /**
40
75
  * JWT Not Before
41
76
  *
@@ -80,7 +115,7 @@ export interface JWTHeaderParameters extends JoseHeaderParameters {
80
115
  /** JWS "crit" (Critical) Header Parameter */
81
116
  crit?: string[];
82
117
  }
83
- export interface JWTOption<Name extends string | undefined = 'jwt', Schema extends TSchema | undefined = undefined> extends JWTHeaderParameters, JWTPayloadSpec {
118
+ export interface JWTOption<Name extends string | undefined = 'jwt', Schema extends TSchema | undefined = undefined> extends JWTHeaderParameters, JWTPayloadInput {
84
119
  /**
85
120
  * Name to decorate method as
86
121
  *
@@ -111,11 +146,11 @@ export interface JWTOption<Name extends string | undefined = 'jwt', Schema exten
111
146
  }
112
147
  export declare const jwt: <const Name extends string = "jwt", const Schema extends TSchema | undefined = undefined>({ name, secret, schema, ...defaultValues }: JWTOption<Name, Schema>) => Elysia<"", {
113
148
  decorator: { [name in Name extends string ? Name : "jwt"]: {
114
- sign(data: UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec): Promise<string>;
115
- verify(jwt?: string): Promise<(UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec) | false>;
149
+ sign(signValue: Omit<UnwrapSchema<Schema, ClaimType>, NormalizedClaim> & JWTPayloadInput): Promise<string>;
150
+ verify(jwt?: string, options?: JWTVerifyOptions): Promise<(UnwrapSchema<Schema, ClaimType> & Omit<JWTPayloadSpec, keyof UnwrapSchema<Schema, {}>>) | false>;
116
151
  }; } extends infer T ? { [K in keyof T]: { [name in Name extends string ? Name : "jwt"]: {
117
- sign(data: UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec): Promise<string>;
118
- verify(jwt?: string): Promise<(UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec) | false>;
152
+ sign(signValue: Omit<UnwrapSchema<Schema, ClaimType>, NormalizedClaim> & JWTPayloadInput): Promise<string>;
153
+ verify(jwt?: string, options?: JWTVerifyOptions): Promise<(UnwrapSchema<Schema, ClaimType> & Omit<JWTPayloadSpec, keyof UnwrapSchema<Schema, {}>>) | false>;
119
154
  }; }[K]; } : never;
120
155
  store: {};
121
156
  derive: {};
package/dist/cjs/index.js CHANGED
@@ -2657,9 +2657,9 @@ var jwt = ({
2657
2657
  Type.Union([Type.String(), Type.Array(Type.String())])
2658
2658
  ),
2659
2659
  jti: Type.Optional(Type.String()),
2660
- nbf: Type.Optional(Type.Union([Type.String(), Type.Number()])),
2661
- exp: Type.Optional(Type.Union([Type.String(), Type.Number()])),
2662
- iat: Type.Optional(Type.Union([Type.Number(), Type.String()]))
2660
+ nbf: Type.Optional(Type.Number()),
2661
+ exp: Type.Optional(Type.Number()),
2662
+ iat: Type.Optional(Type.Number())
2663
2663
  })
2664
2664
  ]),
2665
2665
  {
@@ -2675,7 +2675,8 @@ var jwt = ({
2675
2675
  ...defaultValues
2676
2676
  }
2677
2677
  }).decorate(name, {
2678
- sign(data) {
2678
+ sign(signValue) {
2679
+ const { nbf, exp, iat, ...data } = signValue;
2679
2680
  const JWTHeader = {
2680
2681
  alg: defaultValues.alg ?? "HS256",
2681
2682
  b64: defaultValues.b64,
@@ -2706,28 +2707,32 @@ var jwt = ({
2706
2707
  * Subject (sub): Identifies the principal that is the subject of the JWT.
2707
2708
  */
2708
2709
  sub: data.sub ?? defaultValues.sub,
2709
- // Includes all other properties from the data source, both standard and custom.
2710
+ // Includes all other properties from the data source, both standard and custom,
2711
+ // excluding standard JWT claims like `nbf`, `exp` and `iat`.
2710
2712
  ...data
2711
2713
  };
2712
2714
  let jwt2 = new import_jose.SignJWT({ ...JWTPayload }).setProtectedHeader({
2713
2715
  alg: JWTHeader.alg,
2714
2716
  ...JWTHeader
2715
2717
  });
2716
- if (data.nbf !== void 0 || defaultValues.nbf !== void 0) {
2717
- jwt2 = jwt2.setNotBefore(data.nbf ?? defaultValues.nbf);
2718
+ const setNbf = "nbf" in signValue ? nbf : defaultValues.nbf;
2719
+ if (setNbf !== void 0) {
2720
+ jwt2 = jwt2.setNotBefore(setNbf);
2718
2721
  }
2719
- if (data.exp !== void 0 || defaultValues.exp !== void 0) {
2720
- jwt2 = jwt2.setExpirationTime(data.exp ?? defaultValues.exp);
2722
+ const setExp = "exp" in signValue ? exp : defaultValues.exp;
2723
+ if (setExp !== void 0) {
2724
+ jwt2 = jwt2.setExpirationTime(setExp);
2721
2725
  }
2722
- if (defaultValues.iat !== false || data.iat !== false) {
2726
+ const setIat = "iat" in signValue ? iat : defaultValues.iat;
2727
+ if (setIat !== false) {
2723
2728
  jwt2 = jwt2.setIssuedAt(/* @__PURE__ */ new Date());
2724
2729
  }
2725
2730
  return jwt2.sign(key);
2726
2731
  },
2727
- async verify(jwt2) {
2732
+ async verify(jwt2, options) {
2728
2733
  if (!jwt2) return false;
2729
2734
  try {
2730
- const data = (await (0, import_jose.jwtVerify)(jwt2, key)).payload;
2735
+ const data = (await (options ? (0, import_jose.jwtVerify)(jwt2, key, options) : (0, import_jose.jwtVerify)(jwt2, key))).payload;
2731
2736
  if (validator && !validator.Check(data))
2732
2737
  throw new import_elysia.ValidationError("JWT", validator, data);
2733
2738
  return data;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,11 @@
1
1
  import { Elysia, type TSchema, type UnwrapSchema as Static } from 'elysia';
2
- import { type CryptoKey, type JWK, type KeyObject, type JoseHeaderParameters } from 'jose';
2
+ import { type CryptoKey, type JWK, type KeyObject, type JoseHeaderParameters, type JWTVerifyOptions } from 'jose';
3
3
  type UnwrapSchema<Schema extends TSchema | undefined, Fallback = unknown> = Schema extends TSchema ? Static<NonNullable<Schema>> : Fallback;
4
+ type NormalizedClaim = 'nbf' | 'exp' | 'iat';
5
+ type AllowClaimValue = string | number | boolean | null | undefined | AllowClaimValue[] | {
6
+ [key: string]: AllowClaimValue;
7
+ };
8
+ type ClaimType = Record<string, AllowClaimValue>;
4
9
  /**
5
10
  * This interface is a specific, strongly-typed representation of the
6
11
  * standard claims found in a JWT payload.
@@ -36,6 +41,36 @@ export interface JWTPayloadSpec {
36
41
  * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7 RFC7519#section-4.1.7}
37
42
  */
38
43
  jti?: string;
44
+ /**
45
+ * JWT Not Before
46
+ *
47
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5 RFC7519#section-4.1.5}
48
+ */
49
+ nbf?: number;
50
+ /**
51
+ * JWT Expiration Time
52
+ *
53
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4 RFC7519#section-4.1.4}
54
+ */
55
+ exp?: number;
56
+ /**
57
+ * JWT Issued At
58
+ *
59
+ * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 RFC7519#section-4.1.6}
60
+ */
61
+ iat?: number;
62
+ }
63
+ /**
64
+ * This interface defines the shape of JWT payload fields that can be
65
+ * provided as input when creating or signing a token.
66
+ *
67
+ * Unlike `JWTPayloadSpec`, values here may be expressed in more flexible forms,
68
+ * such as relative time strings or control flags (e.g., `iat: true`).
69
+ *
70
+ * This interface is parsed and normalized by the plugin before becoming part
71
+ * of the final JWT payload.
72
+ */
73
+ export interface JWTPayloadInput extends Omit<JWTPayloadSpec, NormalizedClaim> {
39
74
  /**
40
75
  * JWT Not Before
41
76
  *
@@ -80,7 +115,7 @@ export interface JWTHeaderParameters extends JoseHeaderParameters {
80
115
  /** JWS "crit" (Critical) Header Parameter */
81
116
  crit?: string[];
82
117
  }
83
- export interface JWTOption<Name extends string | undefined = 'jwt', Schema extends TSchema | undefined = undefined> extends JWTHeaderParameters, JWTPayloadSpec {
118
+ export interface JWTOption<Name extends string | undefined = 'jwt', Schema extends TSchema | undefined = undefined> extends JWTHeaderParameters, JWTPayloadInput {
84
119
  /**
85
120
  * Name to decorate method as
86
121
  *
@@ -111,11 +146,11 @@ export interface JWTOption<Name extends string | undefined = 'jwt', Schema exten
111
146
  }
112
147
  export declare const jwt: <const Name extends string = "jwt", const Schema extends TSchema | undefined = undefined>({ name, secret, schema, ...defaultValues }: JWTOption<Name, Schema>) => Elysia<"", {
113
148
  decorator: { [name in Name extends string ? Name : "jwt"]: {
114
- sign(data: UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec): Promise<string>;
115
- verify(jwt?: string): Promise<(UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec) | false>;
149
+ sign(signValue: Omit<UnwrapSchema<Schema, ClaimType>, NormalizedClaim> & JWTPayloadInput): Promise<string>;
150
+ verify(jwt?: string, options?: JWTVerifyOptions): Promise<(UnwrapSchema<Schema, ClaimType> & Omit<JWTPayloadSpec, keyof UnwrapSchema<Schema, {}>>) | false>;
116
151
  }; } extends infer T ? { [K in keyof T]: { [name in Name extends string ? Name : "jwt"]: {
117
- sign(data: UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec): Promise<string>;
118
- verify(jwt?: string): Promise<(UnwrapSchema<Schema, Record<string, string | number>> & JWTPayloadSpec) | false>;
152
+ sign(signValue: Omit<UnwrapSchema<Schema, ClaimType>, NormalizedClaim> & JWTPayloadInput): Promise<string>;
153
+ verify(jwt?: string, options?: JWTVerifyOptions): Promise<(UnwrapSchema<Schema, ClaimType> & Omit<JWTPayloadSpec, keyof UnwrapSchema<Schema, {}>>) | false>;
119
154
  }; }[K]; } : never;
120
155
  store: {};
121
156
  derive: {};
package/dist/index.mjs CHANGED
@@ -2645,9 +2645,9 @@ var jwt = ({
2645
2645
  Type.Union([Type.String(), Type.Array(Type.String())])
2646
2646
  ),
2647
2647
  jti: Type.Optional(Type.String()),
2648
- nbf: Type.Optional(Type.Union([Type.String(), Type.Number()])),
2649
- exp: Type.Optional(Type.Union([Type.String(), Type.Number()])),
2650
- iat: Type.Optional(Type.Union([Type.Number(), Type.String()]))
2648
+ nbf: Type.Optional(Type.Number()),
2649
+ exp: Type.Optional(Type.Number()),
2650
+ iat: Type.Optional(Type.Number())
2651
2651
  })
2652
2652
  ]),
2653
2653
  {
@@ -2663,7 +2663,8 @@ var jwt = ({
2663
2663
  ...defaultValues
2664
2664
  }
2665
2665
  }).decorate(name, {
2666
- sign(data) {
2666
+ sign(signValue) {
2667
+ const { nbf, exp, iat, ...data } = signValue;
2667
2668
  const JWTHeader = {
2668
2669
  alg: defaultValues.alg ?? "HS256",
2669
2670
  b64: defaultValues.b64,
@@ -2694,28 +2695,32 @@ var jwt = ({
2694
2695
  * Subject (sub): Identifies the principal that is the subject of the JWT.
2695
2696
  */
2696
2697
  sub: data.sub ?? defaultValues.sub,
2697
- // Includes all other properties from the data source, both standard and custom.
2698
+ // Includes all other properties from the data source, both standard and custom,
2699
+ // excluding standard JWT claims like `nbf`, `exp` and `iat`.
2698
2700
  ...data
2699
2701
  };
2700
2702
  let jwt2 = new SignJWT({ ...JWTPayload }).setProtectedHeader({
2701
2703
  alg: JWTHeader.alg,
2702
2704
  ...JWTHeader
2703
2705
  });
2704
- if (data.nbf !== void 0 || defaultValues.nbf !== void 0) {
2705
- jwt2 = jwt2.setNotBefore(data.nbf ?? defaultValues.nbf);
2706
+ const setNbf = "nbf" in signValue ? nbf : defaultValues.nbf;
2707
+ if (setNbf !== void 0) {
2708
+ jwt2 = jwt2.setNotBefore(setNbf);
2706
2709
  }
2707
- if (data.exp !== void 0 || defaultValues.exp !== void 0) {
2708
- jwt2 = jwt2.setExpirationTime(data.exp ?? defaultValues.exp);
2710
+ const setExp = "exp" in signValue ? exp : defaultValues.exp;
2711
+ if (setExp !== void 0) {
2712
+ jwt2 = jwt2.setExpirationTime(setExp);
2709
2713
  }
2710
- if (defaultValues.iat !== false || data.iat !== false) {
2714
+ const setIat = "iat" in signValue ? iat : defaultValues.iat;
2715
+ if (setIat !== false) {
2711
2716
  jwt2 = jwt2.setIssuedAt(/* @__PURE__ */ new Date());
2712
2717
  }
2713
2718
  return jwt2.sign(key);
2714
2719
  },
2715
- async verify(jwt2) {
2720
+ async verify(jwt2, options) {
2716
2721
  if (!jwt2) return false;
2717
2722
  try {
2718
- const data = (await jwtVerify(jwt2, key)).payload;
2723
+ const data = (await (options ? jwtVerify(jwt2, key, options) : jwtVerify(jwt2, key))).payload;
2719
2724
  if (validator && !validator.Check(data))
2720
2725
  throw new ValidationError("JWT", validator, data);
2721
2726
  return data;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elysiajs/jwt",
3
3
  "description": "Plugin for Elysia for using JWT Authentication",
4
- "version": "1.3.2",
4
+ "version": "1.3.3",
5
5
  "author": {
6
6
  "name": "saltyAom",
7
7
  "url": "https://github.com/SaltyAom",