@icure/api 8.0.0-RC.3 → 8.0.0-RC.4

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 (58) hide show
  1. package/icc-api/api/IccInsuranceApi.d.ts +2 -0
  2. package/icc-api/api/IccInsuranceApi.js +12 -0
  3. package/icc-api/api/IccInsuranceApi.js.map +1 -1
  4. package/icc-api/api/{IccExchangeDataApi.d.ts → internal/IccExchangeDataApi.d.ts} +4 -4
  5. package/icc-api/api/{IccExchangeDataApi.js → internal/IccExchangeDataApi.js} +5 -5
  6. package/icc-api/api/internal/IccExchangeDataApi.js.map +1 -0
  7. package/icc-api/api/{IccExchangeDataMapApi.d.ts → internal/IccExchangeDataMapApi.d.ts} +4 -4
  8. package/icc-api/api/{IccExchangeDataMapApi.js → internal/IccExchangeDataMapApi.js} +5 -5
  9. package/icc-api/api/internal/IccExchangeDataMapApi.js.map +1 -0
  10. package/icc-api/api/internal/IccRecoveryDataApi.d.ts +19 -0
  11. package/icc-api/api/internal/IccRecoveryDataApi.js +83 -0
  12. package/icc-api/api/internal/IccRecoveryDataApi.js.map +1 -0
  13. package/icc-api/api/{IccSecureDelegationKeyMapApi.d.ts → internal/IccSecureDelegationKeyMapApi.d.ts} +6 -6
  14. package/icc-api/api/{IccSecureDelegationKeyMapApi.js → internal/IccSecureDelegationKeyMapApi.js} +5 -5
  15. package/icc-api/api/internal/IccSecureDelegationKeyMapApi.js.map +1 -0
  16. package/icc-api/model/PaginatedListInsurance.d.ts +20 -0
  17. package/icc-api/model/PaginatedListInsurance.js +10 -0
  18. package/icc-api/model/PaginatedListInsurance.js.map +1 -0
  19. package/icc-api/model/User.d.ts +19 -0
  20. package/icc-api/model/User.js +6 -0
  21. package/icc-api/model/User.js.map +1 -1
  22. package/icc-api/model/internal/ExchangeData.d.ts +20 -4
  23. package/icc-api/model/internal/ExchangeData.js +8 -2
  24. package/icc-api/model/internal/ExchangeData.js.map +1 -1
  25. package/icc-api/model/internal/RecoveryData.d.ts +47 -0
  26. package/icc-api/model/internal/RecoveryData.js +34 -0
  27. package/icc-api/model/internal/RecoveryData.js.map +1 -0
  28. package/icc-x-api/auth/JwtBridgedAuthService.d.ts +1 -0
  29. package/icc-x-api/auth/JwtBridgedAuthService.js +10 -3
  30. package/icc-x-api/auth/JwtBridgedAuthService.js.map +1 -1
  31. package/icc-x-api/crypto/BaseExchangeDataManager.d.ts +37 -25
  32. package/icc-x-api/crypto/BaseExchangeDataManager.js +123 -64
  33. package/icc-x-api/crypto/BaseExchangeDataManager.js.map +1 -1
  34. package/icc-x-api/crypto/CryptoPrimitives.d.ts +3 -0
  35. package/icc-x-api/crypto/CryptoPrimitives.js +5 -0
  36. package/icc-x-api/crypto/CryptoPrimitives.js.map +1 -1
  37. package/icc-x-api/crypto/DelegationsDeAnonymization.js +1 -1
  38. package/icc-x-api/crypto/DelegationsDeAnonymization.js.map +1 -1
  39. package/icc-x-api/crypto/ExchangeDataManager.js +14 -6
  40. package/icc-x-api/crypto/ExchangeDataManager.js.map +1 -1
  41. package/icc-x-api/crypto/ExchangeDataMapManager.d.ts +1 -1
  42. package/icc-x-api/crypto/ExchangeDataMapManager.js.map +1 -1
  43. package/icc-x-api/crypto/HMACUtils.d.ts +10 -0
  44. package/icc-x-api/crypto/HMACUtils.js +48 -0
  45. package/icc-x-api/crypto/HMACUtils.js.map +1 -0
  46. package/icc-x-api/crypto/SecureDelegationsManager.js +3 -0
  47. package/icc-x-api/crypto/SecureDelegationsManager.js.map +1 -1
  48. package/icc-x-api/icc-icure-maintenance-x-api.d.ts +1 -1
  49. package/icc-x-api/icc-icure-maintenance-x-api.js.map +1 -1
  50. package/icc-x-api/icc-recovery-x-api.d.ts +0 -0
  51. package/icc-x-api/icc-recovery-x-api.js +2 -0
  52. package/icc-x-api/icc-recovery-x-api.js.map +1 -0
  53. package/icc-x-api/index.js +2 -2
  54. package/icc-x-api/index.js.map +1 -1
  55. package/package.json +1 -1
  56. package/icc-api/api/IccExchangeDataApi.js.map +0 -1
  57. package/icc-api/api/IccExchangeDataMapApi.js.map +0 -1
  58. package/icc-api/api/IccSecureDelegationKeyMapApi.js.map +0 -1
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @internal this entity is meant for internal use only
3
+ */
4
+ export declare class RecoveryData {
5
+ constructor(json: JSON | any);
6
+ id?: string;
7
+ rev?: string;
8
+ /**
9
+ * Id of the data owner that this recovery data is meant for
10
+ */
11
+ recipient: string;
12
+ /**
13
+ * Encrypted recovery data. The structure of the decrypted data depends on the [type] of the recovery data.
14
+ */
15
+ encryptedSelf: string;
16
+ /**
17
+ * Type of the recovery data.
18
+ */
19
+ type: RecoveryData.Type;
20
+ /**
21
+ * Timestamp (unix epoch in ms) at which this recovery data will expire. If null, this recovery data will never
22
+ * expire. Negative values or zero mean the data is already expired.
23
+ */
24
+ expirationInstant?: number;
25
+ /**
26
+ * hard delete (unix epoch in ms) timestamp of the object. Filled automatically when the delete method is called.
27
+ */
28
+ deletionDate?: number;
29
+ }
30
+ export declare namespace RecoveryData {
31
+ /**
32
+ * Represents possible types of recovery data.
33
+ */
34
+ enum Type {
35
+ /**
36
+ * This recovery data is meant to be used to recover a keypair of the recipient. This could be for making a key
37
+ * available on another device, or for recovering a keypair that has been fully lost.
38
+ */
39
+ KEYPAIR_RECOVERY = "KEYPAIR_RECOVERY",
40
+ /**
41
+ * This recovery data is meant to be used to recover an exchange key of the recipient. The main purpose of this
42
+ * is to allow data owners to share data with other data owners that do not have created a keypair yet, but it
43
+ * can also be used as part of the give-access-back recovery mechanism.
44
+ */
45
+ EXCHANGE_KEY_RECOVERY = "EXCHANGE_KEY_RECOVERY"
46
+ }
47
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RecoveryData = void 0;
4
+ /**
5
+ * @internal this entity is meant for internal use only
6
+ */
7
+ class RecoveryData {
8
+ constructor(json) {
9
+ if (!json.recipient || !json.encryptedSelf || !json.type)
10
+ throw new Error(`Recovery data json is missing required properties.\n${JSON.stringify(json)}`);
11
+ Object.assign(this, json);
12
+ }
13
+ }
14
+ exports.RecoveryData = RecoveryData;
15
+ (function (RecoveryData) {
16
+ /**
17
+ * Represents possible types of recovery data.
18
+ */
19
+ let Type;
20
+ (function (Type) {
21
+ /**
22
+ * This recovery data is meant to be used to recover a keypair of the recipient. This could be for making a key
23
+ * available on another device, or for recovering a keypair that has been fully lost.
24
+ */
25
+ Type["KEYPAIR_RECOVERY"] = "KEYPAIR_RECOVERY";
26
+ /**
27
+ * This recovery data is meant to be used to recover an exchange key of the recipient. The main purpose of this
28
+ * is to allow data owners to share data with other data owners that do not have created a keypair yet, but it
29
+ * can also be used as part of the give-access-back recovery mechanism.
30
+ */
31
+ Type["EXCHANGE_KEY_RECOVERY"] = "EXCHANGE_KEY_RECOVERY";
32
+ })(Type = RecoveryData.Type || (RecoveryData.Type = {}));
33
+ })(RecoveryData = exports.RecoveryData || (exports.RecoveryData = {}));
34
+ //# sourceMappingURL=RecoveryData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecoveryData.js","sourceRoot":"","sources":["../../../../icc-api/model/internal/RecoveryData.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,YAAY;IACvB,YAAY,IAAgB;QAC1B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,IAAI;YACtD,MAAM,IAAI,KAAK,CAAC,uDAAuD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChG,MAAM,CAAC,MAAM,CAAC,IAAoB,EAAE,IAAI,CAAC,CAAA;IAC3C,CAAC;CAyBF;AA9BD,oCA8BC;AACD,WAAiB,YAAY;IAC3B;;OAEG;IACH,IAAY,IAYX;IAZD,WAAY,IAAI;QACd;;;WAGG;QACH,6CAAqC,CAAA;QACrC;;;;WAIG;QACH,uDAA+C,CAAA;IACjD,CAAC,EAZW,IAAI,GAAJ,iBAAI,KAAJ,iBAAI,QAYf;AACH,CAAC,EAjBgB,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAiB5B","sourcesContent":["/**\n * @internal this entity is meant for internal use only\n */\nexport class RecoveryData {\n constructor(json: JSON | any) {\n if (!json.recipient || !json.encryptedSelf || !json.type)\n throw new Error(`Recovery data json is missing required properties.\\n${JSON.stringify(json)}`)\n Object.assign(this as RecoveryData, json)\n }\n\n id?: string\n rev?: string\n /**\n * Id of the data owner that this recovery data is meant for\n */\n recipient!: string\n /**\n * Encrypted recovery data. The structure of the decrypted data depends on the [type] of the recovery data.\n */\n encryptedSelf!: string\n /**\n * Type of the recovery data.\n */\n type!: RecoveryData.Type\n /**\n * Timestamp (unix epoch in ms) at which this recovery data will expire. If null, this recovery data will never\n * expire. Negative values or zero mean the data is already expired.\n */\n expirationInstant?: number\n /**\n * hard delete (unix epoch in ms) timestamp of the object. Filled automatically when the delete method is called.\n */\n deletionDate?: number\n}\nexport namespace RecoveryData {\n /**\n * Represents possible types of recovery data.\n */\n export enum Type {\n /**\n * This recovery data is meant to be used to recover a keypair of the recipient. This could be for making a key\n * available on another device, or for recovering a keypair that has been fully lost.\n */\n KEYPAIR_RECOVERY = 'KEYPAIR_RECOVERY',\n /**\n * This recovery data is meant to be used to recover an exchange key of the recipient. The main purpose of this\n * is to allow data owners to share data with other data owners that do not have created a keypair yet, but it\n * can also be used as part of the give-access-back recovery mechanism.\n */\n EXCHANGE_KEY_RECOVERY = 'EXCHANGE_KEY_RECOVERY',\n }\n}\n"]}
@@ -20,6 +20,7 @@ export declare class JwtBridgedAuthService implements AuthService {
20
20
  token: string;
21
21
  refreshToken: string;
22
22
  } | undefined>;
23
+ getJWT(): Promise<string | undefined>;
23
24
  getAuthHeaders(): Promise<Array<Header>>;
24
25
  private _refreshAuthJwt;
25
26
  private _loginAndGetTokens;
@@ -32,7 +32,7 @@ class JwtBridgedAuthService {
32
32
  getIcureTokens() {
33
33
  return this.getAuthHeaders().then(() => this._currentPromise.then(({ authJwt, refreshJwt }) => ({ token: authJwt, refreshToken: refreshJwt })));
34
34
  }
35
- getAuthHeaders() {
35
+ getJWT() {
36
36
  return __awaiter(this, void 0, void 0, function* () {
37
37
  return this._currentPromise
38
38
  .then(({ authJwt, refreshJwt }) => {
@@ -52,8 +52,15 @@ class JwtBridgedAuthService {
52
52
  throw this._error;
53
53
  }
54
54
  return this._currentPromise;
55
- })
56
- .then(({ authJwt }) => {
55
+ }).then(({ authJwt }) => {
56
+ return authJwt;
57
+ });
58
+ });
59
+ }
60
+ getAuthHeaders() {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ return this.getJWT()
63
+ .then((authJwt) => {
57
64
  return [new XHR_1.XHR.Header('Authorization', `Bearer ${authJwt}`)];
58
65
  });
59
66
  });
@@ -1 +1 @@
1
- {"version":3,"file":"JwtBridgedAuthService.js","sourceRoot":"","sources":["../../../icc-x-api/auth/JwtBridgedAuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthService } from './AuthService'\nimport { XHR } from '../../icc-api/api/XHR'\nimport { IccAuthApi, OAuthThirdParty } from '../../icc-api'\nimport { LoginCredentials } from '../../icc-api/model/LoginCredentials'\nimport Header = XHR.Header\nimport { a2b } from '../utils'\nimport { AuthenticationResponse } from '../../icc-api/model/AuthenticationResponse'\nimport XHRError = XHR.XHRError\n\n/**\n * Differs from JwtAuthService in that it can create new refresh tokens if the old one is expired\n */\nexport class JwtBridgedAuthService implements AuthService {\n private _error: Error | null = null\n private _currentPromise: Promise<{ authJwt?: string; refreshJwt?: string }> = Promise.resolve({})\n\n constructor(\n private authApi: IccAuthApi,\n private username: string,\n private password: string,\n private thirdPartyTokens: { [thirdParty: string]: string } = {}\n ) {}\n\n get refreshToken(): Promise<string | undefined> {\n return this._currentPromise.then((x) => x.refreshJwt as any)\n }\n getIcureTokens(): Promise<{ token: string; refreshToken: string } | undefined> {\n return this.getAuthHeaders().then(() => this._currentPromise.then(({ authJwt, refreshJwt }) => ({ token: authJwt!, refreshToken: refreshJwt! })))\n }\n\n async getAuthHeaders(): Promise<Array<Header>> {\n return this._currentPromise\n .then(({ authJwt, refreshJwt }) => {\n if (!authJwt || this._isJwtInvalidOrExpired(authJwt)) {\n // If it does not have the JWT, tries to get it\n // If the JWT is expired, tries to refresh it\n\n this._currentPromise = this._refreshAuthJwt(refreshJwt).then((updatedTokens) => {\n // If here the token is null,\n // it goes in a suspension status\n if (!updatedTokens.authJwt) {\n throw new Error('Your iCure back-end version does not support JWT authentication')\n }\n\n return updatedTokens\n })\n } else if (!!this._error) {\n throw this._error\n }\n return this._currentPromise\n })\n .then(({ authJwt }) => {\n return [new XHR.Header('Authorization', `Bearer ${authJwt}`)]\n })\n }\n\n private async _refreshAuthJwt(refreshJwt: string | undefined): Promise<{ authJwt?: string; refreshJwt?: string }> {\n // If I do not have a refresh JWT or the refresh JWT is expired,\n // I have to log in again\n if (!refreshJwt || this._isJwtInvalidOrExpired(refreshJwt)) {\n return this._loginAndGetTokens()\n } else {\n return this.authApi.refreshAuthenticationJWT(refreshJwt).then((refreshResponse) => ({\n authJwt: refreshResponse.token,\n refreshJwt: refreshJwt,\n }))\n }\n }\n\n private async _loginAndGetTokens(): Promise<{ authJwt?: string; refreshJwt?: string }> {\n let authResponse: AuthenticationResponse | undefined\n let firstError: XHRError | undefined\n if (this.username && this.password) {\n try {\n authResponse = await this.authApi.login(\n new LoginCredentials({\n username: this.username,\n password: this.password,\n })\n )\n } catch (e) {\n firstError = e as XHRError\n }\n }\n if (!authResponse) {\n authResponse = await (Object.entries(this.thirdPartyTokens) as [OAuthThirdParty, string][]).reduce(async (acc, [thirdParty, token]) => {\n const prev = await acc\n return (\n prev ??\n (token\n ? this.authApi.loginWithThirdPartyToken(thirdParty, token).catch((e) => {\n if (!firstError) {\n firstError = e as XHRError\n }\n return Promise.resolve() as Promise<undefined>\n })\n : undefined)\n )\n }, Promise.resolve() as Promise<AuthenticationResponse | undefined>)\n }\n\n if (!authResponse) {\n if (firstError) throw firstError\n throw new XHRError('', 'Unknown error', 401, 'Unauthorized', new Headers())\n }\n\n return {\n authJwt: authResponse.token,\n refreshJwt: authResponse.refreshToken,\n }\n }\n\n private _isJwtInvalidOrExpired(jwt: string): boolean {\n const parts = jwt.split('.')\n if (parts.length !== 3) {\n return true\n }\n const payload = this._base64Decode(parts[1])\n // Using the 'exp' string is safe to use as it is part of the JWT RFC and cannot be modified by us.\n return !('exp' in payload) || payload['exp'] * 1000 < new Date().getTime()\n }\n\n private _base64Decode(encodedString: string): any {\n return JSON.parse(a2b(encodedString))\n }\n\n invalidateHeader(error: Error): void {\n this._error = error\n }\n\n isInErrorState(): boolean {\n return !!this._error\n }\n}\n"]}
1
+ {"version":3,"file":"JwtBridgedAuthService.js","sourceRoot":"","sources":["../../../icc-x-api/auth/JwtBridgedAuthService.ts"],"names":[],"mappings":"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","sourcesContent":["import { AuthService } from './AuthService'\nimport { XHR } from '../../icc-api/api/XHR'\nimport { IccAuthApi, OAuthThirdParty } from '../../icc-api'\nimport { LoginCredentials } from '../../icc-api/model/LoginCredentials'\nimport Header = XHR.Header\nimport { a2b } from '../utils'\nimport { AuthenticationResponse } from '../../icc-api/model/AuthenticationResponse'\nimport XHRError = XHR.XHRError\n\n/**\n * Differs from JwtAuthService in that it can create new refresh tokens if the old one is expired\n */\nexport class JwtBridgedAuthService implements AuthService {\n private _error: Error | null = null\n private _currentPromise: Promise<{ authJwt?: string; refreshJwt?: string }> = Promise.resolve({})\n\n constructor(\n private authApi: IccAuthApi,\n private username: string,\n private password: string,\n private thirdPartyTokens: { [thirdParty: string]: string } = {}\n ) {}\n\n get refreshToken(): Promise<string | undefined> {\n return this._currentPromise.then((x) => x.refreshJwt as any)\n }\n getIcureTokens(): Promise<{ token: string; refreshToken: string } | undefined> {\n return this.getAuthHeaders().then(() => this._currentPromise.then(({ authJwt, refreshJwt }) => ({ token: authJwt!, refreshToken: refreshJwt! })))\n }\n\n async getJWT(): Promise<string | undefined> {\n return this._currentPromise\n .then(({ authJwt, refreshJwt }) => {\n if (!authJwt || this._isJwtInvalidOrExpired(authJwt)) {\n // If it does not have the JWT, tries to get it\n // If the JWT is expired, tries to refresh it\n\n this._currentPromise = this._refreshAuthJwt(refreshJwt).then((updatedTokens) => {\n // If here the token is null,\n // it goes in a suspension status\n if (!updatedTokens.authJwt) {\n throw new Error('Your iCure back-end version does not support JWT authentication')\n }\n\n return updatedTokens\n })\n } else if (!!this._error) {\n throw this._error\n }\n return this._currentPromise\n }).then(({authJwt}) => {\n return authJwt\n })\n }\n\n async getAuthHeaders(): Promise<Array<Header>> {\n return this.getJWT()\n .then((authJwt) => {\n return [new XHR.Header('Authorization', `Bearer ${authJwt}`)]\n })\n }\n\n private async _refreshAuthJwt(refreshJwt: string | undefined): Promise<{ authJwt?: string; refreshJwt?: string }> {\n // If I do not have a refresh JWT or the refresh JWT is expired,\n // I have to log in again\n if (!refreshJwt || this._isJwtInvalidOrExpired(refreshJwt)) {\n return this._loginAndGetTokens()\n } else {\n return this.authApi.refreshAuthenticationJWT(refreshJwt).then((refreshResponse) => ({\n authJwt: refreshResponse.token,\n refreshJwt: refreshJwt,\n }))\n }\n }\n\n private async _loginAndGetTokens(): Promise<{ authJwt?: string; refreshJwt?: string }> {\n let authResponse: AuthenticationResponse | undefined\n let firstError: XHRError | undefined\n if (this.username && this.password) {\n try {\n authResponse = await this.authApi.login(\n new LoginCredentials({\n username: this.username,\n password: this.password,\n })\n )\n } catch (e) {\n firstError = e as XHRError\n }\n }\n if (!authResponse) {\n authResponse = await (Object.entries(this.thirdPartyTokens) as [OAuthThirdParty, string][]).reduce(async (acc, [thirdParty, token]) => {\n const prev = await acc\n return (\n prev ??\n (token\n ? this.authApi.loginWithThirdPartyToken(thirdParty, token).catch((e) => {\n if (!firstError) {\n firstError = e as XHRError\n }\n return Promise.resolve() as Promise<undefined>\n })\n : undefined)\n )\n }, Promise.resolve() as Promise<AuthenticationResponse | undefined>)\n }\n\n if (!authResponse) {\n if (firstError) throw firstError\n throw new XHRError('', 'Unknown error', 401, 'Unauthorized', new Headers())\n }\n\n return {\n authJwt: authResponse.token,\n refreshJwt: authResponse.refreshToken,\n }\n }\n\n private _isJwtInvalidOrExpired(jwt: string): boolean {\n const parts = jwt.split('.')\n if (parts.length !== 3) {\n return true\n }\n const payload = this._base64Decode(parts[1])\n // Using the 'exp' string is safe to use as it is part of the JWT RFC and cannot be modified by us.\n return !('exp' in payload) || payload['exp'] * 1000 < new Date().getTime()\n }\n\n private _base64Decode(encodedString: string): any {\n return JSON.parse(a2b(encodedString))\n }\n\n invalidateHeader(error: Error): void {\n this._error = error\n }\n\n isInErrorState(): boolean {\n return !!this._error\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { IccDataOwnerXApi } from '../icc-data-owner-x-api';
2
2
  import { KeyPair } from './RSA';
3
3
  import { ExchangeData } from '../../icc-api/model/internal/ExchangeData';
4
- import { IccExchangeDataApi } from '../../icc-api/api/IccExchangeDataApi';
4
+ import { IccExchangeDataApi } from '../../icc-api/api/internal/IccExchangeDataApi';
5
5
  import { CryptoPrimitives } from './CryptoPrimitives';
6
6
  /**
7
7
  * @internal this class is intended for internal use only and may be modified without notice
@@ -35,27 +35,27 @@ export declare class BaseExchangeDataManager {
35
35
  * @return the exchange data with the provided id or undefined if no exchange data with such id could be found.
36
36
  */
37
37
  getExchangeDataById(exchangeDataId: string): Promise<ExchangeData | undefined>;
38
- /**
39
- * Filters exchange data returning only the instances that could be verified using their signature and the provided verification
40
- * keys.
41
- * Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
42
- * will always be unverified.
43
- * @param exchangeData the exchange data to verify.
44
- * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
45
- * @return the exchange data which could be verified given his signature and the available verification keys.
46
- * @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
47
- */
48
- filterVerifiedExchangeData(exchangeData: ExchangeData[], getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>): Promise<ExchangeData[]>;
49
38
  /**
50
39
  * Verifies the authenticity of the exchange data by checking the signature.
51
40
  * Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
52
41
  * will always be unverified.
53
- * @param exchangeData the exchange data to verify.
42
+ * @param data collects the following information about the exchange data being verified:
43
+ * - exchangeData the exchange data to verify.
44
+ * - decryptedAccessControlSecret the access control secret decrypted from the exchange data.
45
+ * - decryptedExchangeKey the exchange key decrypted from the exchange data.
46
+ * - decryptedSharedSignatureKey the shared signature key decrypted from the exchange data.
54
47
  * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
48
+ * @param verifyAsDelegator if true the method will also verify that the hmac key used for the signature was created by the delegator of the
49
+ * exchange data. If true and the data was not created by the current data owner this method will return false.
55
50
  * @return the exchange data which could be verified given his signature and the available verification keys.
56
51
  * @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
57
52
  */
58
- verifyExchangeData(exchangeData: ExchangeData, getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>): Promise<boolean>;
53
+ verifyExchangeData(data: {
54
+ exchangeData: ExchangeData;
55
+ decryptedAccessControlSecret: string;
56
+ decryptedExchangeKey: CryptoKey;
57
+ decryptedSharedSignatureKey: CryptoKey;
58
+ }, getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>, verifyAsDelegator: boolean): Promise<boolean>;
59
59
  /**
60
60
  * Extracts and decrypts the access control secret from the provided exchange data.
61
61
  * These need to be hashed together with the entity class and confidentiality level in order to get the actual access control key
@@ -86,6 +86,20 @@ export declare class BaseExchangeDataManager {
86
86
  successfulDecryptions: CryptoKey[];
87
87
  failedDecryptions: ExchangeData[];
88
88
  }>;
89
+ /**
90
+ * Extract and decrypts the shared signature key from the provided exchange data.
91
+ * @param exchangeData the exchange data from which to extract exchange keys.
92
+ * @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.
93
+ * @return an object composed of:
94
+ * - successfulDecryptions: array containing the successfully decrypted exchange keys.
95
+ * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).
96
+ */
97
+ tryDecryptSharedSignatureKeys(exchangeData: ExchangeData[], decryptionKeys: {
98
+ [publicKeyFingerprint: string]: KeyPair<CryptoKey>;
99
+ }): Promise<{
100
+ successfulDecryptions: CryptoKey[];
101
+ failedDecryptions: ExchangeData[];
102
+ }>;
89
103
  private tryDecryptExchangeData;
90
104
  private tryDecrypt;
91
105
  /**
@@ -113,15 +127,9 @@ export declare class BaseExchangeDataManager {
113
127
  * where one of the data owners involved in the exchange data has lost one of his keys.
114
128
  * If the content of the exchange data could not be decrypted using the provided keys the method will not update anything and will return undefined.
115
129
  * This method assumes that the new encryption keys have been verified.
116
- * If the current data owner is also the delegator of the provided exchange data and at least one of the verification keys can be used to
117
- * validate the current exchange data then the signature will be updated using the signature keys.
118
- * Instead, if the current data owner is not the delegator of the provided exchange data, or the exchange data could not be verified using
119
- * the provided verification keys then the updated exchange data will become unverified, and won't ever be verifiable again.
120
130
  * @param exchangeData exchange data to update.
121
131
  * @param decryptionKeys keys to use to extract the content of the exchange data which will be shared with the new keys.
122
- * @param signatureKeys keys to use for the new signature of the updated exchange data.
123
132
  * @param newEncryptionKeys new keys to add to the exchange data.
124
- * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
125
133
  * @return the updated exchange data, and its decrypted exchange key and access control secret, or undefined if the exchange data content could not
126
134
  * be decrypted and the exchange data could not be updated.
127
135
  */
@@ -129,18 +137,22 @@ export declare class BaseExchangeDataManager {
129
137
  [publicKeyFingerprint: string]: KeyPair<CryptoKey>;
130
138
  }, newEncryptionKeys: {
131
139
  [keyPairFingerprint: string]: CryptoKey;
132
- }, signatureKeys: {
133
- [keyPairFingerprint: string]: CryptoKey;
134
- }, getVerificationKey: (publicKeyFingerprint: string) => Promise<CryptoKey | undefined>): Promise<{
140
+ }): Promise<{
135
141
  exchangeData: ExchangeData;
136
142
  exchangeKey: CryptoKey;
137
143
  accessControlSecret: string;
138
144
  } | undefined>;
139
- private bytesToSign;
145
+ private bytesToSignForSharedSignature;
146
+ private bytesToSignForDelegatorSignature;
140
147
  private generateExchangeKey;
141
148
  private importExchangeKey;
149
+ private generateSharedSignatureKey;
150
+ private importSharedSignatureKey;
142
151
  private generateAccessControlSecret;
143
152
  private importAccessControlSecret;
144
153
  private encryptDataWithKeys;
145
- private signDataWithKeys;
154
+ private signDataWithDelegatorKeys;
155
+ private verifyDelegatorSignature;
156
+ private signDataWithSharedKey;
157
+ private verifyDataWithSharedKey;
146
158
  }
@@ -78,47 +78,41 @@ class BaseExchangeDataManager {
78
78
  });
