@twin.org/web 0.0.1-next.40 → 0.0.1-next.42

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,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@twin.org/core');
4
- var jose = require('jose');
5
4
  var crypto = require('@twin.org/crypto');
5
+ var jose = require('jose');
6
6
 
7
7
  // Copyright 2024 IOTA Stiftung.
8
8
  // SPDX-License-Identifier: Apache-2.0.
@@ -720,6 +720,106 @@ class Jwk {
720
720
  throw new core.GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
721
721
  }
722
722
  }
723
+ /**
724
+ * Convert the Ed25519 private key to a crypto key.
725
+ * @param privateKey The private key to use.
726
+ * @returns The crypto key.
727
+ */
728
+ static async fromEd25519Private(privateKey) {
729
+ core.Guards.uint8Array(Jwk._CLASS_NAME, "privateKey", privateKey);
730
+ try {
731
+ const publicKey = crypto.Ed25519.publicKeyFromPrivateKey(privateKey);
732
+ const jwk = {
733
+ kty: "OKP",
734
+ use: "sig",
735
+ alg: "EdDSA",
736
+ crv: "Ed25519",
737
+ x: core.Converter.bytesToBase64Url(publicKey),
738
+ d: core.Converter.bytesToBase64Url(privateKey)
739
+ };
740
+ return (await jose.importJWK(jwk));
741
+ }
742
+ catch (err) {
743
+ throw new core.GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
744
+ }
745
+ }
746
+ /**
747
+ * Convert the Ed25519 public key to a crypto key.
748
+ * @param publicKey The private key to use.
749
+ * @returns The crypto key.
750
+ */
751
+ static async fromEd25519Public(publicKey) {
752
+ core.Guards.uint8Array(Jwk._CLASS_NAME, "publicKey", publicKey);
753
+ try {
754
+ const jwk = {
755
+ kty: "OKP",
756
+ use: "sig",
757
+ alg: "EdDSA",
758
+ crv: "Ed25519",
759
+ x: core.Converter.bytesToBase64Url(publicKey)
760
+ };
761
+ return (await jose.importJWK(jwk));
762
+ }
763
+ catch (err) {
764
+ throw new core.GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
765
+ }
766
+ }
767
+ }
768
+
769
+ // Copyright 2024 IOTA Stiftung.
770
+ // SPDX-License-Identifier: Apache-2.0.
771
+ /**
772
+ * Class to handle JSON Web Signatures.
773
+ */
774
+ class Jws {
775
+ /**
776
+ * Runtime name for the class.
777
+ * @internal
778
+ */
779
+ static _CLASS_NAME = "Jws";
780
+ /**
781
+ * Create a signature.
782
+ * @param privateKey The private key to use.
783
+ * @param hash The hash to sign.
784
+ * @returns The signature.
785
+ */
786
+ static async create(privateKey, hash) {
787
+ core.Guards.defined(Jws._CLASS_NAME, "privateKey", privateKey);
788
+ core.Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
789
+ try {
790
+ const jws = await new jose.CompactSign(hash)
791
+ .setProtectedHeader({
792
+ alg: privateKey.algorithm.name,
793
+ b64: false,
794
+ crit: ["b64"]
795
+ })
796
+ .sign(privateKey);
797
+ return jws;
798
+ }
799
+ catch (err) {
800
+ throw new core.GeneralError(Jws._CLASS_NAME, "createFailed", undefined, err);
801
+ }
802
+ }
803
+ /**
804
+ * Verify a signature.
805
+ * @param jws The signature to verify.
806
+ * @param publicKey The public key to verify the signature with.
807
+ * @param hash The hash to verify.
808
+ * @returns True if the signature was verified.
809
+ */
810
+ static async verify(jws, publicKey, hash) {
811
+ core.Guards.stringValue(Jws._CLASS_NAME, "jws", jws);
812
+ core.Guards.defined(Jws._CLASS_NAME, "publicKey", publicKey);
813
+ core.Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
814
+ try {
815
+ const jwsParts = jws.split(".");
816
+ await jose.flattenedVerify({ protected: jwsParts[0], payload: hash, signature: jwsParts[2] }, publicKey);
817
+ return true;
818
+ }
819
+ catch (err) {
820
+ throw new core.GeneralError(Jws._CLASS_NAME, "verifyFailed", undefined, err);
821
+ }
822
+ }
723
823
  }
724
824
 
725
825
  // Copyright 2024 IOTA Stiftung.
