@twin.org/web 0.0.1-next.9 → 0.0.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.
Files changed (35) hide show
  1. package/dist/cjs/index.cjs +288 -90
  2. package/dist/esm/index.mjs +289 -92
  3. package/dist/types/index.d.ts +3 -1
  4. package/dist/types/models/IJwk.d.ts +2 -58
  5. package/dist/types/models/IJwtHeader.d.ts +2 -18
  6. package/dist/types/models/IJwtPayload.d.ts +2 -33
  7. package/dist/types/models/jwkCryptoKey.d.ts +4 -0
  8. package/dist/types/models/mimeTypes.d.ts +8 -0
  9. package/dist/types/utils/fetchHelper.d.ts +7 -0
  10. package/dist/types/utils/jwk.d.ts +41 -0
  11. package/dist/types/utils/jws.d.ts +22 -0
  12. package/dist/types/utils/jwt.d.ts +67 -29
  13. package/docs/changelog.md +381 -1
  14. package/docs/reference/classes/FetchError.md +16 -8
  15. package/docs/reference/classes/FetchHelper.md +104 -28
  16. package/docs/reference/classes/Jwk.md +129 -0
  17. package/docs/reference/classes/Jws.md +81 -0
  18. package/docs/reference/classes/Jwt.md +261 -105
  19. package/docs/reference/classes/MimeTypeHelper.md +9 -5
  20. package/docs/reference/index.md +3 -2
  21. package/docs/reference/interfaces/IHttpHeaders.md +1 -1
  22. package/docs/reference/interfaces/IJwk.md +2 -106
  23. package/docs/reference/interfaces/IJwtHeader.md +5 -23
  24. package/docs/reference/interfaces/IJwtPayload.md +5 -55
  25. package/docs/reference/type-aliases/HeaderTypes.md +1 -1
  26. package/docs/reference/type-aliases/HttpMethod.md +1 -1
  27. package/docs/reference/type-aliases/HttpStatusCode.md +1 -1
  28. package/docs/reference/type-aliases/JwkCryptoKey.md +5 -0
  29. package/docs/reference/type-aliases/MimeTypes.md +1 -1
  30. package/docs/reference/variables/MimeTypes.md +12 -0
  31. package/locales/en.json +11 -1
  32. package/package.json +7 -6
  33. package/dist/types/models/jwtAlgorithms.d.ts +0 -17
  34. package/docs/reference/type-aliases/JwtAlgorithms.md +0 -5
  35. package/docs/reference/variables/JwtAlgorithms.md +0 -19
@@ -1,5 +1,6 @@
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, JsonHelper } from '@twin.org/core';
2
+ import { Ed25519, Sha256 } from '@twin.org/crypto';
3
+ import { importJWK, CompactSign, flattenedVerify, SignJWT, jwtVerify } from 'jose';
3
4
 
4
5
  // Copyright 2024 IOTA Stiftung.
5
6
  // SPDX-License-Identifier: Apache-2.0.
@@ -343,23 +344,6 @@ const HttpStatusCode = {
343
344
  networkAuthenticationRequired: 511
344
345
  };
345
346
 
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
347
  // Copyright 2024 IOTA Stiftung.
364
348
  // SPDX-License-Identifier: Apache-2.0.
365
349
  /**
@@ -387,6 +371,10 @@ const MimeTypes = {
387
371
  * JSON-LD - application/ld+json
388
372
  */
389
373
  JsonLd: "application/ld+json",
374
+ /**
375
+ * JWT - application/jwt
376
+ */
377
+ Jwt: "application/jwt",
390
378
  /**
391
379
  * XML - application/xml
392
380
  */
