@cubist-labs/cubesigner-sdk 0.2.28 → 0.3.8

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 (146) hide show
  1. package/README.md +30 -28
  2. package/dist/cjs/package.json +41 -0
  3. package/dist/cjs/spec/env/beta.json +9 -0
  4. package/dist/cjs/spec/env/gamma.json +9 -0
  5. package/dist/cjs/spec/env/prod.json +9 -0
  6. package/dist/cjs/src/api.d.ts +652 -0
  7. package/dist/cjs/src/api.js +1345 -0
  8. package/dist/cjs/src/client.d.ts +642 -0
  9. package/dist/cjs/src/client.js +455 -0
  10. package/dist/cjs/src/env.d.ts +15 -0
  11. package/dist/cjs/src/env.js +35 -0
  12. package/dist/cjs/src/error.d.ts +32 -0
  13. package/dist/cjs/src/error.js +37 -0
  14. package/dist/cjs/src/events.d.ts +84 -0
  15. package/dist/cjs/src/events.js +195 -0
  16. package/dist/cjs/src/index.d.ts +203 -0
  17. package/dist/cjs/src/index.js +298 -0
  18. package/dist/cjs/src/key.d.ts +169 -0
  19. package/dist/cjs/src/key.js +262 -0
  20. package/dist/{src/fido.d.ts → cjs/src/mfa.d.ts} +38 -17
  21. package/dist/cjs/src/mfa.js +172 -0
  22. package/dist/cjs/src/org.d.ts +99 -0
  23. package/dist/cjs/src/org.js +95 -0
  24. package/dist/cjs/src/paginator.d.ts +76 -0
  25. package/dist/cjs/src/paginator.js +99 -0
  26. package/dist/cjs/src/response.d.ts +114 -0
  27. package/dist/cjs/src/response.js +203 -0
  28. package/dist/cjs/src/role.d.ts +289 -0
  29. package/dist/cjs/src/role.js +261 -0
  30. package/dist/cjs/src/schema.d.ts +6404 -0
  31. package/dist/cjs/src/schema.js +7 -0
  32. package/dist/cjs/src/schema_types.d.ts +116 -0
  33. package/dist/cjs/src/schema_types.js +3 -0
  34. package/dist/cjs/src/session/session_storage.d.ts +27 -0
  35. package/dist/cjs/src/session/session_storage.js +47 -0
  36. package/dist/cjs/src/session/signer_session_manager.d.ts +125 -0
  37. package/dist/cjs/src/session/signer_session_manager.js +239 -0
  38. package/dist/cjs/src/signer_session.d.ts +41 -0
  39. package/dist/cjs/src/signer_session.js +77 -0
  40. package/dist/cjs/src/user_export.d.ts +52 -0
  41. package/dist/cjs/src/user_export.js +129 -0
  42. package/dist/cjs/src/util.d.ts +56 -0
  43. package/dist/cjs/src/util.js +87 -0
  44. package/dist/esm/package.json +41 -0
  45. package/dist/esm/spec/env/beta.json +9 -0
  46. package/dist/esm/spec/env/gamma.json +9 -0
  47. package/dist/esm/spec/env/prod.json +9 -0
  48. package/dist/esm/src/api.d.ts +652 -0
  49. package/dist/esm/src/api.js +1335 -0
  50. package/dist/esm/src/client.d.ts +642 -0
  51. package/dist/esm/src/client.js +451 -0
  52. package/dist/esm/src/env.d.ts +15 -0
  53. package/dist/esm/src/env.js +9 -0
  54. package/dist/esm/src/error.d.ts +32 -0
  55. package/dist/esm/src/error.js +32 -0
  56. package/dist/esm/src/events.d.ts +84 -0
  57. package/dist/esm/src/events.js +189 -0
  58. package/dist/esm/src/index.d.ts +203 -0
  59. package/dist/esm/src/index.js +276 -0
  60. package/dist/esm/src/key.d.ts +169 -0
  61. package/dist/esm/src/key.js +256 -0
  62. package/dist/esm/src/mfa.d.ts +97 -0
  63. package/dist/esm/src/mfa.js +166 -0
  64. package/dist/esm/src/org.d.ts +99 -0
  65. package/dist/esm/src/org.js +91 -0
  66. package/dist/esm/src/paginator.d.ts +76 -0
  67. package/dist/esm/src/paginator.js +94 -0
  68. package/dist/esm/src/response.d.ts +114 -0
  69. package/dist/esm/src/response.js +198 -0
  70. package/dist/esm/src/role.d.ts +289 -0
  71. package/dist/esm/src/role.js +256 -0
  72. package/dist/esm/src/schema.d.ts +6404 -0
  73. package/dist/esm/src/schema.js +6 -0
  74. package/dist/esm/src/schema_types.d.ts +116 -0
  75. package/dist/esm/src/schema_types.js +2 -0
  76. package/dist/esm/src/session/session_storage.d.ts +27 -0
  77. package/dist/esm/src/session/session_storage.js +43 -0
  78. package/dist/esm/src/session/signer_session_manager.d.ts +125 -0
  79. package/dist/esm/src/session/signer_session_manager.js +235 -0
  80. package/dist/esm/src/signer_session.d.ts +41 -0
  81. package/dist/esm/src/signer_session.js +72 -0
  82. package/dist/esm/src/user_export.d.ts +52 -0
  83. package/dist/esm/src/user_export.js +99 -0
  84. package/dist/esm/src/util.d.ts +56 -0
  85. package/dist/esm/src/util.js +77 -0
  86. package/dist/package.json +13 -45
  87. package/dist/src/api.d.ts +29 -1
  88. package/dist/src/api.js +66 -1
  89. package/dist/src/client.d.ts +35 -14
  90. package/dist/src/client.js +12 -8
  91. package/dist/src/events.js +1 -1
  92. package/dist/src/index.d.ts +6 -11
  93. package/dist/src/index.js +9 -25
  94. package/dist/src/key.d.ts +18 -7
  95. package/dist/src/key.js +52 -19
  96. package/dist/src/role.d.ts +46 -3
  97. package/dist/src/role.js +60 -8
  98. package/dist/src/schema.d.ts +206 -72
  99. package/dist/src/schema.js +1 -1
  100. package/dist/src/schema_types.d.ts +3 -0
  101. package/dist/src/schema_types.js +1 -1
  102. package/dist/src/session/signer_session_manager.d.ts +38 -14
  103. package/dist/src/session/signer_session_manager.js +93 -33
  104. package/dist/src/util.d.ts +14 -0
  105. package/dist/src/util.js +24 -27
  106. package/package.json +19 -46
  107. package/src/api.ts +145 -19
  108. package/src/client.ts +106 -10
  109. package/src/error.ts +4 -0
  110. package/src/events.ts +2 -0
  111. package/src/index.ts +10 -24
  112. package/src/key.ts +67 -20
  113. package/src/mfa.ts +8 -4
  114. package/src/response.ts +50 -4
  115. package/src/role.ts +87 -7
  116. package/src/schema.ts +764 -152
  117. package/src/schema_types.ts +6 -0
  118. package/src/session/session_storage.ts +0 -32
  119. package/src/session/signer_session_manager.ts +126 -38
  120. package/src/util.ts +18 -10
  121. package/tsconfig.json +1 -21
  122. package/LICENSE-APACHE +0 -177
  123. package/LICENSE-MIT +0 -25
  124. package/NOTICE +0 -13
  125. package/dist/examples/ethers.d.ts +0 -1
  126. package/dist/examples/ethers.js +0 -142
  127. package/dist/src/ethers/index.d.ts +0 -95
  128. package/dist/src/ethers/index.js +0 -215
  129. package/dist/src/fido.js +0 -148
  130. package/dist/src/session/cognito_manager.d.ts +0 -71
  131. package/dist/src/session/cognito_manager.js +0 -129
  132. package/dist/src/session/generic.d.ts +0 -47
  133. package/dist/src/session/generic.js +0 -3
  134. package/dist/src/session/management_session_manager.d.ts +0 -59
  135. package/dist/src/session/management_session_manager.js +0 -111
  136. package/dist/src/session/oidc_session_manager.d.ts +0 -78
  137. package/dist/src/session/oidc_session_manager.js +0 -142
  138. package/dist/src/session/session_manager.d.ts +0 -99
  139. package/dist/src/session/session_manager.js +0 -136
  140. package/dist/src/sign.d.ts +0 -114
  141. package/dist/src/sign.js +0 -248
  142. package/dist/test/sessions.d.ts +0 -35
  143. package/dist/test/sessions.js +0 -56
  144. package/src/ethers/index.ts +0 -253
  145. package/src/session/cognito_manager.ts +0 -161
  146. package/src/session/session_manager.ts +0 -165