@@ -742,7 +842,6 @@ class Jwt {
742
842
  */
743
843
  static async encode(header, payload, key) {
744
844
  core.Guards.object(Jwt._CLASS_NAME, "header", header);
745
- core.Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
746
845
  core.Guards.object(Jwt._CLASS_NAME, "payload", payload);
747
846
  core.Guards.defined(Jwt._CLASS_NAME, "key", key);
748
847
  return Jwt.internalEncode(header, payload, key);
@@ -1106,6 +1205,7 @@ exports.HeaderTypes = HeaderTypes;
1106
1205
  exports.HttpMethod = HttpMethod;
1107
1206
  exports.HttpStatusCode = HttpStatusCode;
1108
1207
  exports.Jwk = Jwk;
1208
+ exports.Jws = Jws;
1109
1209
  exports.Jwt = Jwt;
1110
1210
  exports.MimeTypeHelper = MimeTypeHelper;
1111
1211
  exports.MimeTypes = MimeTypes;
@@ -1,6 +1,6 @@
1
1
  import { BaseError, StringHelper, Guards, Is, AsyncCache, ObjectHelper, GeneralError, Converter } from '@twin.org/core';
2
- import { importJWK, SignJWT, jwtVerify } from 'jose';
3
2
  import { Ed25519 } from '@twin.org/crypto';
3
+ import { importJWK, CompactSign, flattenedVerify, SignJWT, jwtVerify } from 'jose';
4
4
 
5
5
  // Copyright 2024 IOTA Stiftung.
6
6
  // SPDX-License-Identifier: Apache-2.0.
@@ -718,6 +718,106 @@ class Jwk {
718
718
  throw new GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
719
719
  }
720
720
  }
721
+ /**
722
+ * Convert the Ed25519 private key to a crypto key.
723
+ * @param privateKey The private key to use.
724
+ * @returns The crypto key.
725
+ */
726
+ static async fromEd25519Private(privateKey) {
727
+ Guards.uint8Array(Jwk._CLASS_NAME, "privateKey", privateKey);
728
+ try {
729
+ const publicKey = Ed25519.publicKeyFromPrivateKey(privateKey);
730
+ const jwk = {
731
+ kty: "OKP",
732
+ use: "sig",
733
+ alg: "EdDSA",
734
+ crv: "Ed25519",
735
+ x: Converter.bytesToBase64Url(publicKey),
736
+ d: Converter.bytesToBase64Url(privateKey)
737
+ };
738
+ return (await importJWK(jwk));
739
+ }
740
+ catch (err) {
741
+ throw new GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
742
+ }
743
+ }
744
+ /**
745
+ * Convert the Ed25519 public key to a crypto key.
746
+ * @param publicKey The private key to use.
747
+ * @returns The crypto key.
748
+ */
749
+ static async fromEd25519Public(publicKey) {
750
+ Guards.uint8Array(Jwk._CLASS_NAME, "publicKey", publicKey);
751
+ try {
752
+ const jwk = {
753
+ kty: "OKP",
754
+ use: "sig",
755
+ alg: "EdDSA",
756
+ crv: "Ed25519",
757
+ x: Converter.bytesToBase64Url(publicKey)
758
+ };
759
+ return (await importJWK(jwk));
760
+ }
761
+ catch (err) {
762
+ throw new GeneralError(Jwk._CLASS_NAME, "jwkImportFailed", undefined, err);
763
+ }
764
+ }
765
+ }
766
+
767
+ // Copyright 2024 IOTA Stiftung.
768
+ // SPDX-License-Identifier: Apache-2.0.
769
+ /**
770
+ * Class to handle JSON Web Signatures.
771
+ */
772
+ class Jws {
773
+ /**
774
+ * Runtime name for the class.
775
+ * @internal
776
+ */
777
+ static _CLASS_NAME = "Jws";
778
+ /**
779
+ * Create a signature.
780
+ * @param privateKey The private key to use.
781
+ * @param hash The hash to sign.
782
+ * @returns The signature.
783
+ */
784
+ static async create(privateKey, hash) {
785
+ Guards.defined(Jws._CLASS_NAME, "privateKey", privateKey);
786
+ Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
787
+ try {
788
+ const jws = await new CompactSign(hash)
789
+ .setProtectedHeader({
790
+ alg: privateKey.algorithm.name,
791
+ b64: false,
792
+ crit: ["b64"]
793
+ })
794
+ .sign(privateKey);
795
+ return jws;
796
+ }
797
+ catch (err) {
798
+ throw new GeneralError(Jws._CLASS_NAME, "createFailed", undefined, err);
799
+ }
800
+ }
801
+ /**
802
+ * Verify a signature.
803
+ * @param jws The signature to verify.
804
+ * @param publicKey The public key to verify the signature with.
805
+ * @param hash The hash to verify.
806
+ * @returns True if the signature was verified.
807
+ */
808
+ static async verify(jws, publicKey, hash) {
809
+ Guards.stringValue(Jws._CLASS_NAME, "jws", jws);
810
+ Guards.defined(Jws._CLASS_NAME, "publicKey", publicKey);
811
+ Guards.uint8Array(Jws._CLASS_NAME, "hash", hash);
812
+ try {
813
+ const jwsParts = jws.split(".");
814
+ await flattenedVerify({ protected: jwsParts[0], payload: hash, signature: jwsParts[2] }, publicKey);
815
+ return true;
816
+ }
817
+ catch (err) {
818
+ throw new GeneralError(Jws._CLASS_NAME, "verifyFailed", undefined, err);
819
+ }
820
+ }
721
821
  }