@@ -399,6 +387,10 @@ const MimeTypes = {
399
387
  * Application GZIP - application/gzip
400
388
  */
401
389
  Gzip: "application/gzip",
390
+ /**
391
+ * Application deflate - application/zlib
392
+ */
393
+ Zlib: "application/zlib",
402
394
  /**
403
395
  * Application BZIP2 - application/x-bzip2
404
396
  */
@@ -553,7 +545,7 @@ class FetchHelper {
553
545
  if (isErr && Is.stringValue(err.message) && err.message.includes("Failed to fetch")) {
554
546
  lastError = new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.connectivity`, HttpStatusCode.serviceUnavailable, {
555
547
  url
556
- });
548
+ }, err);
557
549
  }
558
550
  else {
559
551
  const isAbort = isErr && err.name === "AbortError";
@@ -568,7 +560,7 @@ class FetchHelper {
568
560
  if (isErr && "statusText" in err) {
569
561
  props.statusText = err.statusText;
570
562
  }
571
- lastError = new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.${isAbort ? "timeout" : "general"}`, httpStatus, props);
563
+ lastError = new FetchError(source, `${FetchHelper._CLASS_NAME_CAMEL_CASE}.${isAbort ? "timeout" : "general"}`, httpStatus, props, err);
572
564
  }
573
565
  }
