@sd-jwt/core 0.12.0 → 0.12.1-next.1

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
@@ -25,7 +25,14 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
25
25
  protected getUnsignedToken(): string;
26
26
  sign(signer: Signer): Promise<string>;
27
27
  encodeJwt(): string;
28
- verify(verifier: Verifier): Promise<{
28
+ /**
29
+ * Verify the JWT using the provided verifier function.
30
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
31
+ * @param verifier
32
+ * @param currentDate
33
+ * @returns
34
+ */
35
+ verify(verifier: Verifier, currentDate?: number): Promise<{
29
36
  payload: Payload | undefined;
30
37
  header: Header | undefined;
31
38
  }>;
@@ -197,7 +204,14 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
197
204
  };
198
205
  }>;
199
206
  private calculateSDHash;
200
- validate(encodedSDJwt: string): Promise<{
207
+ /**
208
+ * This function is for validating the SD JWT
209
+ * Checking signature, if provided the iat and exp when provided and return its the claims
210
+ * @param encodedSDJwt
211
+ * @param currentDate
212
+ * @returns
213
+ */
214
+ validate(encodedSDJwt: string, currentDate?: number): Promise<{
201
215
  payload: unknown;
202
216
  header: Record<string, unknown> | undefined;
203
217
  }>;
package/dist/index.d.ts CHANGED
@@ -25,7 +25,14 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
25
25
  protected getUnsignedToken(): string;
26
26
  sign(signer: Signer): Promise<string>;
27
27
  encodeJwt(): string;
28
- verify(verifier: Verifier): Promise<{
28
+ /**
29
+ * Verify the JWT using the provided verifier function.
30
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
31
+ * @param verifier
32
+ * @param currentDate
33
+ * @returns
34
+ */
35
+ verify(verifier: Verifier, currentDate?: number): Promise<{
29
36
  payload: Payload | undefined;
30
37
  header: Header | undefined;
31
38
  }>;
@@ -197,7 +204,14 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
197
204
  };
198
205
  }>;
199
206
  private calculateSDHash;