722
822
 
723
823
  // Copyright 2024 IOTA Stiftung.
@@ -740,7 +840,6 @@ class Jwt {
740
840
  */
741
841
  static async encode(header, payload, key) {
742
842
  Guards.object(Jwt._CLASS_NAME, "header", header);
743
- Guards.stringValue(Jwt._CLASS_NAME, "header.alg", header.alg);
744
843
  Guards.object(Jwt._CLASS_NAME, "payload", payload);
745
844
  Guards.defined(Jwt._CLASS_NAME, "key", key);
746
845
  return Jwt.internalEncode(header, payload, key);
@@ -1098,4 +1197,4 @@ class MimeTypeHelper {
1098
1197
  }
1099
1198
  }
1100
1199
 
1101
- export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwk, Jwt, MimeTypeHelper, MimeTypes };
1200
+ export { FetchError, FetchHelper, HeaderTypes, HttpMethod, HttpStatusCode, Jwk, Jws, Jwt, MimeTypeHelper, MimeTypes };
@@ -11,5 +11,6 @@ export * from "./models/jwkCryptoKey";
11
11
  export * from "./models/mimeTypes";
12
12
  export * from "./utils/fetchHelper";
13
13
  export * from "./utils/jwk";
14
+ export * from "./utils/jws";
14
15
  export * from "./utils/jwt";
15
16
  export * from "./utils/mimeTypeHelper";
