@twin.org/web 0.0.1-next.36 → 0.0.1-next.38

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.
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@twin.org/core');
4
- var crypto = require('@twin.org/crypto');
4
+ var jose = require('jose');
5
5
 
6
6
  // Copyright 2024 IOTA Stiftung.
7
7
  // SPDX-License-Identifier: Apache-2.0.
@@ -345,23 +345,6 @@ const HttpStatusCode = {
345
345
  networkAuthenticationRequired: 511
346
346
  };
347
347
 
348
- // Copyright 2024 IOTA Stiftung.
349
- // SPDX-License-Identifier: Apache-2.0.
350
- /**
351
- * The cryptographic algorithms supported for JSON Web Tokens and JSON Web Keys.
352
- */
353
- // eslint-disable-next-line @typescript-eslint/naming-convention
354
- const JwtAlgorithms = {
355
- /**
356
- * HMAC using SHA-256.
357
- */
358
- HS256: "HS256",
359
- /**
360
- * EdDSA using Ed25519.
361
- */
362
- EdDSA: "EdDSA"
363
- };
364
-
365
348
  // Copyright 2024 IOTA Stiftung.
366
349
  // SPDX-License-Identifier: Apache-2.0.
367
350
  /**
@@ -714,7 +697,34 @@ class FetchHelper {
714
697
  // Copyright 2024 IOTA Stiftung.
715
698
  // SPDX-License-Identifier: Apache-2.0.
716
699
  /**
717
- * Class to encode and decode JSON Web Tokens.
700
+ * Class to handle JSON Web Keys.
701
+ */
702
+ class Jwk {
703
+ /**
704
+ * Runtime name for the class.
705
+ * @internal
706
+ */
707
+ static _CLASS_NAME = "Jwk";
708
+ /**
709
+ * Convert the JWK to a crypto key.
710
+ * @param jwk The JWK to convert.
711
+ * @returns The crypto key.
712
+ */
713
+ static async toCryptoKey(jwk) {
714
+ core.Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
715
+ try {
716
+ return jose.importJWK(jwk);
717
+ }
718
+ catch (err) {
719
+ throw new core.GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
720
+ }
721
+ }
722
+ }
723
+
724
+ // Copyright 2024 IOTA Stiftung.
725
+ // SPDX-License-Identifier: Apache-2.0.
726
+ /**
727
+ * Class to handle JSON Web Tokens.
718
728
  */