574
566
  finally {
@@ -696,6 +688,15 @@ class FetchHelper {
696
688
  static async getCacheEntry(url) {
697
689
  return AsyncCache.get(`${FetchHelper._CACHE_PREFIX}${url}`);
698
690
  }
691
+ /**
692
+ * Set a cache entry.
693
+ * @param url The url for the request.
694
+ * @param value The value to cache.
695
+ * @returns The cache entry if it exists.
696
+ */
697
+ static async setCacheEntry(url, value) {
698
+ AsyncCache.set(`${FetchHelper._CACHE_PREFIX}${url}`, value);
699
+ }
699
700
  /**
700
701
  * Remove a cache entry.
701
702
  * @param url The url for the request.
@@ -708,7 +709,158 @@ class FetchHelper {
708
709
  // Copyright 2024 IOTA Stiftung.
709
710
  // SPDX-License-Identifier: Apache-2.0.
710
711
  /**
711
- * Class to encode and decode JSON Web Tokens.
712
+ * Class to handle JSON Web Keys.
713
+ */
714
+ class Jwk {
715
+ /**
716
+ * Runtime name for the class.
717
+ * @internal
718
+ */
719
+ static _CLASS_NAME = "Jwk";
720
+ /**
721
+ * Convert the JWK to a crypto key.
722
+ * @param jwk The JWK to convert.
723
+ * @param alg The alg to be used, defaults to jwk.alg.
724
+ * @returns The crypto key.
725
+ */
726
+ static async toCryptoKey(jwk, alg) {
727
+ Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
728
+ try {
729
+ return importJWK(jwk, alg);
730
+ }
731
+ catch (err) {
732
+ throw new GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
733
+ }
734
+ }
735
+ /**
736
+ * Convert the Ed25519 private key to a crypto key.
737
+ * @param privateKey The private key to use.
738
+ * @returns The crypto key.
739
+ */
740
+ static async fromEd25519Private(privateKey) {
741
+ Guards.uint8Array(Jwk._CLASS_NAME, "privateKey", privateKey);
742
+ const publicKey = Ed25519.publicKeyFromPrivateKey(privateKey);
743
+ const jwk = {
744
+ kty: "OKP",
745
+ use: "enc",
746
+ alg: "EdDSA",
747
+ crv: "Ed25519",
748
+ x: Converter.bytesToBase64Url(publicKey),
749
+ d: Converter.bytesToBase64Url(privateKey)
750
+ };
751
+ return jwk;
752
+ }
753
+ /**
754
+ * Convert the Ed25519 public key to a crypto key.
755
+ * @param publicKey The private key to use.
756
+ * @returns The crypto key.
757
+ */
758
+ static async fromEd25519Public(publicKey) {
759
+ Guards.uint8Array(Jwk._CLASS_NAME, "publicKey", publicKey);
760
+ const jwk = {
761
+ kty: "OKP",
762
+ use: "sig",
763
+ alg: "EdDSA",
764
+ crv: "Ed25519",
765
+ x: Converter.bytesToBase64Url(publicKey)
766
+ };
767
+ return jwk;
768
+ }
769
+ /**
770
+ * Convert the JWK to raw keys.
771
+ * @param jwk The JWK to convert to raw.
772
+ * @returns The crypto key.
773
+ */
774
+ static async toRaw(jwk) {
775
+ Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
776
+ let publicKey;
777
+ let privateKey;
778
+ if (Is.stringBase64Url(jwk.x)) {
779
+ publicKey = Converter.base64UrlToBytes(jwk.x);
780
+ }
781
+ if (Is.stringBase64Url(jwk.d)) {
782
+ privateKey = Converter.base64UrlToBytes(jwk.d);
783
+ }
784
+ return {
785
+ publicKey,
786
+ privateKey
787
+ };
788
+ }
789
+ /**
790
+ * Generate a KID for the JWK.
791
+ * @param jwk The JWK to generate a KID for.
792
+ * @returns The KID.
793
+ */
794
+ static async generateKid(jwk) {
795
+ Guards.object(Jwk._CLASS_NAME, "jwk", jwk);
796
+ const kidProps = ObjectHelper.pick(jwk, ["crv", "kty", "x"]);
797
+ const canonicalJson = JsonHelper.canonicalize(kidProps);
798
+ const hash = Sha256.sum256(Converter.utf8ToBytes(canonicalJson));
799
+ return Converter.bytesToBase64Url(hash);
800
+ }
801
+ }
802
+
803
+ // Copyright 2024 IOTA Stiftung.
804
+ // SPDX-License-Identifier: Apache-2.0.
805
+ /**
806
+ * Class to handle JSON Web Signatures.
807
+ */
808
+ class Jws {
809
+ /**
810
+ * Runtime name for the class.
811
+ * @internal
812
+ */
813
+ static _CLASS_NAME = "Jws";
814
+ /**
815
+ * Create a signature.
816
+ * @param privateKey The private key to use.
817
+ * @param hash The hash to sign.
818
+ * @param algOverride An optional algorithm override.
819
+ * @returns The signature.
820
+ */
821
+ static async create(privateKey, hash, algOverride) {
822
+ Guards.defined(Jws._CLASS_NAME, "privateKey", privateKey);
823
+ Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
824
+ try {
825
+ const jws = await new CompactSign(hash)
826
+ .setProtectedHeader({
827
+ alg: algOverride ?? (Is.uint8Array(privateKey) ? "EdDSA" : privateKey.algorithm.name),
828
+ b64: false,
829
+ crit: ["b64"]
830
+ })
831
+ .sign(privateKey);
832
+ return jws;
833
+ }
834
+ catch (err) {
835
+ throw new GeneralError(Jws._CLASS_NAME, "createFailed", undefined, err);
836
+ }
837
+ }
838
+ /**
839
+ * Verify a signature.
840
+ * @param jws The signature to verify.
841
+ * @param publicKey The public key to verify the signature with.
842
+ * @param hash The hash to verify.
843
+ * @returns True if the signature was verified.
844
+ */
845
+ static async verify(jws, publicKey, hash) {
846
+ Guards.stringValue(Jws._CLASS_NAME, "jws", jws);
847
+ Guards.defined(Jws._CLASS_NAME, "publicKey", publicKey);
848
+ Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
849
+ try {
850
+ const jwsParts = jws.split(".");
851
+ await flattenedVerify({ protected: jwsParts[0], payload: hash, signature: jwsParts[2] }, publicKey);
852
+ return true;
853
+ }
854
+ catch (err) {
855
+ throw new GeneralError(Jws._CLASS_NAME, "verifyFailed", undefined, err);
856
+ }
857
+ }
858
+ }
859
+
860
+ // Copyright 2024 IOTA Stiftung.
861
+ // SPDX-License-Identifier: Apache-2.0.
862
+ /**
863
+ * Class to handle JSON Web Tokens.
712
864
  */
713
865
  class Jwt {
714
866
  /**
@@ -725,9 +877,8 @@ class Jwt {
725
877
  */
726
878
  static async encode(header, payload, key) {
727
879
  Guards.object(Jwt._CLASS_NAME, "header", header);
728
- Guards.arrayOneOf(Jwt._CLASS_NAME, "header.alg", header.alg, Object.values(JwtAlgorithms));
729
880
  Guards.object(Jwt._CLASS_NAME, "payload", payload);
730
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
881
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
731
882
  return Jwt.internalEncode(header, payload, key);
732
883
  }
733
884
  /**
@@ -739,7 +890,7 @@ class Jwt {
739
890
  */
740
891
  static async encodeWithSigner(header, payload, signer) {
741
892
  Guards.object(Jwt._CLASS_NAME, "header", header);
742
- Guards.arrayOneOf(Jwt._CLASS_NAME, "header.alg", header.alg, Object.values(JwtAlgorithms));
893
+ Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
743
894
  Guards.object(Jwt._CLASS_NAME, "payload", payload);
744
895
  Guards.function(Jwt._CLASS_NAME, "signer", signer);
745
896
  return Jwt.internalEncode(header, payload, undefined, signer);
@@ -786,13 +937,8 @@ class Jwt {
786
937
  */
787
938
  static async verify(token, key) {
788
939
  Guards.stringValue(Jwt._CLASS_NAME, "token", token);
789
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
790
- const decoded = await Jwt.decode(token);
791
- const verified = await Jwt.verifySignature(decoded.header, decoded.payload, decoded.signature, key);
792
- return {
793
- verified,
794
- ...decoded
795
- };
940
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
941
+ return Jwt.verifySignature(token, key);
796
942
  }
797
943
  /**
798
944
  * Verify a token.
@@ -803,79 +949,131 @@ class Jwt {
803
949
  static async verifyWithVerifier(token, verifier) {
804
950
  Guards.stringValue(Jwt._CLASS_NAME, "token", token);
805
951
  Guards.function(Jwt._CLASS_NAME, "verifier", verifier);
806
- Guards.stringValue(Jwt._CLASS_NAME, "token", token);
807
- const decoded = await Jwt.decode(token);
808
- const verified = await Jwt.verifySignature(decoded.header, decoded.payload, decoded.signature, undefined, verifier);
809
- return {
810
- verified,
811
- ...decoded
812
- };
952
+ return Jwt.verifySignature(token, undefined, verifier);
813
953
  }
814
954
  /**
815
955
  * Verify a token by parts.
816
- * @param header The header to verify.
817
- * @param payload The payload to verify.
818
- * @param signature The signature to verify.
956
+ * @param token The token to verify.
819
957
  * @param key The key for verifying the token, if not provided no verification occurs.
820
958
  * @param verifier Custom verification method.
821
959
  * @returns True if the parts are verified.
822
960
  */
823
- static async verifySignature(header, payload, signature, key, verifier) {
961
+ static async verifySignature(token, key, verifier) {
962
+ Guards.stringValue(Jwt._CLASS_NAME, "token", token);
824
963
  const hasKey = Is.notEmpty(key);
825
964
  const hasVerifier = Is.notEmpty(verifier);
826
965
  if (!hasKey && !hasVerifier) {
827
966
  throw new GeneralError(Jwt._CLASS_NAME, "noKeyOrVerifier");
828
967
  }
829
- let verified = false;
830
- if (Is.object(header) &&
831
- Is.object(payload) &&
832
- Is.uint8Array(signature) &&
833
- Is.arrayOneOf(header.alg, Object.values(JwtAlgorithms))) {
834
- const segments = [];
835
- const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
836
- segments.push(Converter.bytesToBase64Url(headerBytes));
837
- const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
838
- segments.push(Converter.bytesToBase64Url(payloadBytes));
839
- const jwtHeaderAndPayload = Converter.utf8ToBytes(segments.join("."));
840
- verifier ??= async (alg, k, p, s) => Jwt.defaultVerifier(alg, k, p, s);
841
- verified = await verifier(header.alg, key, jwtHeaderAndPayload, signature);
842
- }
843
- return verified;
968
+ verifier ??= async (t, k) => Jwt.defaultVerifier(t, k);
969
+ return verifier(token, key);
844
970
  }
845
971
  /**
846
972
  * The default signer for the JWT.
847
- * @param alg The algorithm to use.
848
- * @param key The key to sign with.
973
+ * @param header The header to sign.
849
974
  * @param payload The payload to sign.
975
+ * @param key The optional key to sign with.
850
976
  * @returns The signature.
851
977
  */
852
- static async defaultSigner(alg, key, payload) {
853
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
854
- Guards.uint8Array(Jwt._CLASS_NAME, "payload", payload);
855
- if (alg === "HS256") {
856
- const algo = new HmacSha256(key);
857
- return algo.update(payload).digest();
978
+ static async defaultSigner(header, payload, key) {
979
+ Guards.object(Jwt._CLASS_NAME, "header", header);
980
+ Guards.object(Jwt._CLASS_NAME, "payload", payload);
981
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
982
+ const signer = new SignJWT(payload);
983
+ signer.setProtectedHeader(header);
984
+ let finalKey = key;
985
+ if (header.alg === "EdDSA" && Is.uint8Array(key)) {
986
+ // Jose does not support Ed25519 keys in raw format, so we need to convert it to PKCS8.
987
+ finalKey = await Ed25519.privateKeyToPkcs8(key);
858
988
  }
859
- return Ed25519.sign(key, payload);
989
+ return signer.sign(finalKey);
860
990
  }
861
991
  /**
862
992
  * The default verifier for the JWT.
863
- * @param alg The algorithm to use.
993
+ * @param token The token to verify.
864
994
  * @param key The key to verify with.
865
- * @param payload The payload to verify.
866
- * @param signature The signature to verify.
867
- * @returns True if the signature was verified.
995
+ * @returns The header and payload if verification successful.
996
+ */
997
+ static async defaultVerifier(token, key) {
998
+ Guards.stringValue(Jwt._CLASS_NAME, "token", token);
999
+ Guards.defined(Jwt._CLASS_NAME, "key", key);
1000
+ try {
1001
+ const result = await jwtVerify(token, key);
1002
+ return {
1003
+ header: result.protectedHeader,
1004
+ payload: result.payload
1005
+ };
1006
+ }
1007
+ catch (err) {
1008
+ throw new GeneralError(Jwt._CLASS_NAME, "verifyFailed", undefined, err);
1009
+ }
1010
+ }
1011
+ /**
1012
+ * Create bytes for signing from header and payload.
1013
+ * @param header The header.
1014
+ * @param payload The payload.
1015
+ * @returns The bytes to sign.
868
1016
  */
869
- static async defaultVerifier(alg, key, payload, signature) {
870
- Guards.uint8Array(Jwt._CLASS_NAME, "key", key);
871
- Guards.uint8Array(Jwt._CLASS_NAME, "payload", payload);
1017
+ static toSigningBytes(header, payload) {
1018
+ Guards.object(Jwt._CLASS_NAME, "header", header);
1019
+ Guards.object(Jwt._CLASS_NAME, "payload", payload);
1020
+ const segments = [];
1021
+ const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
1022
+ segments.push(Converter.bytesToBase64Url(headerBytes));
1023
+ const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
1024
+ segments.push(Converter.bytesToBase64Url(payloadBytes));
1025
+ return Converter.utf8ToBytes(segments.join("."));
1026
+ }
1027
+ /**
1028
+ * Create header and payload from signing bytes.
1029
+ * @param signingBytes The signing bytes from a token.
1030
+ * @returns The header and payload.
1031
+ * @throws If the signing bytes are invalid
1032
+ */
1033
+ static fromSigningBytes(signingBytes) {
1034
+ Guards.uint8Array(Jwt._CLASS_NAME, "signingBytes", signingBytes);
1035
+ const segments = Converter.bytesToUtf8(signingBytes).split(".");
1036
+ if (segments.length !== 2) {
1037
+ throw new GeneralError(Jwt._CLASS_NAME, "invalidSigningBytes");
1038
+ }
1039
+ const headerBytes = Converter.base64UrlToBytes(segments[0]);
1040
+ const payloadBytes = Converter.base64UrlToBytes(segments[1]);
1041
+ return {
1042
+ header: ObjectHelper.fromBytes(headerBytes),
1043
+ payload: ObjectHelper.fromBytes(payloadBytes)
1044
+ };
1045
+ }
1046
+ /**
1047
+ * Convert signed bytes and signature bytes to token.
1048
+ * @param signingBytes The signed bytes.
1049
+ * @param signature The signature.
1050
+ * @returns The token.
1051
+ */
1052
+ static tokenFromBytes(signingBytes, signature) {
1053
+ Guards.uint8Array(Jwt._CLASS_NAME, "signingBytes", signingBytes);
872
1054
  Guards.uint8Array(Jwt._CLASS_NAME, "signature", signature);
873
- if (alg === "HS256") {
874
- const algo = new HmacSha256(key);
875
- const sigBytes = algo.update(payload).digest();
876
- return ArrayHelper.matches(sigBytes, signature);
1055
+ const signedBytesUtf8 = Converter.bytesToUtf8(signingBytes);
1056
+ const signatureBase64 = Converter.bytesToBase64Url(signature);
1057
+ return `${signedBytesUtf8}.${signatureBase64}`;
1058
+ }
1059
+ /**
1060
+ * Convert the token to signing bytes and signature bytes.
1061
+ * @param token The token to convert to bytes.
1062
+ * @returns The decoded bytes.
1063
+ * @throws If the token is invalid.
1064
+ */
1065
+ static tokenToBytes(token) {
1066
+ Guards.stringValue(Jwt._CLASS_NAME, "token", token);
1067
+ const segments = token.split(".");
1068
+ if (segments.length !== 3) {
1069
+ throw new GeneralError(Jwt._CLASS_NAME, "invalidTokenParts");
877
1070
  }
878
- return Ed25519.verify(key, payload, signature);
1071
+ const signingBytes = Converter.utf8ToBytes(`${segments[0]}.${segments[1]}`);
1072
+ const signature = Converter.base64UrlToBytes(segments[2]);
1073
+ return {
1074
+ signingBytes,
1075
+ signature
1076
+ };
879
1077
  }
880
1078
  /**
881
1079
  * Encode a token.
@@ -892,19 +1090,11 @@ class Jwt {
892
1090
  if (!hasKey && !hasSigner) {
893
1091
  throw new GeneralError(Jwt._CLASS_NAME, "noKeyOrSigner");
894
1092
  }
895
- signer ??= async (alg, k, p) => Jwt.defaultSigner(alg, k, p);
1093
+ signer ??= async (h, p, k) => Jwt.defaultSigner(h, p, k);
896
1094
  if (Is.undefined(header.typ)) {
897
1095
  header.typ = "JWT";
898
1096
  }
899
- const segments = [];
900
- const headerBytes = Converter.utf8ToBytes(JSON.stringify(header));
901
- segments.push(Converter.bytesToBase64Url(headerBytes));
902
- const payloadBytes = Converter.utf8ToBytes(JSON.stringify(payload));
903
- segments.push(Converter.bytesToBase64Url(payloadBytes));
904
- const jwtHeaderAndPayload = Converter.utf8ToBytes(segments.join("."));
905
- const sigBytes = await signer(header.alg, key, jwtHeaderAndPayload);
906
- segments.push(Converter.bytesToBase64Url(sigBytes));
907
- return segments.join(".");
1097
+ return signer(header, payload, key);
908
1098
  }
909
1099
  }
910
1100
 
@@ -920,7 +1110,7 @@ class MimeTypeHelper {
920
1110
  * @returns The mime type if detected.
921
1111
  */
922
1112
  static async detect(data) {
923
- if (!Is.uint8Array(data)) {
1113
+ if (!Is.uint8Array(data) || data.length === 0) {
924
1114
  return undefined;
925
1115
  }
926
1116
  // Image
@@ -944,6 +1134,11 @@ class MimeTypeHelper {
944
1134
  if (MimeTypeHelper.checkBytes(data, [0x1f, 0x8b, 0x8])) {
945
1135
  return MimeTypes.Gzip;
946
1136
  }
1137
+ if (MimeTypeHelper.checkBytes(data, [0x78, 0x01]) ||
1138
+ MimeTypeHelper.checkBytes(data, [0x78, 0x9c]) ||
1139
+ MimeTypeHelper.checkBytes(data, [0x78, 0xda])) {
1140
+ return MimeTypes.Zlib;
1141
+ }
947
1142
  if (MimeTypeHelper.checkBytes(data, [0x42, 0x5a, 0x68])) {
948
1143
  return MimeTypes.Bzip2;
949
1144
  }
@@ -992,12 +1187,14 @@ class MimeTypeHelper {
992
1187
  [MimeTypes.Javascript]: "js",
993
1188
  [MimeTypes.Json]: "json",
994
1189
  [MimeTypes.JsonLd]: "jsonld",
1190
+ [MimeTypes.Jwt]: "jwt",
995
1191
  [MimeTypes.Xml]: "xml",
996
1192
  [MimeTypes.OctetStream]: "bin",
997
1193
  [MimeTypes.Gzip]: "gzip",
1194
+ [MimeTypes.Zlib]: "zlib",
998
1195
  [MimeTypes.Bzip2]: "bz2",
999
1196
  [MimeTypes.Zip]: "zip",
1000
- [MimeTypes.Pdf]: "pfd",
1197
+ [MimeTypes.Pdf]: "pdf",
1001
1198
  [MimeTypes.Gif]: "gif",
1002
1199
  [MimeTypes.Bmp]: "bmp",
1003
1200
  [MimeTypes.Jpeg]: "jpeg",
@@ -1043,4 +1240,4 @@ class MimeTypeHelper {
1043
1240
  }
1044
1241
  }
1045
1242
 
1046
- export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwt, JwtAlgorithms, MimeTypeHelper, MimeTypes };
1243
+ export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwk, Jws, Jwt, MimeTypeHelper, MimeTypes };
@@ -7,8 +7,10 @@ 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";
14
+ export * from "./utils/jws";
13
15
  export * from "./utils/jwt";
14
16
  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
  }
@@ -1,37 +1,6 @@
1
+ import type { JWTPayload } from "jose";
1
2
  /**
2
3
  * The fields in a JSON Web Token payload.
3
4
  */
4
- export interface IJwtPayload {
5
- /**
6
- * Additional fields in the payload.
7
- */
8
- [key: string]: unknown;
9
- /**
10
- * The issuer of the token.
11
- */
12
- iss?: string;
13
- /**
14
- * The subject of the token.
15
- */
16
- sub?: string;
17
- /**
18
- * The audience of the token.
19
- */
20
- aud?: string;
21
- /**
22
- * The expiration time of the token.
23
- */
24
- exp?: number;
25
- /**
26
- * The not before time of the token.
27
- */
28
- nbf?: number;
29
- /**
30
- * The issued at time of the token.
31
- */
32
- iat?: number;
33
- /**
34
- * The JWT ID.
35
- */
36
- jti?: string;
5
+ export interface IJwtPayload extends JWTPayload {
37
6
  }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * The crypto key for a JWK.
3
+ */
4
+ export type JwkCryptoKey = CryptoKey | Uint8Array;