@@ -10,4 +10,16 @@ export declare class Jwk {
10
10
  * @returns The crypto key.
11
11
  */
12
12
  static toCryptoKey(jwk: IJwk): Promise<JwkCryptoKey>;
13
+ /**
14
+ * Convert the Ed25519 private key to a crypto key.
15
+ * @param privateKey The private key to use.
16
+ * @returns The crypto key.
17
+ */
18
+ static fromEd25519Private(privateKey: Uint8Array): Promise<CryptoKey>;
19
+ /**
20
+ * Convert the Ed25519 public key to a crypto key.
21
+ * @param publicKey The private key to use.
22
+ * @returns The crypto key.
23
+ */
24
+ static fromEd25519Public(publicKey: Uint8Array): Promise<CryptoKey>;
13
25
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Class to handle JSON Web Signatures.
3
+ */
4
+ export declare class Jws {
5
+ /**
6
+ * Create a signature.
7
+ * @param privateKey The private key to use.
8
+ * @param hash The hash to sign.
9
+ * @returns The signature.
10
+ */
11
+ static create(privateKey: CryptoKey, hash: Uint8Array): Promise<string>;
12
+ /**
13
+ * Verify a signature.
14
+ * @param jws The signature to verify.
15
+ * @param publicKey The public key to verify the signature with.
16
+ * @param hash The hash to verify.
17
+ * @returns True if the signature was verified.
18
+ */
19
+ static verify(jws: string, publicKey: CryptoKey, hash: Uint8Array): Promise<boolean>;
20
+ }
package/docs/changelog.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # @twin.org/web - Changelog
2
2
 
3
- ## 0.0.1-next.40
3
+ ## 0.0.1-next.42
4
4
 
5
5
  - Initial Release
@@ -33,3 +33,47 @@ The JWK to convert.
33
33
  `Promise`\<[`JwkCryptoKey`](../type-aliases/JwkCryptoKey.md)\>
34
34
 
35
35
  The crypto key.
36
+
37
+ ***
38
+
39
+ ### fromEd25519Private()
40
+
41
+ > `static` **fromEd25519Private**(`privateKey`): `Promise`\<`CryptoKey`\>
42
+
43
+ Convert the Ed25519 private key to a crypto key.
44
+
45
+ #### Parameters
46
+
47
+ ##### privateKey
48
+
49
+ `Uint8Array`
50
+
51
+ The private key to use.
52
+
53
+ #### Returns
54
+
55
+ `Promise`\<`CryptoKey`\>
56
+
57
+ The crypto key.
58
+
59
+ ***
60
+
61
+ ### fromEd25519Public()
62
+
63
+ > `static` **fromEd25519Public**(`publicKey`): `Promise`\<`CryptoKey`\>
64
+
65
+ Convert the Ed25519 public key to a crypto key.
66
+
67
+ #### Parameters
68
+
69
+ ##### publicKey
70
+
71
+ `Uint8Array`
72
+
73
+ The private key to use.
74
+
75
+ #### Returns
76
+
77
+ `Promise`\<`CryptoKey`\>
78
+
79
+ The crypto key.
@@ -0,0 +1,75 @@
1
+ # Class: Jws
2
+
3
+ Class to handle JSON Web Signatures.
4
+
5
+ ## Constructors
6
+
7
+ ### new Jws()
8
+
9
+ > **new Jws**(): [`Jws`](Jws.md)
10
+
11
+ #### Returns
12
+
13
+ [`Jws`](Jws.md)
14
+
15
+ ## Methods
16
+
17
+ ### create()
18
+
19
+ > `static` **create**(`privateKey`, `hash`): `Promise`\<`string`\>
20
+
21
+ Create a signature.
22
+
23
+ #### Parameters
24
+
25
+ ##### privateKey
26
+
27
+ `CryptoKey`
28
+
29
+ The private key to use.
30
+
31
+ ##### hash
32
+
33
+ `Uint8Array`
34
+
35
+ The hash to sign.
36
+
37
+ #### Returns
38
+
39
+ `Promise`\<`string`\>
40
+
41
+ The signature.
42
+
43
+ ***
44
+
45
+ ### verify()
46
+
47
+ > `static` **verify**(`jws`, `publicKey`, `hash`): `Promise`\<`boolean`\>
48
+
49
+ Verify a signature.
50
+
51
+ #### Parameters
52
+
53
+ ##### jws
54
+
55
+ `string`
56
+
57
+ The signature to verify.
58
+
59
+ ##### publicKey
60
+
61
+ `CryptoKey`
62
+
63
+ The public key to verify the signature with.
64
+
65
+ ##### hash
66
+
67
+ `Uint8Array`
68
+
69
+ The hash to verify.
70
+
71
+ #### Returns
72
+
73
+ `Promise`\<`boolean`\>
74
+
75
+ True if the signature was verified.
@@ -5,6 +5,7 @@
5
5
  - [FetchError](classes/FetchError.md)
6
6
  - [FetchHelper](classes/FetchHelper.md)
7
7
  - [Jwk](classes/Jwk.md)
8
+ - [Jws](classes/Jws.md)
8
9
  - [Jwt](classes/Jwt.md)
9
10
  - [MimeTypeHelper](classes/MimeTypeHelper.md)
10
11
 
package/locales/en.json CHANGED
@@ -16,6 +16,10 @@
16
16
  },
17
17
  "jwk": {
18
18
  "jwkImportFailed": "Failed to import JWK"
19
+ },
20
+ "jws": {
21
+ "createFailed": "Failed to create JWS",
22
+ "verifyFailed": "Failed to verify JWS"
19
23
  }
20
24
  },
21
25
  "errorMessages": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/web",
3
- "version": "0.0.1-next.40",
3
+ "version": "0.0.1-next.42",
4
4
  "description": "Contains classes for use with web operations",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,8 +14,8 @@
14
14
  "node": ">=20.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/core": "0.0.1-next.40",
18
- "@twin.org/crypto": "0.0.1-next.40",
17
+ "@twin.org/core": "0.0.1-next.42",
18
+ "@twin.org/crypto": "0.0.1-next.42",
19
19
  "@twin.org/nameof": "next",
20
20
  "jose": "6.0.8"
21
21
  },