package/package.json CHANGED
@@ -1,68 +1,41 @@
1
1
  {
2
2
  "name": "@cubist-labs/cubesigner-sdk",
3
- "author": "Cubist, Inc.",
4
- "version": "0.2.28",
3
+ "version": "0.3.8",
5
4
  "description": "CubeSigner TypeScript SDK",
6
- "homepage": "https://github.com/cubist-labs/CubeSigner-TypeScript-SDK",
7
- "bugs": "https://github.com/cubist-labs/CubeSigner-TypeScript-SDK/issues",
8
5
  "license": "MIT OR Apache-2.0",
6
+ "author": "Cubist, Inc.",
7
+ "main": "dist/cjs/src/index.js",
9
8
  "files": [
10
9
  "tsconfig.json",
11
10
  "src/**",
12
11
  "dist/**",
13
- "NOTICE",
14
- "LICENSE-APACHE",
15
- "LICENSE-MIT"
12
+ "../..NOTICE",
13
+ "../..LICENSE-APACHE",
14
+ "../..LICENSE-MIT"
16
15
  ],
17
- "main": "dist/src/index.js",
18
- "types": "dist/src/index.d.ts",
16
+ "exports": {
17
+ "require": "./dist/cjs/src/index.js",
18
+ "import": "./dist/esm/src/index.js"
19
+ },
19
20
  "scripts": {
20
- "build": "tsc",
21
+ "build": "npm run build:cjs && npm run build:mjs",
22
+ "prepack": "npm run build",
23
+ "build:cjs": "tsc -p . --outDir dist/cjs --module commonjs --moduleResolution node",
24
+ "build:mjs": "tsc -p . --outDir dist/esm --module es2022",
25
+ "gen-schema": "openapi-typescript ./spec/openapi.json --output ./src/schema.ts",
21
26
  "test": "jest --maxWorkers=1",
22
- "prepack": "tsc",
23
- "typedoc": "typedoc",
24
- "fix": "eslint . --ext .ts --fix",
25
- "lint": "eslint . --ext .ts",
26
- "fmt": "prettier --write .",
27
- "fmt-check": "prettier --check .",
28
- "gen-schema": "npx openapi-typescript ./spec/openapi.json --output ./src/schema.ts"
27
+ "typedoc": "typedoc"
29
28
  },
30
29
  "dependencies": {
31
- "ethers": "6.7.1",
32
30
  "openapi-fetch": "0.6.1"
33
31
  },
34
- "devDependencies": {
35
- "@hpke/core": "^1.2.5",
36
- "@types/chai": "^4.3.11",
37
- "@types/chai-as-promised": "^7.1.8",
38
- "@types/jest": "^29.5.10",
39
- "@types/node": "^20.10.4",
40
- "@types/node-fetch": "^2.6.9",
41
- "@types/tmp": "^0.2.6",
42
- "@typescript-eslint/eslint-plugin": "^6.13.2",
43
- "chai": "^4.3.10",
44
- "chai-as-promised": "^7.1.1",
45
- "dotenv": "^16.3.1",
46
- "eslint": "^8.55.0",
47
- "eslint-config-google": "^0.14.0",
48
- "eslint-config-prettier": "^9.1.0",
49
- "jest": "^29.7.0",
50
- "openapi-typescript": "^6.7.1",
51
- "otplib": "^12.0.1",
52
- "prettier": "3.1.1",
53
- "tmp": "^0.2.1",
54
- "ts-jest": "^29.1.0",
55
- "ts-node": "^10.9.1",
56
- "typescript": "^5.3.3"
57
- },
58
32
  "optionalDependencies": {
59
- "@aws-sdk/client-cognito-identity-provider": "^3.470.0",
60
33
  "@hpke/core": "^1.2.5"
61
34
  },
62
- "prettier": {
63
- "printWidth": 100
64
- },
65
35
  "engines": {
66
36
  "node": ">=18.0.0"
37
+ },
38
+ "directories": {
39
+ "test": "test"
67
40
  }
68
41
  }