200
- validate(encodedSDJwt: string): Promise<{
207
+ /**
208
+ * This function is for validating the SD JWT
209
+ * Checking signature, if provided the iat and exp when provided and return its the claims
210
+ * @param encodedSDJwt
211
+ * @param currentDate
212
+ * @returns
213
+ */
214
+ validate(encodedSDJwt: string, currentDate?: number): Promise<{
201
215
  payload: unknown;
202
216
  header: Record<string, unknown> | undefined;
203
217
  }>;
package/dist/index.js CHANGED
@@ -143,8 +143,25 @@ var Jwt = class _Jwt {
143
143
  this.encoded = compact;
144
144
  return compact;
145
145
  }
146
- verify(verifier) {
147
- return __async(this, null, function* () {
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 currentDate
151
+ * @returns
152
+ */
153
+ verify(_0) {
154
+ return __async(this, arguments, function* (verifier, currentDate = Math.floor(Date.now() / 1e3)) {
155
+ var _a, _b, _c;
156
+ if (((_a = this.payload) == null ? void 0 : _a.iat) && this.payload.iat > currentDate) {
157
+ throw new import_utils.SDJWTException("Verify Error: JWT is not yet valid");
158
+ }
159
+ if (((_b = this.payload) == null ? void 0 : _b.nbf) && this.payload.nbf > currentDate) {
160
+ throw new import_utils.SDJWTException("Verify Error: JWT is not yet valid");
161
+ }
162
+ if (((_c = this.payload) == null ? void 0 : _c.exp) && this.payload.exp < currentDate) {
163
+ throw new import_utils.SDJWTException("Verify Error: JWT is expired");
164
+ }
148
165
  if (!this.signature) {
149
166
  throw new import_utils.SDJWTException("Verify Error: no signature in JWT");
150
167
  }
@@ -655,12 +672,12 @@ var _SDJwtInstance = class _SDJwtInstance {
655
672
  return jwt;
656
673
  });
657
674
  }
658
- VerifyJwt(jwt) {
675
+ VerifyJwt(jwt, currentDate) {
659
676
  return __async(this, null, function* () {
660
677
  if (!this.userConfig.verifier) {
661
678
  throw new import_utils7.SDJWTException("Verifier not found");
662
679
  }
663
- return jwt.verify(this.userConfig.verifier);
680
+ return jwt.verify(this.userConfig.verifier, currentDate);
664
681
  });
665
682
  }
666
683
  issue(payload, disclosureFrame, options) {
@@ -804,10 +821,15 @@ var _SDJwtInstance = class _SDJwtInstance {
804
821
  return sdHashStr;
805
822
  });
806
823
  }
807
- // This function is for validating the SD JWT
808
- // Just checking signature and return its the claims
809
- validate(encodedSDJwt) {
810
- return __async(this, null, function* () {
824
+ /**
825
+ * This function is for validating the SD JWT
826
+ * Checking signature, if provided the iat and exp when provided and return its the claims
827
+ * @param encodedSDJwt
828
+ * @param currentDate
829
+ * @returns
830
+ */
831
+ validate(_0) {
832
+ return __async(this, arguments, function* (encodedSDJwt, currentDate = Math.floor(Date.now() / 1e3)) {
811
833
  if (!this.userConfig.hasher) {
812
834
  throw new import_utils7.SDJWTException("Hasher not found");
813
835
  }
@@ -816,7 +838,7 @@ var _SDJwtInstance = class _SDJwtInstance {
816
838
  if (!sdjwt.jwt) {
817
839
  throw new import_utils7.SDJWTException("Invalid SD JWT");
818
840
  }
819
- const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt);
841
+ const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, currentDate);
820
842
  const claims = yield sdjwt.getClaims(hasher);
821
843
  return { payload: claims, header: verifiedPayloads.header };
822
844
  });
package/dist/index.mjs CHANGED
@@ -118,8 +118,25 @@ var Jwt = class _Jwt {
118
118
  this.encoded = compact;
119
119
  return compact;
120
120
  }
121
- verify(verifier) {
122
- return __async(this, null, function* () {
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 currentDate
126
+ * @returns
127
+ */
128
+ verify(_0) {
129
+ return __async(this, arguments, function* (verifier, currentDate = Math.floor(Date.now() / 1e3)) {
130
+ var _a, _b, _c;
131
+ if (((_a = this.payload) == null ? void 0 : _a.iat) && this.payload.iat > currentDate) {
132
+ throw new SDJWTException("Verify Error: JWT is not yet valid");
133
+ }
134
+ if (((_b = this.payload) == null ? void 0 : _b.nbf) && this.payload.nbf > currentDate) {
135
+ throw new SDJWTException("Verify Error: JWT is not yet valid");
136
+ }
137
+ if (((_c = this.payload) == null ? void 0 : _c.exp) && this.payload.exp < currentDate) {
138
+ throw new SDJWTException("Verify Error: JWT is expired");
139
+ }
123
140
  if (!this.signature) {
124
141
  throw new SDJWTException("Verify Error: no signature in JWT");
125
142
  }
@@ -640,12 +657,12 @@ var _SDJwtInstance = class _SDJwtInstance {
640
657
  return jwt;
641
658
  });
642
659
  }
643
- VerifyJwt(jwt) {
660
+ VerifyJwt(jwt, currentDate) {
644
661
  return __async(this, null, function* () {
645
662
  if (!this.userConfig.verifier) {
646
663
  throw new SDJWTException6("Verifier not found");
647
664
  }
648
- return jwt.verify(this.userConfig.verifier);
665
+ return jwt.verify(this.userConfig.verifier, currentDate);
649
666
  });
650
667
  }
651
668
  issue(payload, disclosureFrame, options) {
@@ -789,10 +806,15 @@ var _SDJwtInstance = class _SDJwtInstance {
789
806
  return sdHashStr;
790
807
  });
791
808
  }
792
- // This function is for validating the SD JWT
793
- // Just checking signature and return its the claims
794
- validate(encodedSDJwt) {
795
- return __async(this, null, function* () {
809
+ /**
810
+ * This function is for validating the SD JWT
811
+ * Checking signature, if provided the iat and exp when provided and return its the claims
812
+ * @param encodedSDJwt
813
+ * @param currentDate
814
+ * @returns
815
+ */
816
+ validate(_0) {
817
+ return __async(this, arguments, function* (encodedSDJwt, currentDate = Math.floor(Date.now() / 1e3)) {
796
818
  if (!this.userConfig.hasher) {
797
819
  throw new SDJWTException6("Hasher not found");
798
820
  }
@@ -801,7 +823,7 @@ var _SDJwtInstance = class _SDJwtInstance {
801
823
  if (!sdjwt.jwt) {
802
824
  throw new SDJWTException6("Invalid SD JWT");
803
825
  }
804
- const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt);
826
+ const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, currentDate);
805
827
  const claims = yield sdjwt.getClaims(hasher);
806
828
  return { payload: claims, header: verifiedPayloads.header };
807
829
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sd-jwt/core",
3
- "version": "0.12.0",
3
+ "version": "0.12.1-next.1+0a2f20b",
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.0"
41
+ "@sd-jwt/crypto-nodejs": "0.12.1-next.1+0a2f20b"
42
42
  },
43
43
  "dependencies": {
44
- "@sd-jwt/decode": "0.12.0",
45
- "@sd-jwt/present": "0.12.0",
46
- "@sd-jwt/types": "0.12.0",
47
- "@sd-jwt/utils": "0.12.0"
44
+ "@sd-jwt/decode": "0.12.1-next.1+0a2f20b",
45
+ "@sd-jwt/present": "0.12.1-next.1+0a2f20b",
46
+ "@sd-jwt/types": "0.12.1-next.1+0a2f20b",
47
+ "@sd-jwt/utils": "0.12.1-next.1+0a2f20b"
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": "0a2f20b6383d2356540e7a9cc37748c7b9caced2"
66
66
  }
package/src/index.ts CHANGED
@@ -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, currentDate: number) {
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, currentDate);
94
94
  }
95
95
 
96
96
  public async issue<Payload extends ExtendedPayload>(
@@ -273,9 +273,17 @@ 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 currentDate
281
+ * @returns
282
+ */
283
+ public async validate(
284
+ encodedSDJwt: string,
285
+ currentDate: number = Math.floor(Date.now() / 1000),
286
+ ) {
279
287
  if (!this.userConfig.hasher) {
280
288
  throw new SDJWTException('Hasher not found');
281
289
  }
@@ -286,7 +294,7 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
286
294
  throw new SDJWTException('Invalid SD JWT');
287
295
  }
288
296
 
289
- const verifiedPayloads = await this.VerifyJwt(sdjwt.jwt);
297
+ const verifiedPayloads = await this.VerifyJwt(sdjwt.jwt, currentDate);
290
298
  const claims = await sdjwt.getClaims(hasher);
291
299
  return { payload: claims, header: verifiedPayloads.header };
292
300
  }
package/src/jwt.ts CHANGED
@@ -113,7 +113,28 @@ export class Jwt<
113
113
  return compact;
114
114
  }
115
115
 
116
- public async verify(verifier: Verifier) {
116
+ /**
117
+ * Verify the JWT using the provided verifier function.
118
+ * It checks the signature and validates the iat, nbf, and exp claims if they are present.
119
+ * @param verifier
120
+ * @param currentDate
121
+ * @returns
122
+ */
123
+ public async verify(
124
+ verifier: Verifier,
125
+ currentDate = Math.floor(Date.now() / 1000),
126
+ ) {
127
+ if (this.payload?.iat && (this.payload.iat as number) > currentDate) {
128
+ throw new SDJWTException('Verify Error: JWT is not yet valid');
129
+ }
130
+
131
+ if (this.payload?.nbf && (this.payload.nbf as number) > currentDate) {
132
+ throw new SDJWTException('Verify Error: JWT is not yet valid');
133
+ }
134
+ if (this.payload?.exp && (this.payload.exp as number) < currentDate) {
135
+ throw new SDJWTException('Verify Error: JWT is expired');
136
+ }
137
+
117
138
  if (!this.signature) {
118
139
  throw new SDJWTException('Verify Error: no signature in JWT');
119
140
  }
@@ -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,82 @@ 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, Math.floor(Date.now() / 1000) + 100);
273
+ } catch (e: unknown) {
274
+ expect(e).toBeInstanceOf(SDJWTException);
275
+ expect((e as SDJWTException).message).toBe(
276
+ 'Verify Error: JWT is expired',
277
+ );
278
+ }
279
+ });
202
280
  });
@@ -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
  );