79
79
  });
80
80
  }
81
- /**
82
- * Filters exchange data returning only the instances that could be verified using their signature and the provided verification
83
- * keys.
84
- * Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
85
- * will always be unverified.
86
- * @param exchangeData the exchange data to verify.
87
- * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
88
- * @return the exchange data which could be verified given his signature and the available verification keys.
89
- * @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
90
- */
91
- filterVerifiedExchangeData(exchangeData, getVerificationKey) {
92
- return __awaiter(this, void 0, void 0, function* () {
93
- const verified = [];
94
- for (const ed of exchangeData) {
95
- if (yield this.verifyExchangeData(ed, (x) => getVerificationKey(x)))
96
- verified.push(ed);
97
- }
98
- return verified;
99
- });
100
- }
101
81
  /**
102
82
  * Verifies the authenticity of the exchange data by checking the signature.
103
83
  * Note that all exchange data created by data owners other than the current data owner (including members of his hierarchy)
104
84
  * will always be unverified.
105
- * @param exchangeData the exchange data to verify.
85
+ * @param data collects the following information about the exchange data being verified:
86
+ * - exchangeData the exchange data to verify.
87
+ * - decryptedAccessControlSecret the access control secret decrypted from the exchange data.
88
+ * - decryptedExchangeKey the exchange key decrypted from the exchange data.
89
+ * - decryptedSharedSignatureKey the shared signature key decrypted from the exchange data.
106
90
  * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
91
+ * @param verifyAsDelegator if true the method will also verify that the hmac key used for the signature was created by the delegator of the
92
+ * exchange data. If true and the data was not created by the current data owner this method will return false.
107
93
  * @return the exchange data which could be verified given his signature and the available verification keys.
108
94
  * @throws if any of the provided exchange data has been created by a data owner other than the current data owner.
109
95
  */