package/src/api.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  KeyInRoleInfo,
18
18
  KeyInfoApi,
19
19
  ListKeysResponse,
20
+ ListKeyRolesResponse,
20
21
  ListRoleKeysResponse,
21
22
  ListRoleUsersResponse,
22
23
  ListRolesResponse,
@@ -34,6 +35,9 @@ import {
34
35
  SessionInfo,
35
36
  OrgInfo,
36
37
  RatchetConfig,
38
+ Eip191SignRequest,
39
+ Eip712SignRequest,
40
+ Eip191Or712SignResponse,
37
41
  EvmSignRequest,
38
42
  EvmSignResponse,
39
43
  Eth2SignRequest,
@@ -52,11 +56,13 @@ import {
52
56
  AvaSignRequest,
53
57
  AvaTx,
54
58
  MfaRequestInfo,
59
+ MfaVote,
55
60
  MemberRole,
56
61
  UserExportCompleteResponse,
57
62
  UserExportInitResponse,
58
63
  UserExportListResponse,
59
64
  Empty,
65
+ ErrorResponse,
60
66
  } from "./schema_types";
61
67
  import { encodeToBase64 } from "./util";
62
68
  import { AddFidoChallenge, MfaFidoChallenge, MfaReceipt, TotpChallenge } from "./mfa";
@@ -66,9 +72,9 @@ import { Key, KeyType } from "./key";
66
72
  import { Page, PageOpts, PageQueryArgs, Paginator } from "./paginator";
67
73
  import { KeyPolicy } from "./role";
68
74
  import { EnvInterface } from "./env";
69
- import { NAME, VERSION } from ".";
70
75
  import { loadSubtleCrypto } from "./user_export";
71
76
  import { EventEmitter } from "./events";
77
+ import { NAME, VERSION } from "./index";
72
78
 
73
79
  /** @internal */
74
80
  export type Client = ReturnType<typeof createClient<paths>>;
@@ -147,14 +153,16 @@ export class OpClient<Op extends keyof operations> {
147
153
  */
148
154
  private async assertOk<T>(resp: FetchResponse<T>): Promise<FetchResponseSuccessData<T>> {
149
155
  if (resp.error) {
156
+ const errResp = resp.error as unknown as ErrorResponse | undefined;
150
157
  const error = new ErrResponse({
151
158
  operation: this.op,
152
- message: (resp.error as any).message, // eslint-disable-line @typescript-eslint/no-explicit-any
159
+ message: errResp?.message,
153
160
  statusText: resp.response?.statusText,
154
161
  status: resp.response?.status,
155
162
  url: resp.response?.url,
163
+ errorCode: errResp?.error_code,
156
164
  });
157
- this.#eventEmitter.classifyAndEmitError(error);
165
+ await this.#eventEmitter.classifyAndEmitError(error);
158
166
  throw error;
159
167
  }
160
168
  if (resp.data === undefined) {
@@ -225,9 +233,11 @@ export class OpClient<Op extends keyof operations> {
225
233
  export function createHttpClient(baseUrl: string, authToken: string): Client {
226
234
  return createClient<paths>({
227
235
  baseUrl,
236
+ cache: "no-store",
228
237
  headers: {
229
238
  Authorization: authToken,
230
239
  ["User-Agent"]: `${NAME}@${VERSION}`,
240
+ ["X-Cubist-Ts-Sdk"]: `${NAME}@${VERSION}`,
231
241
  },
232
242
  });
233
243
  }
@@ -572,6 +582,31 @@ export class CubeSignerApi {
572
582
  });
573
583
  }
574
584
 
585
+ /**
586
+ * List all roles a key is in.
587
+ *
588
+ * @param {string} keyId The id of the key to get.
589
+ * @param {PageOpts} page Pagination options. Defaults to fetching the entire result set.
590
+ * @return {Paginator<ListKeyRolesResponse, KeyInRoleInfo>} Paginator for iterating over the roles a key is in.
591
+ */
592
+ keyRolesList(keyId: string, page?: PageOpts): Paginator<ListKeyRolesResponse, KeyInRoleInfo> {
593
+ const listFn = async (query: PageQueryArgs) => {
594
+ const client = await this.client("listKeyRoles");
595
+ return await client.get("/v0/org/{org_id}/keys/{key_id}/roles", {
596
+ params: {
597
+ path: { org_id: this.orgId, key_id: keyId },
598
+ query,
599
+ },
600
+ });
601
+ };
602
+ return new Paginator(
603
+ page ?? Page.default(),
604
+ listFn,
605
+ (r) => r.roles,
606
+ (r) => r.last_evaluated_key,
607
+ );
608
+ }
609
+
575
610
  /**
576
611
  * Update key.
577
612
  * @param {string} keyId The ID of the key to update.
@@ -819,7 +854,7 @@ export class CubeSignerApi {
819
854
 
820
855
  // #endregion
821
856
 
822
- // #region ROLE USERS: roleUserAdd, roleUsersList
857
+ // #region ROLE USERS: roleUserAdd, roleUserRemove, roleUsersList
823
858
 
824
859
  /**
825
860
  * Add an existing user to an existing role.
@@ -834,6 +869,19 @@ export class CubeSignerApi {
834
869
  });
835
870
  }
836
871
 
872
+ /**
873
+ * Remove an existing user from an existing role.
874
+ *
875
+ * @param {string} roleId The ID of the role.
876
+ * @param {string} userId The ID of the user to remove from the role.
877
+ */
878
+ async roleUserRemove(roleId: string, userId: string) {
879
+ const client = await this.client("removeUserFromRole");
880
+ await client.del("/v0/org/{org_id}/roles/{role_id}/users/{user_id}", {
881
+ params: { path: { org_id: this.orgId, role_id: roleId, user_id: userId } },
882
+ });
883
+ }
884
+
837
885
  /**
838
886
  * List all users in a role.
839
887
  *
@@ -1059,29 +1107,31 @@ export class CubeSignerApi {
1059
1107
  }
1060
1108
 
1061
1109
  /**
1062
- * Approve a pending MFA request using the current session.
1110
+ * Approve or reject a pending MFA request using the current session.
1063
1111
  *
1064
1112
  * @param {string} mfaId The id of the MFA request
1113
+ * @param {MfaVote} mfaVote Approve or reject the MFA request
1065
1114
  * @return {Promise<MfaRequestInfo>} The result of the MFA request
1066
1115
  */
1067
- async mfaApprove(mfaId: string): Promise<MfaRequestInfo> {
1068
- const client = await this.client("mfaApproveCs");
1116
+ async mfaVoteCs(mfaId: string, mfaVote: MfaVote): Promise<MfaRequestInfo> {
1117
+ const client = await this.client("mfaVoteCs");
1069
1118
  return await client.patch("/v0/org/{org_id}/mfa/{mfa_id}", {
1070
- params: { path: { org_id: this.orgId, mfa_id: mfaId } },
1119
+ params: { path: { org_id: this.orgId, mfa_id: mfaId }, query: { mfa_vote: mfaVote } },
1071
1120
  });
1072
1121
  }
1073
1122
 
1074
1123
  /**
1075
- * Approve a pending MFA request using TOTP.
1124
+ * Approve or reject a pending MFA request using TOTP.
1076
1125
  *
1077
- * @param {string} mfaId The MFA request to approve
1126
+ * @param {string} mfaId The ID of the MFA request
1078
1127
  * @param {string} code The TOTP code
1128
+ * @param {MfaVote} mfaVote Approve or reject the MFA request
1079
1129
  * @return {Promise<MfaRequestInfo>} The current status of the MFA request
1080
1130
  */
1081
- async mfaApproveTotp(mfaId: string, code: string): Promise<MfaRequestInfo> {
1082
- const client = await this.client("mfaApproveTotp");
1131
+ async mfaVoteTotp(mfaId: string, code: string, mfaVote: MfaVote): Promise<MfaRequestInfo> {
1132
+ const client = await this.client("mfaVoteTotp");
1083
1133
  return await client.patch("/v0/org/{org_id}/mfa/{mfa_id}/totp", {
1084
- params: { path: { org_id: this.#orgId, mfa_id: mfaId } },
1134
+ params: { path: { org_id: this.#orgId, mfa_id: mfaId }, query: { mfa_vote: mfaVote } },
1085
1135
  body: { code },
1086
1136
  });
1087
1137
  }
@@ -1093,8 +1143,8 @@ export class CubeSignerApi {
1093
1143
  * @param {string} mfaId The MFA request ID.
1094
1144
  * @return {Promise<MfaFidoChallenge>} A challenge that needs to be answered to complete the approval.
1095
1145
  */
1096
- async mfaApproveFidoInit(mfaId: string): Promise<MfaFidoChallenge> {
1097
- const client = await this.client("mfaApproveFido");
1146
+ async mfaFidoInit(mfaId: string): Promise<MfaFidoChallenge> {
1147
+ const client = await this.client("mfaFidoInit");
1098
1148
  const challenge = await client.post("/v0/org/{org_id}/mfa/{mfa_id}/fido", {
1099
1149
  params: { path: { org_id: this.orgId, mfa_id: mfaId } },
1100
1150
  });
@@ -1102,24 +1152,26 @@ export class CubeSignerApi {
1102
1152
  }
1103
1153
 
1104
1154
  /**
1105
- * Complete a previously initiated (via {@link mfaApproveFidoInit}) MFA request approval using FIDO.
1155
+ * Complete a previously initiated (via {@link mfaApproveFidoInit}) MFA request using FIDO.
1106
1156
  *
1107
1157
  * Instead of calling this method directly, prefer {@link MfaFidoChallenge.answer} or
1108
1158
  * {@link MfaFidoChallenge.createCredentialAndAnswer}.
1109
1159
  *
1110
1160
  * @param {string} mfaId The MFA request ID
1161
+ * @param {MfaVote} mfaVote Approve or reject the MFA request
1111
1162
  * @param {string} challengeId The ID of the challenge issued by {@link mfaApproveFidoInit}
1112
1163
  * @param {PublicKeyCredential} credential The answer to the challenge
1113
1164
  * @return {Promise<MfaRequestInfo>} The current status of the MFA request.
1114
1165
  */
1115
- async mfaApproveFidoComplete(
1166
+ async mfaVoteFidoComplete(
1116
1167
  mfaId: string,
1168
+ mfaVote: MfaVote,
1117
1169
  challengeId: string,
1118
1170
  credential: PublicKeyCredential,
1119
1171
  ): Promise<MfaRequestInfo> {
1120
- const client = await this.client("mfaApproveFidoComplete");
1172
+ const client = await this.client("mfaVoteFidoComplete");
1121
1173
  return await client.patch("/v0/org/{org_id}/mfa/{mfa_id}/fido", {
1122
- params: { path: { org_id: this.orgId, mfa_id: mfaId } },
1174
+ params: { path: { org_id: this.orgId, mfa_id: mfaId }, query: { mfa_vote: mfaVote } },
1123
1175
  body: {
1124
1176
  challenge_id: challengeId,
1125
1177
  credential,
@@ -1155,6 +1207,64 @@ export class CubeSignerApi {
1155
1207
  return await CubeSignerResponse.create(signFn, mfaReceipt);
1156
1208
  }
1157
1209
 
1210
+ /**
1211
+ * Sign EIP-191 typed data.
1212
+ *
1213
+ * This requires the key to have a '"AllowEip191Signing"' {@link KeyPolicy}.
1214
+ *
1215
+ * @param {Key | string} key The key to sign with (either {@link Key} or its material ID).
1216
+ * @param {BlobSignRequest} req What to sign
1217
+ * @param {MfaReceipt} mfaReceipt Optional MFA receipt
1218
+ * @return {Promise<EvmSignResponse | AcceptedResponse>} Signature (or MFA approval request).
1219
+ */
1220
+ async signEip191(
1221
+ key: Key | string,
1222
+ req: Eip191SignRequest,
1223
+ mfaReceipt?: MfaReceipt,
1224
+ ): Promise<CubeSignerResponse<Eip191Or712SignResponse>> {
1225
+ const pubkey = typeof key === "string" ? (key as string) : key.materialId;
1226
+ const signFn = async (headers?: HeadersInit) => {
1227
+ const client = await this.client("eip191Sign");
1228
+ return await client.post("/v0/org/{org_id}/evm/eip191/sign/{pubkey}", {
1229
+ params: {
1230
+ path: { org_id: this.orgId, pubkey },
1231
+ },
1232
+ body: req,
1233
+ headers,
1234
+ });
1235
+ };
1236
+ return await CubeSignerResponse.create(signFn, mfaReceipt);
1237
+ }
1238
+
1239
+ /**
1240
+ * Sign EIP-712 typed data.
1241
+ *
1242
+ * This requires the key to have a '"AllowEip712Signing"' {@link KeyPolicy}.
1243
+ *
1244
+ * @param {Key | string} key The key to sign with (either {@link Key} or its material ID).
1245
+ * @param {BlobSignRequest} req What to sign
1246
+ * @param {MfaReceipt} mfaReceipt Optional MFA receipt
1247
+ * @return {Promise<EvmSignResponse | AcceptedResponse>} Signature (or MFA approval request).
1248
+ */
1249
+ async signEip712(
1250
+ key: Key | string,
1251
+ req: Eip712SignRequest,
1252
+ mfaReceipt?: MfaReceipt,
1253
+ ): Promise<CubeSignerResponse<Eip191Or712SignResponse>> {
1254
+ const pubkey = typeof key === "string" ? (key as string) : key.materialId;
1255
+ const signFn = async (headers?: HeadersInit) => {
1256
+ const client = await this.client("eip712Sign");
1257
+ return await client.post("/v0/org/{org_id}/evm/eip712/sign/{pubkey}", {
1258
+ params: {
1259
+ path: { org_id: this.orgId, pubkey },
1260
+ },
1261
+ body: req,
1262
+ headers,
1263
+ });
1264
+ };
1265
+ return await CubeSignerResponse.create(signFn, mfaReceipt);
1266
+ }
1267
+
1158
1268
  /**
1159
1269
  * Sign an Eth2/Beacon-chain validation message.
1160
1270
  *
@@ -1457,6 +1567,22 @@ export class CubeSignerApi {
1457
1567
  return await CubeSignerResponse.create(completeFn, mfaReceipt);
1458
1568
  }
1459
1569
  // #endregion
1570
+
1571
+ // #region MISC: heartbeat()
1572
+ /**
1573
+ * Send a heartbeat / upcheck request.
1574
+ *
1575
+ * @return { Promise<void> } The response.
1576
+ */
1577
+ async heartbeat(): Promise<void> {
1578
+ const client = await this.client("cube3signerHeartbeat");
1579
+ await client.post("/v1/org/{org_id}/cube3signer/heartbeat", {
1580
+ params: {
1581
+ path: { org_id: this.orgId },
1582
+ },
1583
+ });
1584
+ }
1585
+ // #endregion
1460
1586
  }
1461
1587
 
1462
1588
  /**
package/src/client.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { SignerSessionManager, SignerSessionStorage } from "./session/signer_session_manager";
2
- import { CognitoSessionManager } from "./session/cognito_manager";
3
2
  import { CubeSignerApi, OidcClient } from "./api";
4
3
  import { KeyType, Key } from "./key";
5
- import { OrgInfo, RatchetConfig } from "./schema_types";
4
+ import { MfaRequestInfo, OrgInfo, PublicKeyCredential, RatchetConfig } from "./schema_types";
6
5
  import { MfaReceipt } from "./mfa";
7
6
  import { PageOpts } from "./paginator";
8
7
  import { Role } from "./role";
@@ -49,15 +48,20 @@ export class CubeSignerClient extends CubeSignerApi {
49
48
  /**
50
49
  * Loads an existing management session and creates a {@link CubeSignerClient} instance.
51
50
  *
51
+ * @param {SignerSessionStorage} storage Storage from which to load the session
52
52
  * @return {Promise<CubeSignerClient>} New CubeSigner instance
53
53
  */
54
- static async loadManagementSession(): Promise<CubeSignerClient> {
55
- const mgr = await CognitoSessionManager.loadManagementSession();
56
- // HACK: Ignore that sessionMgr may be a CognitoSessionManager and pretend that it
57
- // is a SignerSessionManager; that's fine because the CubeSignerClient will
58
- // almost always just call `await token()` on it, which works in both cases.
59
- // NOTE: This will go away once `cs login` starts producing signer sessions.
60
- return new CubeSignerClient(mgr as unknown as SignerSessionManager);
54
+ static async loadManagementSession(storage: SignerSessionStorage): Promise<CubeSignerClient> {
55
+ // Throw and actionable error if the management session file contains a Cognito session
56
+ const session = await storage.retrieve();
57
+ if ((session as unknown as { id_token: string }).id_token) {
58
+ throw new Error(
59
+ `It appears that the storage contains the old (Cognito) session; please update your session by updating your 'cs' to version 'v0.37.0' or later and then running 'cs login'`,
60
+ );
61
+ }
62
+
63
+ const mgr = await SignerSessionManager.loadFromStorage(storage);
64
+ return new CubeSignerClient(mgr);
61
65
  }
62
66
 
63
67
  /**
@@ -274,6 +278,26 @@ export class CubeSignerClient extends CubeSignerApi {
274
278
  return this.orgUsersList.bind(this);
275
279
  }
276
280
 
281
+ /**
282
+ * Approve a pending MFA request using the current session.
283
+ *
284
+ * @param {string} mfaId The id of the MFA request
285
+ * @return {Promise<MfaRequestInfo>} The result of the MFA request
286
+ */
287
+ async mfaApprove(mfaId: string): Promise<MfaRequestInfo> {
288
+ return await this.mfaVoteCs(mfaId, "approve");
289
+ }
290
+
291
+ /**
292
+ * Reject a pending MFA request using the current session.
293
+ *
294
+ * @param {string} mfaId The id of the MFA request
295
+ * @return {Promise<MfaRequestInfo>} The result of the MFA request
296
+ */
297
+ async mfaReject(mfaId: string): Promise<MfaRequestInfo> {
298
+ return await this.mfaVoteCs(mfaId, "reject");
299
+ }
300
+
277
301
  /**
278
302
  * Approve a pending MFA request.
279
303
  *
@@ -283,6 +307,28 @@ export class CubeSignerClient extends CubeSignerApi {
283
307
  return this.mfaApprove.bind(this);
284
308
  }
285
309
 
310
+ /**
311
+ * Approve a pending MFA request using TOTP.
312
+ *
313
+ * @param {string} mfaId The MFA request to approve
314
+ * @param {string} code The TOTP code
315
+ * @return {Promise<MfaRequestInfo>} The current status of the MFA request
316
+ */
317
+ async mfaApproveTotp(mfaId: string, code: string): Promise<MfaRequestInfo> {
318
+ return await this.mfaVoteTotp(mfaId, code, "approve");
319
+ }
320
+
321
+ /**
322
+ * Reject a pending MFA request using TOTP.
323
+ *
324
+ * @param {string} mfaId The MFA request to reject
325
+ * @param {string} code The TOTP code
326
+ * @return {Promise<MfaRequestInfo>} The current status of the MFA request
327
+ */
328
+ async mfaRejectTotp(mfaId: string, code: string): Promise<MfaRequestInfo> {
329
+ return await this.mfaVoteTotp(mfaId, code, "reject");
330
+ }
331
+
286
332
  /**
287
333
  * Approve a pending MFA request using TOTP.
288
334
  *
@@ -292,6 +338,18 @@ export class CubeSignerClient extends CubeSignerApi {
292
338
  return this.mfaApproveTotp.bind(this);
293
339
  }
294
340
 
341
+ /**
342
+ * Initiate approval of an existing MFA request using FIDO.
343
+ *
344
+ * Returns a {@link MfaFidoChallenge} that must be answered by calling
345
+ * {@link MfaFidoChallenge.answer} or {@link fidoApproveComplete}.
346
+ *
347
+ * Same as {@link mfaApproveFidoInit}
348
+ */
349
+ get fidoApproveFidoInit() {
350
+ return this.mfaFidoInit.bind(this);
351
+ }
352
+
295
353
  /**
296
354
  * Initiate approval of an existing MFA request using FIDO.
297
355
  *
@@ -301,7 +359,45 @@ export class CubeSignerClient extends CubeSignerApi {
301
359
  * Same as {@link mfaApproveFidoInit}
302
360
  */
303
361
  get fidoApproveStart() {
304
- return this.mfaApproveFidoInit.bind(this);
362
+ return this.mfaFidoInit.bind(this);
363
+ }
364
+
365
+ /**
366
+ * Approve a previously initiated (via {@link mfaApproveFidoInit}) MFA request using FIDO.
367
+ *
368
+ * Instead of calling this method directly, prefer {@link MfaFidoChallenge.answer} or
369
+ * {@link MfaFidoChallenge.createCredentialAndAnswer}.
370
+ *
371
+ * @param {string} mfaId The MFA request ID
372
+ * @param {string} challengeId The ID of the challenge issued by {@link mfaApproveFidoInit}
373
+ * @param {PublicKeyCredential} credential The answer to the challenge
374
+ * @return {Promise<MfaRequestInfo>} The current status of the MFA request.
375
+ */
376
+ async mfaApproveFidoComplete(
377
+ mfaId: string,
378
+ challengeId: string,
379
+ credential: PublicKeyCredential,
380
+ ): Promise<MfaRequestInfo> {
381
+ return await this.mfaVoteFidoComplete(mfaId, "approve", challengeId, credential);
382
+ }
383
+
384
+ /**
385
+ * Reject a previously initiated (via {@link mfaApproveFidoInit}) MFA request using FIDO.
386
+ *
387
+ * Instead of calling this method directly, prefer {@link MfaFidoChallenge.answer} or
388
+ * {@link MfaFidoChallenge.createCredentialAndAnswer}.
389
+ *
390
+ * @param {string} mfaId The MFA request ID
391
+ * @param {string} challengeId The ID of the challenge issued by {@link mfaApproveFidoInit}
392
+ * @param {PublicKeyCredential} credential The answer to the challenge
393
+ * @return {Promise<MfaRequestInfo>} The current status of the MFA request.
394
+ */
395
+ async mfaRejectFidoComplete(
396
+ mfaId: string,
397
+ challengeId: string,
398
+ credential: PublicKeyCredential,
399
+ ): Promise<MfaRequestInfo> {
400
+ return await this.mfaVoteFidoComplete(mfaId, "reject", challengeId, credential);
305
401
  }
306
402
 
307
403
  /**
package/src/error.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { CsErrCode } from "./schema_types";
1
2
  import { operations } from "./schema";
2
3
 
3
4
  /**
@@ -12,6 +13,8 @@ export class ErrResponse extends Error {
12
13
  readonly status?: number;
13
14
  /** HTTP response url */
14
15
  readonly url?: string;
16
+ /** CubeSigner error code */
17
+ readonly errorCode?: CsErrCode;
15
18
 
16
19
  /**
17
20
  * @param {Partial<ErrResponse>} init Initializer
@@ -37,6 +40,7 @@ export class SessionExpiredError extends ErrResponse {
37
40
  status: 403,
38
41
  statusText: "Forbidden",
39
42
  operation,
43
+ errorCode: "SessionExpired",
40
44
  });
41
45
  }
42
46
  }
package/src/events.ts CHANGED
@@ -2,6 +2,8 @@ import { ErrResponse } from "./error";
2
2
 
3
3
  export type EventHandler<T> = (event: T) => Promise<void>;
4
4
  export type ErrorEvent = ErrResponse;
5
+
6
+ /* eslint-disable-next-line @typescript-eslint/no-empty-interface */
5
7
  export interface SessionExpiredEvent {}
6
8
 
7
9
  /**
package/src/index.ts CHANGED
@@ -2,7 +2,6 @@ import { envs, EnvInterface } from "./env";
2
2
  import { Client, OidcClient } from "./api";
3
3
  import { CubeSignerClient } from "./client";
4
4
  import { Org } from "./org";
5
- import { JsonFileSessionStorage } from "./session/session_storage";
6
5
 
7
6
  import {
8
7
  SignerSessionStorage,
@@ -11,9 +10,6 @@ import {
11
10
  } from "./session/signer_session_manager";
12
11
  import { CubeSignerResponse } from "./response";
13
12
  import { SignerSession } from "./signer_session";
14
- import { CognitoSessionManager, CognitoSessionStorage } from "./session/cognito_manager";
15
- import { configDir } from "./util";
16
- import * as path from "path";
17
13
  import { MfaReceipt } from "./mfa";
18
14
  import { name, version } from "./../package.json";
19
15
  import { IdentityProof, MfaRequestInfo, RatchetConfig, UserInfo } from "./schema_types";
@@ -23,7 +19,7 @@ export interface CubeSignerOptions {
23
19
  /** The environment to use */
24
20
  env?: EnvInterface;
25
21
  /** The management authorization token */
26
- sessionMgr?: CognitoSessionManager | SignerSessionManager;
22
+ sessionMgr?: SignerSessionManager;
27
23
  /** Optional organization id */
28
24
  orgId?: string;
29
25
  }
@@ -35,7 +31,7 @@ export interface CubeSignerOptions {
35
31
  */
36
32
  export class CubeSigner {
37
33
  readonly #env: EnvInterface;
38
- readonly sessionMgr?: CognitoSessionManager | SignerSessionManager;
34
+ readonly sessionMgr?: SignerSessionManager;
39
35
  #csc?: CubeSignerClient;
40
36
 
41
37
  /**
@@ -70,28 +66,22 @@ export class CubeSigner {
70
66
  /**
71
67
  * Loads an existing management session and creates a CubeSigner instance.
72
68
  *
73
- * @param {CognitoSessionStorage} storage Optional session storage to load
74
- * the session from. If not specified, the management session from the config
75
- * directory will be loaded.
69
+ * @param {SignerSessionStorage} storage Session storage to load the session from.
76
70
  * @return {Promise<CubeSigner>} New CubeSigner instance
77
71
  */
78
- static async loadManagementSession(storage?: CognitoSessionStorage): Promise<CubeSigner> {
72
+ static async loadManagementSession(storage: SignerSessionStorage): Promise<CubeSigner> {
79
73
  return new CubeSigner(<CubeSignerOptions>{
80
- sessionMgr: await CognitoSessionManager.loadManagementSession(storage),
74
+ sessionMgr: await SignerSessionManager.loadFromStorage(storage),
81
75
  });
82
76
  }
83
77
 
84
78
  /**
85
79
  * Loads a signer session from a session storage (e.g., session file).
86
- * @param {SignerSessionStorage} storage Optional session storage to load
87
- * the session from. If not specified, the signer session from the config
88
- * directory will be loaded.
80
+ * @param {SignerSessionStorage} storage Session storage to load the session from.
89
81
  * @return {Promise<SignerSession>} New signer session
90
82
  */
91
- static async loadSignerSession(storage?: SignerSessionStorage): Promise<SignerSession> {
92
- const defaultFilePath = path.join(configDir(), "signer-session.json");
93
- const sss = storage ?? new JsonFileSessionStorage(defaultFilePath);
94
- return await SignerSession.loadSignerSession(sss);
83
+ static async loadSignerSession(storage: SignerSessionStorage): Promise<SignerSession> {
84
+ return await SignerSession.loadSignerSession(storage);
95
85
  }
96
86
 
97
87
  /**
@@ -318,16 +308,12 @@ export * from "./schema_types";
318
308
  export * from "./signer_session";
319
309
  /** Session storage */
320
310
  export * from "./session/session_storage";
321
- /** Session manager */
322
- export * from "./session/session_manager";
323
- /** Management session manager */
324
- export * from "./session/cognito_manager";
325
311
  /** Signer session manager */
326
312
  export * from "./session/signer_session_manager";
313
+ /** Utils */
314
+ export * from "./util";
327
315
  /** User-export decryption helper */
328
316
  export { userExportDecrypt, userExportKeygen } from "./user_export";
329
- /** Export ethers.js Signer */
330
- export * as ethers from "./ethers";
331
317
 
332
318
  /** CubeSigner SDK package name */
333
319
  export const NAME: string = name;