@sd-jwt/core 0.12.1-next.0 → 0.12.1-next.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/dist/index.d.mts CHANGED
@@ -8,6 +8,19 @@ type JwtData<Header extends Record<string, unknown>, Payload extends Record<stri
8
8
  signature?: Base64urlString;
9
9
  encoded?: string;
10
10
  };
11
+ /**
12
+ * Options for the JWT verifier
13
+ */
14
+ type VerifierOptions = {
15
+ /**
16
+ * current time in seconds since epoch
17
+ */
18
+ currentDate?: number;
19
+ /**
20
+ * allowed skew for the current time in seconds. Positive value that will lower the iat and nbf checks, and increase the exp check.
21
+ */
22
+ skewSeconds?: number;
23
+ };
11
24
  declare class Jwt<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>> {
12
25
  header?: Header;
13
26
  payload?: Payload;
@@ -25,7 +38,14 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
25
38
  protected getUnsignedToken(): string;
26
39
  sign(signer: Signer): Promise<string>;
27
40
  encodeJwt(): string;
28
- verify(verifier: Verifier): Promise<{
41
+ /**
42
+ * Verify the JWT using the provided verifier function.
43
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
44
+ * @param verifier
45
+ * @param options - Options for verification, such as current date and skew seconds
46
+ * @returns
47
+ */
48
+ verify(verifier: Verifier, options?: VerifierOptions): Promise<{
29
49
  payload: Payload | undefined;
30
50
  header: Header | undefined;
31
51
  }>;
@@ -197,7 +217,14 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
197
217
  };
198
218
  }>;
199
219
  private calculateSDHash;
200
- validate(encodedSDJwt: string): Promise<{
220
+ /**
221
+ * This function is for validating the SD JWT
222
+ * Checking signature, if provided the iat and exp when provided and return its the claims
223
+ * @param encodedSDJwt
224
+ * @param options
225
+ * @returns
226
+ */
227
+ validate(encodedSDJwt: string, options?: VerifierOptions): Promise<{
201
228
  payload: unknown;
202
229
  header: Record<string, unknown> | undefined;
203
230
  }>;
@@ -259,4 +286,4 @@ declare class SDJwtGeneralJSONInstance<ExtendedPayload extends SdJwtPayload> {
259
286
  getClaims(generalSdjwt: GeneralJSON): Promise<unknown>;
260
287
  }
261
288
 
262
- export { FlattenJSON, type FlattenJSONData, type FlattenJSONSerialized, GeneralJSON, type GeneralJSONData, type GeneralJSONSerialized, Jwt, type JwtData, KBJwt, SDJwt, type SDJwtData, SDJwtGeneralJSONInstance, SDJwtInstance, type SdJwtPayload, createDecoy, listKeys, pack };
289
+ export { FlattenJSON, type FlattenJSONData, type FlattenJSONSerialized, GeneralJSON, type GeneralJSONData, type GeneralJSONSerialized, Jwt, type JwtData, KBJwt, SDJwt, type SDJwtData, SDJwtGeneralJSONInstance, SDJwtInstance, type SdJwtPayload, type VerifierOptions, createDecoy, listKeys, pack };
package/dist/index.d.ts CHANGED
@@ -8,6 +8,19 @@ type JwtData<Header extends Record<string, unknown>, Payload extends Record<stri
8
8
  signature?: Base64urlString;
9
9
  encoded?: string;
10
10
  };
11
+ /**
12
+ * Options for the JWT verifier
13
+ */
14
+ type VerifierOptions = {
15
+ /**
16
+ * current time in seconds since epoch
17
+ */
18
+ currentDate?: number;
19
+ /**
20
+ * allowed skew for the current time in seconds. Positive value that will lower the iat and nbf checks, and increase the exp check.
21
+ */
22
+ skewSeconds?: number;
23
+ };
11
24
  declare class Jwt<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>> {
12
25
  header?: Header;
13
26
  payload?: Payload;
@@ -25,7 +38,14 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
25
38
  protected getUnsignedToken(): string;
26
39
  sign(signer: Signer): Promise<string>;
27
40
  encodeJwt(): string;
28
- verify(verifier: Verifier): Promise<{
41
+ /**
42
+ * Verify the JWT using the provided verifier function.
43
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
44
+ * @param verifier
45
+ * @param options - Options for verification, such as current date and skew seconds
46
+ * @returns
47
+ */
48
+ verify(verifier: Verifier, options?: VerifierOptions): Promise<{
29
49
  payload: Payload | undefined;
30
50
  header: Header | undefined;
31
51
  }>;
@@ -197,7 +217,14 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
197
217
  };
198
218
  }>;