719
729
  class Jwt {
720
730
  /**
@@ -731,9 +741,9 @@ class Jwt {
731
741
  */
732
742
  static async encode(header, payload, key) {
733
743
  core.Guards.object(Jwt._CLASS_NAME, "header", header);
734
- core.Guards.arrayOneOf(Jwt._CLASS_NAME, "header.alg", header.alg, Object.values(JwtAlgorithms));
744
+ core.Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
735
745
  core.Guards.object(Jwt._CLASS_NAME, "payload", payload);
736
- core.Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
746
+ core.Guards.defined(Jwt._CLASS_NAME, "key", key);
737
747
  return Jwt.internalEncode(header, payload, key);
738
748
  }
739
749
  /**
@@ -745,7 +755,7 @@ class Jwt {
745
755
  */
746
756
  static async encodeWithSigner(header, payload, signer) {
747
757
  core.Guards.object(Jwt._CLASS_NAME, "header", header);
748
- core.Guards.arrayOneOf(Jwt._CLASS_NAME, "header.alg", header.alg, Object.values(JwtAlgorithms));
758
+ core.Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
749
759
  core.Guards.object(Jwt._CLASS_NAME, "payload", payload);
750
760
  core.Guards.function(Jwt._CLASS_NAME, "signer", signer);
751
761
  return Jwt.internalEncode(header, payload, undefined, signer);
@@ -792,13 +802,8 @@ class Jwt {
792
802
  */
793
803
  static async verify(token, key) {
794
804
  core.Guards.stringValue(Jwt._CLASS_NAME, "token", token);
795
- core.Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
796
- const decoded = await Jwt.decode(token);
797
- const verified = await Jwt.verifySignature(decoded.header, decoded.payload, decoded.signature, key);
798
- return {
799
- verified,
800
- ...decoded
801
- };
805
+ core.Guards.defined(Jwt._CLASS_NAME, "key", key);
806
+ return Jwt.verifySignature(token, key);
802
807
  }
803
808
  /**
804
809
  * Verify a token.
@@ -809,79 +814,98 @@ class Jwt {
809
814
  static async verifyWithVerifier(token, verifier) {
810
815
  core.Guards.stringValue(Jwt._CLASS_NAME, "token", token);
811
816
  core.Guards.function(Jwt._CLASS_NAME, "verifier", verifier);
812
- core.Guards.stringValue(Jwt._CLASS_NAME, "token", token);
813
- const decoded = await Jwt.decode(token);
814
- const verified = await Jwt.verifySignature(decoded.header, decoded.payload, decoded.signature, undefined, verifier);
815
- return {
816
- verified,
817
- ...decoded
818
- };
817
+ return Jwt.verifySignature(token, undefined, verifier);
819
818
  }
820
819
  /**
821
820
  * Verify a token by parts.
822
- * @param header The header to verify.
823
- * @param payload The payload to verify.
824
- * @param signature The signature to verify.
821
+ * @param token The token to verify.
825
822
  * @param key The key for verifying the token, if not provided no verification occurs.
826
823
  * @param verifier Custom verification method.
827
824
  * @returns True if the parts are verified.
828
825
  */
829
- static async verifySignature(header, payload, signature, key, verifier) {
826
+ static async verifySignature(token, key, verifier) {
827
+ core.Guards.stringValue(Jwt._CLASS_NAME, "token", token);
830
828
  const hasKey = core.Is.notEmpty(key);
831
829
  const hasVerifier = core.Is.notEmpty(verifier);
832
830
  if (!hasKey && !hasVerifier) {
833
831
  throw new core.GeneralError(Jwt._CLASS_NAME, "noKeyOrVerifier");
834
832
  }
835
- let verified = false;
836
- if (core.Is.object(header) &&
837
- core.Is.object(payload) &&
838
- core.Is.uint8Array(signature) &&
839
- core.Is.arrayOneOf(header.alg, Object.values(JwtAlgorithms))) {
840
- const segments = [];
841
- const headerBytes = core.Converter.utf8ToBytes(JSON.stringify(header));
842
- segments.push(core.Converter.bytesToBase64Url(headerBytes));
843
- const payloadBytes = core.Converter.utf8ToBytes(JSON.stringify(payload));
844
- segments.push(core.Converter.bytesToBase64Url(payloadBytes));
845
- const jwtHeaderAndPayload = core.Converter.utf8ToBytes(segments.join("."));
846
- verifier ??= async (alg, k, p, s) => Jwt.defaultVerifier(alg, k, p, s);
847
- verified = await verifier(header.alg, key, jwtHeaderAndPayload, signature);
848
- }
849
- return verified;
833
+ verifier ??= async (t, k) => Jwt.defaultVerifier(t, k);
834
+ return verifier(token, key);
850
835
  }
851
836
  /**
852
837
  * The default signer for the JWT.
853
- * @param alg The algorithm to use.
854
- * @param key The key to sign with.
838
+ * @param header The header to sign.
855
839
  * @param payload The payload to sign.
840
+ * @param key The optional key to sign with.
856
841
  * @returns The signature.
857
842
  */
858
- static async defaultSigner(alg, key, payload) {
859
- core.Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
860
- core.Guards.uint8Array(Jwt._CLASS_NAME, "payload", payload);
861
- if (alg === "HS256") {
862
- const algo = new crypto.HmacSha256(key);
863
- return algo.update(payload).digest();
843
+ static async defaultSigner(header, payload, key) {
844
+ core.Guards.object(Jwt._CLASS_NAME, "header", header);
845
+ core.Guards.object(Jwt._CLASS_NAME, "payload", payload);
846
+ core.Guards.defined(Jwt._CLASS_NAME, "key", key);
847
+ const signer = new jose.SignJWT(payload);
848
+ signer.setProtectedHeader(header);
849
+ if (header.alg === "EdDSA" && core.Is.uint8Array(key)) {
850
+ // crypto.subtle.importKey does not support Ed25519 keys in raw format.
851
+ // We need to convert the key to PKCS8 format before importing.
852
+ // The PKCS8 format is the raw key prefixed with the ASN.1 sequence for an Ed25519 private key.
853
+ // The ASN.1 sequence is 48 46 02 01 00 30 05 06 03 2b 65 70 04 20 04 20
854
+ const pkcs8Prefix = new Uint8Array([
855
+ 48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32
856
+ ]); // 0x302e020100300506032b657004220420
857
+ const pkcs8PrivateKey = core.Uint8ArrayHelper.concat([pkcs8Prefix, key]);
858
+ const imported = await crypto.subtle.importKey("pkcs8", pkcs8PrivateKey, "Ed25519", false, [
859
+ "sign"
860
+ ]);
861
+ return signer.sign(imported);
864
862
  }
865
- return crypto.Ed25519.sign(key, payload);
863
+ return signer.sign(key);
866
864
  }
867
865
  /**
868
866
  * The default verifier for the JWT.
869
- * @param alg The algorithm to use.
867
+ * @param token The token to verify.
870
868
  * @param key The key to verify with.
871
- * @param payload The payload to verify.
872
- * @param signature The signature to verify.
873
869
  * @returns True if the signature was verified.
874
870
  */
875
- static async defaultVerifier(alg, key, payload, signature) {
876
- core.Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
877
- core.Guards.uint8Array(Jwt._CLASS_NAME, "payload", payload);
878
- core.Guards.uint8Array(Jwt._CLASS_NAME, "signature", signature);
879
- if (alg === "HS256") {
880
- const algo = new crypto.HmacSha256(key);
881
- const sigBytes = algo.update(payload).digest();
882
- return core.ArrayHelper.matches(sigBytes, signature);
871
+ static async defaultVerifier(token, key) {
872
+ core.Guards.stringValue(Jwt._CLASS_NAME, "token", token);
873
+ core.Guards.defined(Jwt._CLASS_NAME, "key", key);
874
+ try {
875
+ const result = await jose.jwtVerify(token, key);
876
+ return {
877
+ header: result.protectedHeader,
878
+ payload: result.payload
879
+ };
880
+ }
881
+ catch (err) {
882
+ throw new core.GeneralError(Jwt._CLASS_NAME, "verifyFailed", undefined, err);
883
883
  }
884
- return crypto.Ed25519.verify(key, payload, signature);
884
+ }
885
+ /**
886
+ * Create bytes for signing from header and payload.
887
+ * @param header The header.
888
+ * @param payload The payload.
889
+ * @returns The bytes to sign.
890
+ */
891
+ static createSignBytes(header, payload) {
892
+ const segments = [];
893
+ const headerBytes = core.Converter.utf8ToBytes(JSON.stringify(header));
894
+ segments.push(core.Converter.bytesToBase64Url(headerBytes));
895
+ const payloadBytes = core.Converter.utf8ToBytes(JSON.stringify(payload));
896
+ segments.push(core.Converter.bytesToBase64Url(payloadBytes));
897
+ return core.Converter.utf8ToBytes(segments.join("."));
898
+ }
899
+ /**
900
+ * Create token from bytes and signature.
901
+ * @param signedBytes The signed bytes.
902
+ * @param signature The signature.
903
+ * @returns The token.
904
+ */
905
+ static createTokenFromBytes(signedBytes, signature) {
906
+ const signedBytesUtf8 = core.Converter.bytesToUtf8(signedBytes);
907
+ const signatureBase64 = core.Converter.bytesToBase64Url(signature);
908
+ return `${signedBytesUtf8}.${signatureBase64}`;
885
909
  }
886
910
  /**
887
911
  * Encode a token.
@@ -898,19 +922,11 @@ class Jwt {
898
922
  if (!hasKey && !hasSigner) {
899
923
  throw new core.GeneralError(Jwt._CLASS_NAME, "noKeyOrSigner");
900
924
  }
901
- signer ??= async (alg, k, p) => Jwt.defaultSigner(alg, k, p);
925
+ signer ??= async (h, p, k) => Jwt.defaultSigner(h, p, k);
902
926
  if (core.Is.undefined(header.typ)) {
903
927
  header.typ = "JWT";
904
928
  }
905
- const segments = [];
906
- const headerBytes = core.Converter.utf8ToBytes(JSON.stringify(header));
907
- segments.push(core.Converter.bytesToBase64Url(headerBytes));
908
- const payloadBytes = core.Converter.utf8ToBytes(JSON.stringify(payload));
909
- segments.push(core.Converter.bytesToBase64Url(payloadBytes));
910
- const jwtHeaderAndPayload = core.Converter.utf8ToBytes(segments.join("."));
911
- const sigBytes = await signer(header.alg, key, jwtHeaderAndPayload);
912
- segments.push(core.Converter.bytesToBase64Url(sigBytes));
913
- return segments.join(".");
929
+ return signer(header, payload, key);
914
930
  }
915
931
  }
916
932
 
@@ -1055,7 +1071,7 @@ exports.FetchHelper = FetchHelper;
1055
1071
  exports.HeaderTypes = HeaderTypes;
1056
1072
  exports.HttpMethod = HttpMethod;
1057
1073
  exports.HttpStatusCode = HttpStatusCode;
1074
+ exports.Jwk = Jwk;
1058
1075
  exports.Jwt = Jwt;
1059
- exports.JwtAlgorithms = JwtAlgorithms;
1060
1076
  exports.MimeTypeHelper = MimeTypeHelper;
1061
1077
  exports.MimeTypes = MimeTypes;
@@ -1,5 +1,5 @@
1
- import { BaseError, StringHelper, Guards, Is, AsyncCache, ObjectHelper, Converter, GeneralError, ArrayHelper } from '@twin.org/core';
2
- import { HmacSha256, Ed25519 } from '@twin.org/crypto';
1
+ import { BaseError, StringHelper, Guards, Is, AsyncCache, ObjectHelper, GeneralError, Converter, Uint8ArrayHelper } from '@twin.org/core';
2
+ import { importJWK, SignJWT, jwtVerify } from 'jose';
3
3
 
4
4
  // Copyright 2024 IOTA Stiftung.
5
5
  // SPDX-License-Identifier: Apache-2.0.
@@ -343,23 +343,6 @@ const HttpStatusCode = {
343
343
  networkAuthenticationRequired: 511
344
344
  };
345
345
 
346
- // Copyright 2024 IOTA Stiftung.
347
- // SPDX-License-Identifier: Apache-2.0.
348
- /**
349
- * The cryptographic algorithms supported for JSON Web Tokens and JSON Web Keys.
350
- */
351
- // eslint-disable-next-line @typescript-eslint/naming-convention
352
- const JwtAlgorithms = {
353
- /**
354
- * HMAC using SHA-256.
355
- */
356
- HS256: "HS256",
357
- /**
358
- * EdDSA using Ed25519.
359
- */
360
- EdDSA: "EdDSA"
361
- };
362
-
363
346
  // Copyright 2024 IOTA Stiftung.
364
347
  // SPDX-License-Identifier: Apache-2.0.
365
348
  /**
@@ -712,7 +695,34 @@ class FetchHelper {
712
695
  // Copyright 2024 IOTA Stiftung.
713
696
  // SPDX-License-Identifier: Apache-2.0.
714
697
  /**
715
- * Class to encode and decode JSON Web Tokens.
698
+ * Class to handle JSON Web Keys.
699
+ */
700
+ class Jwk {
701
+ /**
702
+ * Runtime name for the class.
703
+ * @internal
704
+ */
705
+ static _CLASS_NAME = "Jwk";
706
+ /**
707
+ * Convert the JWK to a crypto key.
708
+ * @param jwk The JWK to convert.
709
+ * @returns The crypto key.
710
+ */
711
+ static async toCryptoKey(jwk) {
712
+ Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
713
+ try {
714
+ return importJWK(jwk);
715
+ }
716
+ catch (err) {
717
+ throw new GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
718
+ }
719
+ }
720
+ }
721
+
722
+ // Copyright 2024 IOTA Stiftung.
723
+ // SPDX-License-Identifier: Apache-2.0.
724
+ /**
725
+ * Class to handle JSON Web Tokens.
716
726
  */
717
727
  class Jwt {
718
728
  /**
@@ -729,9 +739,9 @@ class Jwt {
729
739
  */
730
740
  static async encode(header, payload, key) {
731
741
  Guards.object(Jwt._CLASS_NAME, "header", header);
732
- Guards.arrayOneOf(Jwt._CLASS_NAME, "header.alg", header.alg, Object.values(JwtAlgorithms));
742
+ Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
733
743
  Guards.object(Jwt._CLASS_NAME, "payload", payload);
734
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
744
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
735
745
  return Jwt.internalEncode(header, payload, key);
736
746
  }
737
747
  /**
@@ -743,7 +753,7 @@ class Jwt {
743
753
  */
744
754
  static async encodeWithSigner(header, payload, signer) {
745
755
  Guards.object(Jwt._CLASS_NAME, "header", header);
746
- Guards.arrayOneOf(Jwt._CLASS_NAME, "header.alg", header.alg, Object.values(JwtAlgorithms));
756
+ Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
747
757
  Guards.object(Jwt._CLASS_NAME, "payload", payload);
748
758
  Guards.function(Jwt._CLASS_NAME, "signer", signer);
749
759
  return Jwt.internalEncode(header, payload, undefined, signer);
@@ -790,13 +800,8 @@ class Jwt {
790
800
  */
791
801
  static async verify(token, key) {
792
802
  Guards.stringValue(Jwt._CLASS_NAME, "token", token);
793
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
794
- const decoded = await Jwt.decode(token);
795
- const verified = await Jwt.verifySignature(decoded.header, decoded.payload, decoded.signature, key);
796
- return {
797
- verified,
798
- ...decoded
799
- };
803
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
804
+ return Jwt.verifySignature(token, key);
800
805
  }
801
806
  /**
802
807
  * Verify a token.
@@ -807,79 +812,98 @@ class Jwt {
807
812
  static async verifyWithVerifier(token, verifier) {
808
813
  Guards.stringValue(Jwt._CLASS_NAME, "token", token);
809
814
  Guards.function(Jwt._CLASS_NAME, "verifier", verifier);
810
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
811
- const decoded = await Jwt.decode(token);
812
- const verified = await Jwt.verifySignature(decoded.header, decoded.payload, decoded.signature, undefined, verifier);
813
- return {
814
- verified,
815
- ...decoded
816
- };
815
+ return Jwt.verifySignature(token, undefined, verifier);
817
816
  }
818
817
  /**
819
818
  * Verify a token by parts.
820
- * @param header The header to verify.
821
- * @param payload The payload to verify.
822
- * @param signature The signature to verify.
819
+ * @param token The token to verify.
823
820
  * @param key The key for verifying the token, if not provided no verification occurs.
824
821
  * @param verifier Custom verification method.
825
822
  * @returns True if the parts are verified.
826
823
  */
827
- static async verifySignature(header, payload, signature, key, verifier) {
824
+ static async verifySignature(token, key, verifier) {
825
+ Guards.stringValue(Jwt._CLASS_NAME, "token", token);
828
826
  const hasKey = Is.notEmpty(key);
829
827
  const hasVerifier = Is.notEmpty(verifier);
830
828
  if (!hasKey && !hasVerifier) {
831
829
  throw new GeneralError(Jwt._CLASS_NAME, "noKeyOrVerifier");
832
830
  }
833
- let verified = false;
834
- if (Is.object(header) &&
835
- Is.object(payload) &&
836
- Is.uint8Array(signature) &&
837
- Is.arrayOneOf(header.alg, Object.values(JwtAlgorithms))) {
838
- const segments = [];
839
- const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
840
- segments.push(Converter.bytesToBase64Url(headerBytes));
841
- const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
842
- segments.push(Converter.bytesToBase64Url(payloadBytes));
843
- const jwtHeaderAndPayload = Converter.utf8ToBytes(segments.join("."));
844
- verifier ??= async (alg, k, p, s) => Jwt.defaultVerifier(alg, k, p, s);
845
- verified = await verifier(header.alg, key, jwtHeaderAndPayload, signature);
846
- }
847
- return verified;
831
+ verifier ??= async (t, k) => Jwt.defaultVerifier(t, k);
832
+ return verifier(token, key);
848
833
  }
849
834
  /**
850
835
  * The default signer for the JWT.
851
- * @param alg The algorithm to use.
852
- * @param key The key to sign with.
836
+ * @param header The header to sign.
853
837
  * @param payload The payload to sign.
838
+ * @param key The optional key to sign with.
854
839
  * @returns The signature.
855
840
  */
856
- static async defaultSigner(alg, key, payload) {
857
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
858
- Guards.uint8Array(Jwt._CLASS_NAME, "payload", payload);
859
- if (alg === "HS256") {
860
- const algo = new HmacSha256(key);
861
- return algo.update(payload).digest();
841
+ static async defaultSigner(header, payload, key) {
842
+ Guards.object(Jwt._CLASS_NAME, "header", header);
843
+ Guards.object(Jwt._CLASS_NAME, "payload", payload);
844
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
845
+ const signer = new SignJWT(payload);
846
+ signer.setProtectedHeader(header);
847
+ if (header.alg === "EdDSA" && Is.uint8Array(key)) {
848
+ // crypto.subtle.importKey does not support Ed25519 keys in raw format.
849
+ // We need to convert the key to PKCS8 format before importing.
850
+ // The PKCS8 format is the raw key prefixed with the ASN.1 sequence for an Ed25519 private key.
851
+ // The ASN.1 sequence is 48 46 02 01 00 30 05 06 03 2b 65 70 04 20 04 20
852
+ const pkcs8Prefix = new Uint8Array([
853
+ 48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32
854
+ ]); // 0x302e020100300506032b657004220420
855
+ const pkcs8PrivateKey = Uint8ArrayHelper.concat([pkcs8Prefix, key]);
856
+ const imported = await crypto.subtle.importKey("pkcs8", pkcs8PrivateKey, "Ed25519", false, [
857
+ "sign"
858
+ ]);
859
+ return signer.sign(imported);
862
860
  }
863
- return Ed25519.sign(key, payload);
861
+ return signer.sign(key);
864
862
  }
865
863
  /**
866
864
  * The default verifier for the JWT.
867
- * @param alg The algorithm to use.
865
+ * @param token The token to verify.
868
866
  * @param key The key to verify with.
869
- * @param payload The payload to verify.
870
- * @param signature The signature to verify.
871
867
  * @returns True if the signature was verified.
872
868
  */
873
- static async defaultVerifier(alg, key, payload, signature) {
874
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
875
- Guards.uint8Array(Jwt._CLASS_NAME, "payload", payload);
876
- Guards.uint8Array(Jwt._CLASS_NAME, "signature", signature);
877
- if (alg === "HS256") {
878
- const algo = new HmacSha256(key);
879
- const sigBytes = algo.update(payload).digest();
880
- return ArrayHelper.matches(sigBytes, signature);
869
+ static async defaultVerifier(token, key) {
870
+ Guards.stringValue(Jwt._CLASS_NAME, "token", token);
871
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
872
+ try {
873
+ const result = await jwtVerify(token, key);
874
+ return {
875
+ header: result.protectedHeader,
876
+ payload: result.payload
877
+ };
878
+ }
879
+ catch (err) {
880
+ throw new GeneralError(Jwt._CLASS_NAME, "verifyFailed", undefined, err);
881
881
  }
882
- return Ed25519.verify(key, payload, signature);
882
+ }
883
+ /**
884
+ * Create bytes for signing from header and payload.
885
+ * @param header The header.
886
+ * @param payload The payload.
887
+ * @returns The bytes to sign.
888
+ */
889
+ static createSignBytes(header, payload) {
890
+ const segments = [];
891
+ const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
892
+ segments.push(Converter.bytesToBase64Url(headerBytes));
893
+ const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
894
+ segments.push(Converter.bytesToBase64Url(payloadBytes));
895
+ return Converter.utf8ToBytes(segments.join("."));
896
+ }
897
+ /**
898
+ * Create token from bytes and signature.
899
+ * @param signedBytes The signed bytes.
900
+ * @param signature The signature.
901
+ * @returns The token.
902
+ */
903
+ static createTokenFromBytes(signedBytes, signature) {
904
+ const signedBytesUtf8 = Converter.bytesToUtf8(signedBytes);
905
+ const signatureBase64 = Converter.bytesToBase64Url(signature);
906
+ return `${signedBytesUtf8}.${signatureBase64}`;
883
907
  }
884
908
  /**
885
909
  * Encode a token.
@@ -896,19 +920,11 @@ class Jwt {
896
920
  if (!hasKey && !hasSigner) {
897
921
  throw new GeneralError(Jwt._CLASS_NAME, "noKeyOrSigner");
898
922
  }
899
- signer ??= async (alg, k, p) => Jwt.defaultSigner(alg, k, p);
923
+ signer ??= async (h, p, k) => Jwt.defaultSigner(h, p, k);
900
924
  if (Is.undefined(header.typ)) {
901
925
  header.typ = "JWT";
902
926
  }
903
- const segments = [];
904
- const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
905
- segments.push(Converter.bytesToBase64Url(headerBytes));
906
- const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
907
- segments.push(Converter.bytesToBase64Url(payloadBytes));
908
- const jwtHeaderAndPayload = Converter.utf8ToBytes(segments.join("."));
909
- const sigBytes = await signer(header.alg, key, jwtHeaderAndPayload);
910
- segments.push(Converter.bytesToBase64Url(sigBytes));
911
- return segments.join(".");
927
+ return signer(header, payload, key);
912
928
  }
913
929
  }
914
930
 
@@ -1048,4 +1064,4 @@ class MimeTypeHelper {
1048
1064
  }
1049
1065
  }
1050
1066
 
1051
- export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwt, JwtAlgorithms, MimeTypeHelper, MimeTypes };
1067
+ export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwk, Jwt, MimeTypeHelper, MimeTypes };
@@ -7,8 +7,9 @@ export * from "./models/IHttpHeaders";
7
7
  export * from "./models/IJwk";
8
8
  export * from "./models/IJwtHeader";
9
9
  export * from "./models/IJwtPayload";
10
- export * from "./models/jwtAlgorithms";
10
+ export * from "./models/jwkCryptoKey";
11
11
  export * from "./models/mimeTypes";
12
12
  export * from "./utils/fetchHelper";
13
+ export * from "./utils/jwk";
13
14
  export * from "./utils/jwt";
14
15
  export * from "./utils/mimeTypeHelper";
@@ -1,62 +1,6 @@
1
- import type { JwtAlgorithms } from "./jwtAlgorithms";
1
+ import type { JWK } from "jose";
2
2
  /**
3
3
  * The fields in a JSON Web Key.
4
4
  */
5
- export interface IJwk {
6
- /**
7
- * Additional fields in the key.
8
- */
9
- [key: string]: unknown;
10
- /**
11
- * The cryptographic algorithm for the key.
12
- */
13
- alg?: JwtAlgorithms;
14
- /**
15
- * The intended use for the key.
16
- */
17
- use?: string;
18
- /**
19
- * The operation(s) that the key is intended to be used for.
20
- */
21
- key_ops?: string[];
22
- /**
23
- * The key type parameter.
24
- */
25
- kty: string;
26
- /**
27
- * The public key parameters.
28
- */
29
- n?: string;
30
- /**
31
- * Exponent parameter.
32
- */
33
- e?: string;
34
- /**
35
- * The private key parameters.
36
- */
37
- d?: string;
38
- /**
39
- * The private key parameters.
40
- */
41
- p?: string;
42
- /**
43
- * The private key parameters.
44
- */
45
- q?: string;
46
- /**
47
- * The private key parameters.
48
- */
49
- dp?: string;
50
- /**
51
- * The private key parameters.
52
- */
53
- dq?: string;
54
- /**
55
- * The private key parameters.
56
- */
57
- qi?: string;
58
- /**
59
- * The key ID.
60
- */
61
- kid?: string;
5
+ export interface IJwk extends JWK {
62
6
  }
@@ -1,22 +1,6 @@
1
- import type { JwtAlgorithms } from "./jwtAlgorithms";
1
+ import type { JWTHeaderParameters } from "jose";
2
2
  /**
3
3
  * The fields in a JSON Web Token header.
4
4
  */
5
- export interface IJwtHeader {
6
- /**
7
- * Additional fields in the header.
8
- */
9
- [key: string]: unknown;
10
- /**
11
- * The type of the token.
12
- */
13
- typ?: string;
14
- /**
15
- * The algorithm used to sign the token.
16
- */
17
- alg: JwtAlgorithms;
18
- /**
19
- * The key ID.
20
- */
21
- kid?: string;
5
+ export interface IJwtHeader extends JWTHeaderParameters {
22
6
  }