110
- verifyExchangeData(exchangeData, getVerificationKey) {
96
+ verifyExchangeData(data, getVerificationKey, verifyAsDelegator) {
111
97
  return __awaiter(this, void 0, void 0, function* () {
112
- const dataOwnerId = yield this.dataOwnerApi.getCurrentDataOwnerId();
113
- if (exchangeData.delegator !== dataOwnerId)
98
+ if (verifyAsDelegator && data.exchangeData.delegator !== (yield this.dataOwnerApi.getCurrentDataOwnerId()))
114
99
  return false;
115
- const signatureData = yield this.bytesToSign(exchangeData);
116
- for (const [fp, signature] of Object.entries(exchangeData.signature)) {
117
- const verificationKey = yield getVerificationKey(fp.slice(-32));
118
- if (verificationKey && (yield this.primitives.RSA.verifySignature(verificationKey, (0, utils_1.b64_2ua)(signature), signatureData)))
119
- return true;
120
- }
121
- return false;
100
+ if (verifyAsDelegator && !(yield this.verifyDelegatorSignature(data.exchangeData, data.decryptedSharedSignatureKey, getVerificationKey)))
101
+ return false;
102
+ const sharedSignatureData = yield this.bytesToSignForSharedSignature({
103
+ decryptedAccessControlSecret: data.decryptedAccessControlSecret,
104
+ decryptedExchangeKey: data.decryptedExchangeKey,
105
+ delegator: data.exchangeData.delegator,
106
+ delegate: data.exchangeData.delegate,
107
+ publicKeysFingerprintsV2: [
108
+ ...new Set([
109
+ ...Object.keys(data.exchangeData.exchangeKey),
110
+ ...Object.keys(data.exchangeData.accessControlSecret),
111
+ ...Object.keys(data.exchangeData.sharedSignatureKey),
112
+ ]),
113
+ ],
114
+ });
115
+ return yield this.verifyDataWithSharedKey(sharedSignatureData, data.decryptedSharedSignatureKey, data.exchangeData.sharedSignature);
122
116
  });
123
117
  }
124
118
  /**
@@ -149,6 +143,19 @@ class BaseExchangeDataManager {
149
143
  return yield this.tryDecryptExchangeData(exchangeData, decryptionKeys, (ed) => ed.exchangeKey, (d) => this.importExchangeKey(new Uint8Array(d)));
150
144
  });
151
145
  }
146
+ /**
147
+ * Extract and decrypts the shared signature key from the provided exchange data.
148
+ * @param exchangeData the exchange data from which to extract exchange keys.
149
+ * @param decryptionKeys rsa key pairs to use for the decryption of the exchange keys.
150
+ * @return an object composed of:
151
+ * - successfulDecryptions: array containing the successfully decrypted exchange keys.
152
+ * - failedDecryptions: array containing all exchange data for which the access control key could not be decrypted (using the provided keys).
153
+ */
154
+ tryDecryptSharedSignatureKeys(exchangeData, decryptionKeys) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ return yield this.tryDecryptExchangeData(exchangeData, decryptionKeys, (ed) => ed.sharedSignatureKey, (d) => this.importSharedSignatureKey(new Uint8Array(d)));
157
+ });
158
+ }
152
159
  tryDecryptExchangeData(exchangeData, decryptionKeys, encryptedDataSelector, unmarshalDecrypted) {
153
160
  return __awaiter(this, void 0, void 0, function* () {
154
161
  const successfulDecryptions = [];
@@ -180,7 +187,7 @@ class BaseExchangeDataManager {
180
187
  try {
181
188
  const key = (_a = decryptionKeysWithV2Fp[fp]) === null || _a === void 0 ? void 0 : _a.privateKey;
182
189
  if (key)
183
- return (0, utils_1.hex2ua)((0, utils_1.ua2utf8)(yield this.primitives.RSA.decrypt(key, (0, utils_1.b64_2ua)(encrypted))));
190
+ return yield this.primitives.RSA.decrypt(key, (0, utils_1.b64_2ua)(encrypted));
184
191
  }
185
192
  catch (e) {
186
193
  // Try with another key
@@ -205,17 +212,29 @@ class BaseExchangeDataManager {
205
212
  }
206
213
  const exchangeKey = yield this.generateExchangeKey();
207
214
  const accessControlSecret = yield this.generateAccessControlSecret();
215
+ const sharedSignatureKey = yield this.generateSharedSignatureKey();
208
216
  const encryptedExchangeKey = yield this.encryptDataWithKeys(exchangeKey.rawBytes, encryptionKeys);
209
217
  const encryptedAccessControlSecret = yield this.encryptDataWithKeys(accessControlSecret.rawBytes, encryptionKeys);
218
+ const encryptedSharedSignatureKey = yield this.encryptDataWithKeys(sharedSignatureKey.rawBytes, encryptionKeys);
210
219
  const baseExchangeData = {
211
220
  id: (_a = optionalAttributes.id) !== null && _a !== void 0 ? _a : this.primitives.randomUuid(),
212
221
  delegator: yield this.dataOwnerApi.getCurrentDataOwnerId(),
213
222
  delegate: delegateId,
214
223
  exchangeKey: encryptedExchangeKey,
215
224
  accessControlSecret: encryptedAccessControlSecret,
225
+ sharedSignatureKey: encryptedSharedSignatureKey,
216
226
  };
217
- const signature = yield this.signDataWithKeys(yield this.bytesToSign(baseExchangeData), signatureKeys);
218
- const exchangeData = new ExchangeData_1.ExchangeData(Object.assign(Object.assign({}, baseExchangeData), { signature }));
227
+ const sharedSignature = yield this.signDataWithSharedKey(yield this.bytesToSignForSharedSignature({
228
+ delegate: baseExchangeData.delegate,
229
+ delegator: baseExchangeData.delegator,
230
+ decryptedAccessControlSecret: accessControlSecret.secret,
231
+ decryptedExchangeKey: exchangeKey.key,
232
+ publicKeysFingerprintsV2: Object.keys(encryptionKeys).map(utils_2.fingerprintV1toV2),
233
+ }), sharedSignatureKey.key);
234
+ const delegatorSignature = yield this.signDataWithDelegatorKeys(yield this.bytesToSignForDelegatorSignature({
235
+ sharedSignatureKey: sharedSignatureKey.key,
236
+ }), signatureKeys);
237
+ const exchangeData = new ExchangeData_1.ExchangeData(Object.assign(Object.assign({}, baseExchangeData), { delegatorSignature, sharedSignature }));
219
238
  return {
220
239
  exchangeData: yield this.api.createExchangeData(exchangeData),
221
240
  exchangeKey: exchangeKey.key,
@@ -228,67 +247,73 @@ class BaseExchangeDataManager {
228
247
  * where one of the data owners involved in the exchange data has lost one of his keys.
229
248
  * If the content of the exchange data could not be decrypted using the provided keys the method will not update anything and will return undefined.
230
249
  * This method assumes that the new encryption keys have been verified.
231
- * If the current data owner is also the delegator of the provided exchange data and at least one of the verification keys can be used to
232
- * validate the current exchange data then the signature will be updated using the signature keys.
233
- * Instead, if the current data owner is not the delegator of the provided exchange data, or the exchange data could not be verified using
234
- * the provided verification keys then the updated exchange data will become unverified, and won't ever be verifiable again.
235
250
  * @param exchangeData exchange data to update.
236
251
  * @param decryptionKeys keys to use to extract the content of the exchange data which will be shared with the new keys.
237
- * @param signatureKeys keys to use for the new signature of the updated exchange data.
238
252
  * @param newEncryptionKeys new keys to add to the exchange data.
239
- * @param getVerificationKey function to retrieve keys to use for verification by fingerprint.
240
253
  * @return the updated exchange data, and its decrypted exchange key and access control secret, or undefined if the exchange data content could not
241
254
  * be decrypted and the exchange data could not be updated.
242
255
  */
243
- tryUpdateExchangeData(exchangeData, decryptionKeys, newEncryptionKeys, signatureKeys, getVerificationKey) {
256
+ tryUpdateExchangeData(exchangeData, decryptionKeys, newEncryptionKeys) {
244
257
  return __awaiter(this, void 0, void 0, function* () {
245
258
  const dataOwnerId = yield this.dataOwnerApi.getCurrentDataOwnerId();
246
259
  const rawExchangeKey = yield this.tryDecrypt(exchangeData.exchangeKey, decryptionKeys);
247
260
  const rawAccessControlSecret = yield this.tryDecrypt(exchangeData.accessControlSecret, decryptionKeys);
248
- if (!rawExchangeKey || !rawAccessControlSecret)
261
+ const rawSharedSignatureKey = yield this.tryDecrypt(exchangeData.sharedSignatureKey, decryptionKeys);
262
+ if (!rawExchangeKey || !rawAccessControlSecret || !rawSharedSignatureKey)
249
263
  return undefined;
250
264
  const exchangeKey = yield this.importExchangeKey(new Uint8Array(rawExchangeKey));
251
265
  const accessControlSecret = yield this.importAccessControlSecret(new Uint8Array(rawAccessControlSecret));
266
+ const sharedSignatureKey = yield this.importSharedSignatureKey(new Uint8Array(rawSharedSignatureKey));
252
267
  const existingExchangeKeyEntries = new Set(Object.keys(exchangeData.exchangeKey));
253
268
  const existingAcsEntries = new Set(Object.keys(exchangeData.accessControlSecret));
254
- const missingEntries = Object.keys(newEncryptionKeys).filter((fp) => !existingAcsEntries.has(fp) || !existingExchangeKeyEntries.has(fp));
269
+ const existingSharedSignatureKeyEntries = new Set(Object.keys(exchangeData.sharedSignatureKey));
270
+ const missingEntries = Object.keys(newEncryptionKeys).filter((fp) => !existingAcsEntries.has(fp) || !existingExchangeKeyEntries.has(fp) || !existingSharedSignatureKeyEntries.has(fp));
255
271
  if (!missingEntries.length)
256
272
  return { exchangeData, exchangeKey, accessControlSecret };
257
273
  const encryptionKeysForMissingEntries = missingEntries.reduce((obj, fp) => {
258
274
  obj[fp] = newEncryptionKeys[fp];
259
275
  return obj;
260
276
  }, {});
261
- const isVerified = exchangeData.delegator == dataOwnerId && (yield this.verifyExchangeData(exchangeData, (fp) => getVerificationKey(fp)));
262
277
  const updatedExchangeData = _.cloneDeep(exchangeData);
263
278
  updatedExchangeData.exchangeKey = Object.assign(Object.assign({}, exchangeData.exchangeKey), (yield this.encryptDataWithKeys(rawExchangeKey, encryptionKeysForMissingEntries)));
264
279
  updatedExchangeData.accessControlSecret = Object.assign(Object.assign({}, exchangeData.accessControlSecret), (yield this.encryptDataWithKeys(rawAccessControlSecret, encryptionKeysForMissingEntries)));
280
+ updatedExchangeData.sharedSignatureKey = Object.assign(Object.assign({}, exchangeData.sharedSignatureKey), (yield this.encryptDataWithKeys(rawSharedSignatureKey, encryptionKeysForMissingEntries)));
281
+ const isVerified = yield this.verifyExchangeData({
282
+ exchangeData,
283
+ decryptedAccessControlSecret: accessControlSecret,
284
+ decryptedExchangeKey: exchangeKey,
285
+ decryptedSharedSignatureKey: sharedSignatureKey,
286
+ }, () => Promise.resolve(undefined), false);
265
287
  if (isVerified) {
266
- const newDataToSign = yield this.bytesToSign(updatedExchangeData);
267
- updatedExchangeData.signature = yield this.signDataWithKeys(newDataToSign, signatureKeys);
288
+ updatedExchangeData.sharedSignature = yield this.signDataWithSharedKey(yield this.bytesToSignForSharedSignature({
289
+ delegate: updatedExchangeData.delegate,
290
+ delegator: updatedExchangeData.delegator,
291
+ decryptedAccessControlSecret: accessControlSecret,
292
+ decryptedExchangeKey: exchangeKey,
293
+ publicKeysFingerprintsV2: Object.keys(updatedExchangeData.exchangeKey),
294
+ }), sharedSignatureKey);
268
295
  }
269
296
  return { exchangeData: yield this.api.modifyExchangeData(new ExchangeData_1.ExchangeData(updatedExchangeData)), exchangeKey, accessControlSecret };
270
297
  });
271
298
  }
272
- // Gets a byte representation of the parts of exchange data which should be included in the signature.
273
- // Equivalent json representations of the exchange data should provide the same bytes (even if the order of entries
274
- // is different).
275
- bytesToSign(exchangeData) {
299
+ bytesToSignForSharedSignature(data) {
276
300
  return __awaiter(this, void 0, void 0, function* () {
277
- function sortObject(obj) {
278
- return Object.keys(obj)
279
- .sort()
280
- .reduce((sorted, key) => {
281
- return [...sorted, [key, obj[key]]];
282
- }, []);
283
- }
301
+ // Use array of array to ensure that order is preserved regardless of how the specific js implementation orders
302
+ // the keys of an object
284
303
  const signObject = [
285
- ['delegator', exchangeData.delegator],
286
- ['delegate', exchangeData.delegate],
287
- ['exchangeKey', sortObject(exchangeData.exchangeKey)],
288
- ['accessControlSecret', sortObject(exchangeData.accessControlSecret)],
304
+ ['delegator', data.delegator],
305
+ ['delegate', data.delegate],
306
+ ['exchangeKey', (0, utils_1.ua2hex)(yield this.primitives.AES.exportKey(data.decryptedExchangeKey, 'raw'))],
307
+ ['accessControlSecret', data.decryptedAccessControlSecret],
308
+ ['publicKeysFingerprints', data.publicKeysFingerprintsV2.sort()],
289
309
  ];
290
310
  const signJson = JSON.stringify(signObject);
291
- return this.primitives.sha256((0, utils_1.utf8_2ua)(signJson));
311
+ return (0, utils_1.utf8_2ua)(signJson);
312
+ });
313
+ }
314
+ bytesToSignForDelegatorSignature(data) {
315
+ return __awaiter(this, void 0, void 0, function* () {
316
+ return this.primitives.sha256(yield this.primitives.HMAC.exportKey(data.sharedSignatureKey));
292
317
  });
293
318
  }
294
319
  // Generates a new exchange key
@@ -306,6 +331,17 @@ class BaseExchangeDataManager {
306
331
  return yield this.primitives.AES.importKey('raw', decryptedBytes);
307
332
  });
308
333
  }
334
+ generateSharedSignatureKey() {
335
+ return __awaiter(this, void 0, void 0, function* () {
336
+ const key = yield this.primitives.HMAC.generateKey();
337
+ return { key, rawBytes: yield this.primitives.HMAC.exportKey(key) };
338
+ });
339
+ }
340
+ importSharedSignatureKey(decryptedBytes) {
341
+ return __awaiter(this, void 0, void 0, function* () {
342
+ return yield this.primitives.HMAC.importKey(decryptedBytes);
343
+ });
344
+ }
309
345
  // Generates a new access control secret
310
346
  generateAccessControlSecret() {
311
347
  return __awaiter(this, void 0, void 0, function* () {
@@ -323,12 +359,12 @@ class BaseExchangeDataManager {
323
359
  return __awaiter(this, void 0, void 0, function* () {
324
360
  const res = {};
325
361
  for (const [fp, key] of Object.entries(keys)) {
326
- res[(0, utils_2.fingerprintIsV1)(fp) ? (0, utils_2.fingerprintV1toV2)(fp) : fp] = (0, utils_1.ua2b64)(yield this.primitives.RSA.encrypt(key, (0, utils_1.utf8_2ua)((0, utils_1.ua2hex)(rawData))));
362
+ res[(0, utils_2.fingerprintIsV1)(fp) ? (0, utils_2.fingerprintV1toV2)(fp) : fp] = (0, utils_1.ua2b64)(yield this.primitives.RSA.encrypt(key, new Uint8Array(rawData)));
327
363
  }
328
364
  return res;
329
365
  });
330
366
  }
331
- signDataWithKeys(rawData, keys) {
367
+ signDataWithDelegatorKeys(rawData, keys) {
332
368
  return __awaiter(this, void 0, void 0, function* () {
333
369
  const res = {};
334
370
  for (const [fp, key] of Object.entries(keys)) {
@@ -337,6 +373,29 @@ class BaseExchangeDataManager {
337
373
  return res;
338
374
  });
339
375
  }
376
+ verifyDelegatorSignature(exchangeData, decryptedSharedSignatureKey, getVerificationKey) {
377
+ return __awaiter(this, void 0, void 0, function* () {
378
+ const delegatorSignatureData = yield this.bytesToSignForDelegatorSignature({
379
+ sharedSignatureKey: decryptedSharedSignatureKey,
380
+ });
381
+ for (const [fp, signature] of Object.entries(exchangeData.delegatorSignature)) {
382
+ const verificationKey = yield getVerificationKey(fp.slice(-32));
383
+ if (verificationKey && (yield this.primitives.RSA.verifySignature(verificationKey, (0, utils_1.b64_2ua)(signature), delegatorSignatureData)))
384
+ return true;
385
+ }
386
+ return false;
387
+ });
388
+ }
389
+ signDataWithSharedKey(rawData, key) {
390
+ return __awaiter(this, void 0, void 0, function* () {
391
+ return (0, utils_1.ua2b64)(yield this.primitives.HMAC.sign(key, new Uint8Array(rawData)));
392
+ });
393
+ }
394
+ verifyDataWithSharedKey(rawData, key, signature) {
395
+ return __awaiter(this, void 0, void 0, function* () {
396
+ return yield this.primitives.HMAC.verify(key, new Uint8Array(rawData), (0, utils_1.b64_2ua)(signature));
397
+ });
398
+ }
340
399
  }
341
400
  exports.BaseExchangeDataManager = BaseExchangeDataManager;
342
401
  //# sourceMappingURL=BaseExchangeDataManager.js.map