199
219
  private calculateSDHash;
200
- validate(encodedSDJwt: string): Promise<{
220
+ /**
221
+ * This function is for validating the SD JWT
222
+ * Checking signature, if provided the iat and exp when provided and return its the claims
223
+ * @param encodedSDJwt
224
+ * @param options
225
+ * @returns
226
+ */
227
+ validate(encodedSDJwt: string, options?: VerifierOptions): Promise<{
201
228
  payload: unknown;
202
229
  header: Record<string, unknown> | undefined;
203
230
  }>;
@@ -259,4 +286,4 @@ declare class SDJwtGeneralJSONInstance<ExtendedPayload extends SdJwtPayload> {
259
286
  getClaims(generalSdjwt: GeneralJSON): Promise<unknown>;
260
287
  }
261
288
 
262
- export { FlattenJSON, type FlattenJSONData, type FlattenJSONSerialized, GeneralJSON, type GeneralJSONData, type GeneralJSONSerialized, Jwt, type JwtData, KBJwt, SDJwt, type SDJwtData, SDJwtGeneralJSONInstance, SDJwtInstance, type SdJwtPayload, createDecoy, listKeys, pack };
289
+ export { FlattenJSON, type FlattenJSONData, type FlattenJSONSerialized, GeneralJSON, type GeneralJSONData, type GeneralJSONSerialized, Jwt, type JwtData, KBJwt, SDJwt, type SDJwtData, SDJwtGeneralJSONInstance, SDJwtInstance, type SdJwtPayload, type VerifierOptions, createDecoy, listKeys, pack };
package/dist/index.js CHANGED
@@ -143,8 +143,27 @@ var Jwt = class _Jwt {
143
143
  this.encoded = compact;
144
144
  return compact;
145
145
  }
146
- verify(verifier) {
146
+ /**
147
+ * Verify the JWT using the provided verifier function.
148
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
149
+ * @param verifier
150
+ * @param options - Options for verification, such as current date and skew seconds
151
+ * @returns
152
+ */
153
+ verify(verifier, options) {
147
154
  return __async(this, null, function* () {
155
+ var _a, _b, _c, _d;
156
+ const skew = (options == null ? void 0 : options.skewSeconds) ? options.skewSeconds : 0;
157
+ const currentDate = (_a = options == null ? void 0 : options.currentDate) != null ? _a : Math.floor(Date.now() / 1e3);
158
+ if (((_b = this.payload) == null ? void 0 : _b.iat) && this.payload.iat - skew > currentDate) {
159
+ throw new import_utils.SDJWTException("Verify Error: JWT is not yet valid");
160
+ }
161
+ if (((_c = this.payload) == null ? void 0 : _c.nbf) && this.payload.nbf - skew > currentDate) {
162
+ throw new import_utils.SDJWTException("Verify Error: JWT is not yet valid");
163
+ }
164
+ if (((_d = this.payload) == null ? void 0 : _d.exp) && this.payload.exp + skew < currentDate) {
165
+ throw new import_utils.SDJWTException("Verify Error: JWT is expired");
166
+ }
148
167
  if (!this.signature) {
149
168
  throw new import_utils.SDJWTException("Verify Error: no signature in JWT");
150
169
  }
@@ -655,12 +674,12 @@ var _SDJwtInstance = class _SDJwtInstance {
655
674
  return jwt;
656
675
  });
657
676
  }
658
- VerifyJwt(jwt) {
677
+ VerifyJwt(jwt, options) {
659
678
  return __async(this, null, function* () {
660
679
  if (!this.userConfig.verifier) {
661
680
  throw new import_utils7.SDJWTException("Verifier not found");
662
681
  }
663
- return jwt.verify(this.userConfig.verifier);
682
+ return jwt.verify(this.userConfig.verifier, options);
664
683
  });
665
684
  }
666
685
  issue(payload, disclosureFrame, options) {
@@ -804,9 +823,14 @@ var _SDJwtInstance = class _SDJwtInstance {
804
823
  return sdHashStr;
805
824
  });
806
825
  }
807
- // This function is for validating the SD JWT
808
- // Just checking signature and return its the claims
809
- validate(encodedSDJwt) {
826
+ /**
827
+ * This function is for validating the SD JWT
828
+ * Checking signature, if provided the iat and exp when provided and return its the claims
829
+ * @param encodedSDJwt
830
+ * @param options
831
+ * @returns
832
+ */
833
+ validate(encodedSDJwt, options) {
810
834
  return __async(this, null, function* () {
811
835
  if (!this.userConfig.hasher) {
812
836
  throw new import_utils7.SDJWTException("Hasher not found");
@@ -816,7 +840,7 @@ var _SDJwtInstance = class _SDJwtInstance {
816
840
  if (!sdjwt.jwt) {
817
841
  throw new import_utils7.SDJWTException("Invalid SD JWT");
818
842
  }
819
- const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt);
843
+ const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, options);
820
844
  const claims = yield sdjwt.getClaims(hasher);
821
845
  return { payload: claims, header: verifiedPayloads.header };
822
846
  });
package/dist/index.mjs CHANGED
@@ -118,8 +118,27 @@ var Jwt = class _Jwt {
118
118
  this.encoded = compact;
119
119
  return compact;
120
120
  }
121
- verify(verifier) {
121
+ /**
122
+ * Verify the JWT using the provided verifier function.
123
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
124
+ * @param verifier
125
+ * @param options - Options for verification, such as current date and skew seconds
126
+ * @returns
127
+ */
128
+ verify(verifier, options) {
122
129
  return __async(this, null, function* () {
130
+ var _a, _b, _c, _d;
131
+ const skew = (options == null ? void 0 : options.skewSeconds) ? options.skewSeconds : 0;
132
+ const currentDate = (_a = options == null ? void 0 : options.currentDate) != null ? _a : Math.floor(Date.now() / 1e3);
133
+ if (((_b = this.payload) == null ? void 0 : _b.iat) && this.payload.iat - skew > currentDate) {
134
+ throw new SDJWTException("Verify Error: JWT is not yet valid");
135
+ }
136
+ if (((_c = this.payload) == null ? void 0 : _c.nbf) && this.payload.nbf - skew > currentDate) {
137
+ throw new SDJWTException("Verify Error: JWT is not yet valid");
138
+ }
139
+ if (((_d = this.payload) == null ? void 0 : _d.exp) && this.payload.exp + skew < currentDate) {
140
+ throw new SDJWTException("Verify Error: JWT is expired");
141
+ }
123
142
  if (!this.signature) {
124
143
  throw new SDJWTException("Verify Error: no signature in JWT");
125
144
  }
@@ -640,12 +659,12 @@ var _SDJwtInstance = class _SDJwtInstance {
640
659
  return jwt;
641
660
  });
642
661
  }
643
- VerifyJwt(jwt) {
662
+ VerifyJwt(jwt, options) {
644
663
  return __async(this, null, function* () {
645
664
  if (!this.userConfig.verifier) {
646
665
  throw new SDJWTException6("Verifier not found");
647
666
  }
648
- return jwt.verify(this.userConfig.verifier);
667
+ return jwt.verify(this.userConfig.verifier, options);
649
668
  });
650
669
  }
651
670
  issue(payload, disclosureFrame, options) {
@@ -789,9 +808,14 @@ var _SDJwtInstance = class _SDJwtInstance {
789
808
  return sdHashStr;
790
809
  });
791
810
  }
792
- // This function is for validating the SD JWT
793
- // Just checking signature and return its the claims
794
- validate(encodedSDJwt) {
811
+ /**
812
+ * This function is for validating the SD JWT
813
+ * Checking signature, if provided the iat and exp when provided and return its the claims
814
+ * @param encodedSDJwt
815
+ * @param options
816
+ * @returns
817
+ */
818
+ validate(encodedSDJwt, options) {
795
819
  return __async(this, null, function* () {
796
820
  if (!this.userConfig.hasher) {
797
821
  throw new SDJWTException6("Hasher not found");
@@ -801,7 +825,7 @@ var _SDJwtInstance = class _SDJwtInstance {
801
825
  if (!sdjwt.jwt) {
802
826
  throw new SDJWTException6("Invalid SD JWT");
803
827
  }
804
- const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt);
828
+ const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, options);
805
829
  const claims = yield sdjwt.getClaims(hasher);
806
830
  return { payload: claims, header: verifiedPayloads.header };
807
831
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sd-jwt/core",
3
- "version": "0.12.1-next.0+36e0b22",
3
+ "version": "0.12.1-next.2+1eefb26",
4
4
  "description": "sd-jwt draft 7 implementation in typescript",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -38,13 +38,13 @@
38
38
  },
39
39
  "license": "Apache-2.0",
40
40
  "devDependencies": {
41
- "@sd-jwt/crypto-nodejs": "0.12.1-next.0+36e0b22"
41
+ "@sd-jwt/crypto-nodejs": "0.12.1-next.2+1eefb26"
42
42
  },
43
43
  "dependencies": {
44
- "@sd-jwt/decode": "0.12.1-next.0+36e0b22",
45
- "@sd-jwt/present": "0.12.1-next.0+36e0b22",
46
- "@sd-jwt/types": "0.12.1-next.0+36e0b22",
47
- "@sd-jwt/utils": "0.12.1-next.0+36e0b22"
44
+ "@sd-jwt/decode": "0.12.1-next.2+1eefb26",
45
+ "@sd-jwt/present": "0.12.1-next.2+1eefb26",
46
+ "@sd-jwt/types": "0.12.1-next.2+1eefb26",
47
+ "@sd-jwt/utils": "0.12.1-next.2+1eefb26"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"
@@ -62,5 +62,5 @@
62
62
  "esm"
63
63
  ]
64
64
  },
65
- "gitHead": "36e0b22eb619f3ca9ae8522a26617e50c3680526"
65
+ "gitHead": "1eefb262c40ea23e999cdef6e75222e5b4df1e2c"
66
66
  }
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  SDJWTException,
5
5
  uint8ArrayToBase64Url,
6
6
  } from '@sd-jwt/utils';
7
- import { Jwt } from './jwt';
7
+ import { Jwt, type VerifierOptions } from './jwt';
8
8
  import { KBJwt } from './kbjwt';
9
9
  import { SDJwt, pack } from './sdjwt';
10
10
  import {
@@ -86,11 +86,11 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
86
86
  return jwt;
87
87
  }
88
88
 
89
- private async VerifyJwt(jwt: Jwt) {
89
+ private async VerifyJwt(jwt: Jwt, options?: VerifierOptions) {
90
90
  if (!this.userConfig.verifier) {
91
91
  throw new SDJWTException('Verifier not found');
92
92
  }
93
- return jwt.verify(this.userConfig.verifier);
93
+ return jwt.verify(this.userConfig.verifier, options);
94
94
  }
95
95
 
96
96
  public async issue<Payload extends ExtendedPayload>(
@@ -273,9 +273,14 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
273
273
  return sdHashStr;
274
274
  }
275
275
 
276
- // This function is for validating the SD JWT
277
- // Just checking signature and return its the claims
278
- public async validate(encodedSDJwt: string) {
276
+ /**
277
+ * This function is for validating the SD JWT
278
+ * Checking signature, if provided the iat and exp when provided and return its the claims
279
+ * @param encodedSDJwt
280
+ * @param options
281
+ * @returns
282
+ */
283
+ public async validate(encodedSDJwt: string, options?: VerifierOptions) {
279
284
  if (!this.userConfig.hasher) {
280
285
  throw new SDJWTException('Hasher not found');
281
286
  }
@@ -286,7 +291,7 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
286
291
  throw new SDJWTException('Invalid SD JWT');
287
292
  }
288
293
 
289
- const verifiedPayloads = await this.VerifyJwt(sdjwt.jwt);
294
+ const verifiedPayloads = await this.VerifyJwt(sdjwt.jwt, options);
290
295
  const claims = await sdjwt.getClaims(hasher);
291
296
  return { payload: claims, header: verifiedPayloads.header };
292
297
  }
package/src/jwt.ts CHANGED
@@ -12,6 +12,21 @@ export type JwtData<
12
12
  encoded?: string;
13
13
  };
14
14
 
15
+ /**
16
+ * Options for the JWT verifier
17
+ */
18
+ export type VerifierOptions = {
19
+ /**
20
+ * current time in seconds since epoch
21
+ */
22
+ currentDate?: number;
23
+
24
+ /**
25
+ * allowed skew for the current time in seconds. Positive value that will lower the iat and nbf checks, and increase the exp check.
26
+ */
27
+ skewSeconds?: number;
28
+ };
29
+
15
30
  // This class is used to create and verify JWT
16
31
  // Contains header, payload, and signature
17
32
  export class Jwt<
@@ -113,7 +128,36 @@ export class Jwt<
113
128
  return compact;
114
129
  }
115
130
 
116
- public async verify(verifier: Verifier) {
131
+ /**
132
+ * Verify the JWT using the provided verifier function.
133
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
134
+ * @param verifier
135
+ * @param options - Options for verification, such as current date and skew seconds
136
+ * @returns
137
+ */
138
+ public async verify(verifier: Verifier, options?: VerifierOptions) {
139
+ const skew = options?.skewSeconds ? options.skewSeconds : 0;
140
+ const currentDate = options?.currentDate ?? Math.floor(Date.now() / 1000);
141
+ if (
142
+ this.payload?.iat &&
143
+ (this.payload.iat as number) - skew > currentDate
144
+ ) {
145
+ throw new SDJWTException('Verify Error: JWT is not yet valid');
146
+ }
147
+
148
+ if (
149
+ this.payload?.nbf &&
150
+ (this.payload.nbf as number) - skew > currentDate
151
+ ) {
152
+ throw new SDJWTException('Verify Error: JWT is not yet valid');
153
+ }
154
+ if (
155
+ this.payload?.exp &&
156
+ (this.payload.exp as number) + skew < currentDate
157
+ ) {
158
+ throw new SDJWTException('Verify Error: JWT is expired');
159
+ }
160
+
117
161
  if (!this.signature) {
118
162
  throw new SDJWTException('Verify Error: no signature in JWT');
119
163
  }
@@ -49,7 +49,7 @@ describe('index', () => {
49
49
  {
50
50
  foo: 'bar',
51
51
  iss: 'Issuer',
52
- iat: new Date().getTime(),
52
+ iat: Math.floor(Date.now() / 1000),
53
53
  vct: '',
54
54
  },
55
55
  {
@@ -89,7 +89,7 @@ describe('index', () => {
89
89
  {
90
90
  foo: 'bar',
91
91
  iss: 'Issuer',
92
- iat: new Date().getTime(),
92
+ iat: Math.floor(Date.now() / 1000),
93
93
  vct: '',
94
94
  },
95
95
  {
@@ -124,7 +124,7 @@ describe('index', () => {
124
124
  {
125
125
  foo: 'bar',
126
126
  iss: 'Issuer',
127
- iat: new Date().getTime(),
127
+ iat: Math.floor(Date.now() / 1000),
128
128
  vct: '',
129
129
  },
130
130
  {
@@ -165,7 +165,7 @@ describe('index', () => {
165
165
  {
166
166
  foo: 'bar',
167
167
  iss: 'Issuer',
168
- iat: new Date().getTime(),
168
+ iat: Math.floor(Date.now() / 1000),
169
169
  vct: '',
170
170
  },
171
171
  {
@@ -239,7 +239,7 @@ describe('index', () => {
239
239
  const credential = await sdjwt.issue(
240
240
  {
241
241
  foo: 'bar',
242
- iat: new Date().getTime(),
242
+ iat: Math.floor(Date.now() / 1000),
243
243
  cnf: {
244
244
  jwk: await exportJWK(publicKey),
245
245
  },
@@ -274,7 +274,7 @@ describe('index', () => {
274
274
  {
275
275
  foo: 'bar',
276
276
  iss: 'Issuer',
277
- iat: new Date().getTime(),
277
+ iat: Math.floor(Date.now() / 1000),
278
278
  vct: '',
279
279
  },
280
280
  {
@@ -297,7 +297,7 @@ describe('index', () => {
297
297
  {
298
298
  foo: 'bar',
299
299
  iss: 'Issuer',
300
- iat: new Date().getTime(),
300
+ iat: Math.floor(Date.now() / 1000),
301
301
  vct: '',
302
302
  },
303
303
  {
@@ -321,7 +321,7 @@ describe('index', () => {
321
321
  {
322
322
  foo: 'bar',
323
323
  iss: 'Issuer',
324
- iat: new Date().getTime(),
324
+ iat: Math.floor(Date.now() / 1000),
325
325
  vct: '',
326
326
  },
327
327
  {
@@ -351,7 +351,7 @@ describe('index', () => {
351
351
  {
352
352
  foo: 'bar',
353
353
  iss: 'Issuer',
354
- iat: new Date().getTime(),
354
+ iat: Math.floor(Date.now() / 1000),
355
355
  vct: '',
356
356
  },
357
357
  {
@@ -395,7 +395,7 @@ describe('index', () => {
395
395
  {
396
396
  foo: 'bar',
397
397
  iss: 'Issuer',
398
- iat: new Date().getTime(),
398
+ iat: Math.floor(Date.now() / 1000),
399
399
  vct: '',
400
400
  },
401
401
  {
@@ -437,7 +437,7 @@ describe('index', () => {
437
437
  {
438
438
  foo: 'bar',
439
439
  iss: 'Issuer',
440
- iat: new Date().getTime(),
440
+ iat: Math.floor(Date.now() / 1000),
441
441
  vct: '',
442
442
  },
443
443
  {
@@ -480,7 +480,7 @@ describe('index', () => {
480
480
  {
481
481
  foo: 'bar',
482
482
  iss: 'Issuer',
483
- iat: new Date().getTime(),
483
+ iat: Math.floor(Date.now() / 1000),
484
484
  vct: '',
485
485
  },
486
486
  {
@@ -518,7 +518,7 @@ describe('index', () => {
518
518
  {
519
519
  foo: 'bar',
520
520
  iss: 'Issuer',
521
- iat: new Date().getTime(),
521
+ iat: Math.floor(Date.now() / 1000),
522
522
  vct: '',
523
523
  },
524
524
  {
@@ -547,7 +547,7 @@ describe('index', () => {
547
547
  {
548
548
  foo: 'bar',
549
549
  iss: 'Issuer',
550
- iat: new Date().getTime(),
550
+ iat: Math.floor(Date.now() / 1000),
551
551
  vct: '',
552
552
  },
553
553
  {
@@ -573,7 +573,7 @@ describe('index', () => {
573
573
  {
574
574
  foo: 'bar',
575
575
  iss: 'Issuer',
576
- iat: new Date().getTime(),
576
+ iat: Math.floor(Date.now() / 1000),
577
577
  vct: '',
578
578
  },
579
579
  {
@@ -199,4 +199,109 @@ describe('JWT', () => {
199
199
  expect(e).toBeInstanceOf(SDJWTException);
200
200
  }
201
201
  });
202
+
203
+ test('verify with issuance date in the future', async () => {
204
+ const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
205
+ const testVerifier: Verifier = async (data: string, sig: string) => {
206
+ return Crypto.verify(
207
+ null,
208
+ Buffer.from(data),
209
+ publicKey,
210
+ Buffer.from(sig, 'base64url'),
211
+ );
212
+ };
213
+
214
+ const jwt = new Jwt({
215
+ header: { alg: 'EdDSA' },
216
+ payload: { iat: Math.floor(Date.now() / 1000) + 100 },
217
+ });
218
+
219
+ try {
220
+ await jwt.verify(testVerifier);
221
+ } catch (e: unknown) {
222
+ expect(e).toBeInstanceOf(SDJWTException);
223
+ expect((e as SDJWTException).message).toBe(
224
+ 'Verify Error: JWT is not yet valid',
225
+ );
226
+ }
227
+ });
228
+
229
+ test('verify with not before in the future', async () => {
230
+ const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
231
+ const testVerifier: Verifier = async (data: string, sig: string) => {
232
+ return Crypto.verify(
233
+ null,
234
+ Buffer.from(data),
235
+ publicKey,
236
+ Buffer.from(sig, 'base64url'),
237
+ );
238
+ };
239
+
240
+ const jwt = new Jwt({
241
+ header: { alg: 'EdDSA' },
242
+ payload: { nbf: Math.floor(Date.now() / 1000) + 100 },
243
+ });
244
+
245
+ try {
246
+ await jwt.verify(testVerifier);
247
+ } catch (e: unknown) {
248
+ expect(e).toBeInstanceOf(SDJWTException);
249
+ expect((e as SDJWTException).message).toBe(
250
+ 'Verify Error: JWT is not yet valid',
251
+ );
252
+ }
253
+ });
254
+
255
+ test('verify with expired', async () => {
256
+ const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
257
+ const testVerifier: Verifier = async (data: string, sig: string) => {
258
+ return Crypto.verify(
259
+ null,
260
+ Buffer.from(data),
261
+ publicKey,
262
+ Buffer.from(sig, 'base64url'),
263
+ );
264
+ };
265
+
266
+ const jwt = new Jwt({
267
+ header: { alg: 'EdDSA' },
268
+ payload: { exp: Math.floor(Date.now() / 1000) },
269
+ });
270
+
271
+ try {
272
+ await jwt.verify(testVerifier, {
273
+ currentDate: Math.floor(Date.now() / 1000) + 100,
274
+ });
275
+ } catch (e: unknown) {
276
+ expect(e).toBeInstanceOf(SDJWTException);
277
+ expect((e as SDJWTException).message).toBe(
278
+ 'Verify Error: JWT is expired',
279
+ );
280
+ }
281
+ });
282
+
283
+ test('verify with skew', async () => {
284
+ const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
285
+ const testVerifier: Verifier = async (data: string, sig: string) => {
286
+ return Crypto.verify(
287
+ null,
288
+ Buffer.from(data),
289
+ publicKey,
290
+ Buffer.from(sig, 'base64url'),
291
+ );
292
+ };
293
+
294
+ const jwt = new Jwt({
295
+ header: { alg: 'EdDSA' },
296
+ payload: { exp: Math.floor(Date.now() / 1000) - 1 },
297
+ });
298
+
299
+ const testSigner: Signer = async (data: string) => {
300
+ const sig = Crypto.sign(null, Buffer.from(data), privateKey);
301
+ return Buffer.from(sig).toString('base64url');
302
+ };
303
+
304
+ await jwt.sign(testSigner);
305
+ await jwt.verify(testVerifier, { skewSeconds: 2 });
306
+ });
202
307
  });
@@ -224,7 +224,7 @@ async function JSONtest(filename: string) {
224
224
  payload: test.claims,
225
225
  });
226
226
 
227
- const presentedSDJwt = await sdjwt.present<typeof claims>(
227
+ const presentedSDJwt = await sdjwt.present<typeof test.claims>(
228
228
  encodedSdjwt,
229
229
  test.presentationFrames,
230
230
  );