@ledgerhq/revault-sdk 0.26.7 → 0.27.0
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.
- package/lib/onboarding.cjs +21 -11
- package/lib/onboarding.cjs.map +1 -1
- package/lib/onboarding.d.cts +13 -1
- package/lib/onboarding.d.ts +13 -1
- package/lib/onboarding.js +21 -11
- package/lib/onboarding.js.map +1 -1
- package/package.json +2 -2
package/lib/onboarding.cjs
CHANGED
|
@@ -67,11 +67,13 @@ const checkHsmHostingMode = (state, expectedMode) => {
|
|
|
67
67
|
if (state.hsmHostingMode !== expectedMode) throw new Error(`HSM hosting mode should be ${expectedMode} but is ${state.hsmHostingMode}`);
|
|
68
68
|
};
|
|
69
69
|
/* v8 ignore next -- @preserve */
|
|
70
|
-
const checkExternalSigners = (state, externalSigners) => {
|
|
70
|
+
const checkExternalSigners = (state, externalSigners, debugAuthToken) => {
|
|
71
71
|
const hasExternalSigners = externalSigners && externalSigners.length > 0;
|
|
72
|
-
const
|
|
72
|
+
const canFetchExternalSigner = !!debugAuthToken;
|
|
73
|
+
const errorMessage = (0, ts_pattern.match)(state.hsmHostingMode).with("HOSTED", () => !hasExternalSigners ? null : "Hosted HSM does not support external signers").with("ON_PREM", () => hasExternalSigners || canFetchExternalSigner ? null : "On-premises HSM requires at least 1 external signer or a debug auth token").exhaustive();
|
|
73
74
|
if (errorMessage !== null) throw new Error(errorMessage);
|
|
74
75
|
};
|
|
76
|
+
const base64ToHex = (value) => Buffer.from(value, "base64").toString("hex");
|
|
75
77
|
const STEPS = {
|
|
76
78
|
PENDING_DEVICE_CLAIMS: async ({ state, engine }, logger) => {
|
|
77
79
|
const promises = [];
|
|
@@ -164,21 +166,28 @@ const STEPS = {
|
|
|
164
166
|
}));
|
|
165
167
|
return engine.client.onboarding.commitReviewByMasterAdmins.mutate({ onboardingId });
|
|
166
168
|
},
|
|
167
|
-
PENDING_EXTERNAL_SIGNERS_REGISTRATION: async ({ state, engine, externalSigners, debugAuthToken }, logger) => {
|
|
169
|
+
PENDING_EXTERNAL_SIGNERS_REGISTRATION: async ({ state, engine, externalSigners, debugAuthToken, signerSeed }, logger) => {
|
|
168
170
|
checkHsmHostingMode(state, "ON_PREM");
|
|
169
|
-
(0, invariant.default)(externalSigners && externalSigners.length > 0, "External signers must exist");
|
|
170
171
|
const { id: onboardingId } = state;
|
|
172
|
+
let externalSignerPublicKeys = externalSigners;
|
|
171
173
|
if (debugAuthToken) {
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
+
const debugClient = engine.createClient({ debugAuthToken });
|
|
175
|
+
const seed = signerSeed ?? Buffer.from(await require_crypto.getMasterSeed(engine.__options.salt)).toString("base64");
|
|
176
|
+
await debugClient.debug.insertExternalSignerSeed.mutate({
|
|
174
177
|
workspaceName: state.workspaceName,
|
|
175
|
-
seed
|
|
178
|
+
seed
|
|
176
179
|
});
|
|
177
180
|
logger.info("Inserted external signer seed");
|
|
181
|
+
if (!externalSignerPublicKeys || externalSignerPublicKeys.length === 0) {
|
|
182
|
+
const { publicKey } = await debugClient.debug.getExternalSignerAuthKeypair.query({ workspaceName: state.workspaceName });
|
|
183
|
+
externalSignerPublicKeys = [base64ToHex(publicKey)];
|
|
184
|
+
logger.info("Fetched external signer public key");
|
|
185
|
+
}
|
|
178
186
|
}
|
|
187
|
+
(0, invariant.default)(externalSignerPublicKeys && externalSignerPublicKeys.length > 0, "External signers must exist");
|
|
179
188
|
state = await engine.client.onboarding.startExternalSignersRegistration.mutate({
|
|
180
189
|
onboardingId,
|
|
181
|
-
externalSigners
|
|
190
|
+
externalSigners: externalSignerPublicKeys
|
|
182
191
|
});
|
|
183
192
|
const toCollect = state.masterAdmins.filter((admin) => !admin.reviewOfExternalSigners?.signature);
|
|
184
193
|
await Promise.all(toCollect.map(async (admin) => {
|
|
@@ -205,11 +214,11 @@ const STEPS = {
|
|
|
205
214
|
PENDING_WORKSPACE_INITIALIZATION: async ({ state, engine }) => engine.client.onboarding.initializeWorkspace.mutate({ onboardingId: state.id })
|
|
206
215
|
};
|
|
207
216
|
async function onboard(opts, logger) {
|
|
208
|
-
const { engine, externalSigners, debugAuthToken, untilStep } = opts;
|
|
217
|
+
const { engine, externalSigners, debugAuthToken, signerSeed, untilStep } = opts;
|
|
209
218
|
const { __onboardingId } = engine;
|
|
210
219
|
logger.info(`Joining onboarding ${__onboardingId}`);
|
|
211
220
|
let state = await engine.client.onboarding.getOnboarding.query({ onboardingId: __onboardingId });
|
|
212
|
-
checkExternalSigners(state, externalSigners);
|
|
221
|
+
checkExternalSigners(state, externalSigners, debugAuthToken);
|
|
213
222
|
while (state.step !== "COMPLETED") {
|
|
214
223
|
if (untilStep && state.step === untilStep) {
|
|
215
224
|
logger.info("Skipping the rest of the onboarding");
|
|
@@ -221,7 +230,8 @@ async function onboard(opts, logger) {
|
|
|
221
230
|
engine,
|
|
222
231
|
state,
|
|
223
232
|
externalSigners,
|
|
224
|
-
debugAuthToken
|
|
233
|
+
debugAuthToken,
|
|
234
|
+
signerSeed
|
|
225
235
|
}, logger);
|
|
226
236
|
}
|
|
227
237
|
}
|
package/lib/onboarding.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding.cjs","names":["getMasterSeed"],"sources":["../src/onboarding.ts"],"sourcesContent":["import type {\n ClaimedRole,\n HsmHostingMode,\n OnboardingFullStateResponse,\n OnboardingStep,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport { match } from \"ts-pattern\";\n\nimport { getMasterSeed } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\n\nimport type { Engine, WithOnboarding } from \"./engine/types\";\n\ntype StepAction = (\n options: {\n engine: Engine<WithOnboarding>;\n state: OnboardingFullStateResponse;\n externalSigners?: string[];\n debugAuthToken?: string;\n },\n logger: Logger,\n) => Promise<OnboardingFullStateResponse>;\n\nconst roleLabels: Record<ClaimedRole, string> = {\n WRAPPING_KEY_OWNER: \"Wrapping Key\",\n MASTER_ADMIN: \"Admin\",\n SHARED_OWNER: \"Shared Owner\",\n};\n\nconst devices: { index: number; role: ClaimedRole; name: string }[] = [\n { index: 1, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 1` },\n { index: 2, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 2` },\n { index: 3, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 3` },\n { index: 4, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 1` },\n { index: 5, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 2` },\n { index: 6, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 3` },\n { index: 7, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 1` },\n { index: 8, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 2` },\n { index: 9, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 3` },\n];\n\nconst deviceNameToIndex = (name: string): number => {\n const index = devices.find((d) => d.name === name)?.index;\n invariant(index !== undefined, `Unknown device ${name}`);\n return index;\n};\n\nconst checkHsmHostingMode = (\n state: OnboardingFullStateResponse,\n expectedMode: HsmHostingMode,\n): void => {\n /* v8 ignore next -- @preserve */\n if (state.hsmHostingMode !== expectedMode) {\n throw new Error(`HSM hosting mode should be ${expectedMode} but is ${state.hsmHostingMode}`);\n }\n};\n\n/* v8 ignore next -- @preserve */\nconst checkExternalSigners = (\n state: OnboardingFullStateResponse,\n externalSigners: string[] | undefined,\n): void => {\n const hasExternalSigners = externalSigners && externalSigners.length > 0;\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () =>\n !hasExternalSigners ? null : \"Hosted HSM does not support external signers\",\n )\n .with(\"ON_PREM\", () =>\n hasExternalSigners ? null : \"On-premises HSM requires at least 1 external signer\",\n )\n .exhaustive();\n if (errorMessage !== null) {\n throw new Error(errorMessage);\n }\n};\n\nexport const STEPS = {\n /**\n * Devices claiming\n */\n PENDING_DEVICE_CLAIMS: async ({ state, engine }, logger) => {\n const promises: Promise<void>[] = [];\n for (const device of devices) {\n if (state.hsmHostingMode === \"ON_PREM\" && device.role === \"SHARED_OWNER\") {\n continue;\n }\n /* v8 ignore else -- @preserve */\n if (\n state.claimedDevices.find(\n /* v8 ignore next -- @preserve */\n (c) => c.deviceName === device.name,\n ) === undefined\n ) {\n const promise = engine\n .withDeviceIndex(device.index)\n .claimDevice({ role: device.role, deviceName: device.name })\n .then(() => logger.info(`Claimed ${device.name}`));\n promises.push(promise);\n }\n }\n await Promise.all(promises);\n return engine.client.onboarding.commitDeviceClaims.mutate({ onboardingId: state.id });\n },\n\n /**\n * Wrapping Key provisioning\n */\n PENDING_WRAPPING_KEY_PROVISIONING: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startWrappingKeyProvisioning.mutate({ onboardingId });\n const wrappingKey = state.wrappingKey!;\n const toCollect = state.claimedDevices\n .filter((claimed) => {\n if (claimed.role !== \"WRAPPING_KEY_OWNER\") return false;\n const inFragment = !!state.wrappingKey?.fragments.find(\n /* v8 ignore next -- @preserve */\n (f) => f.pubKey === claimed.pubKey,\n );\n return !inFragment;\n })\n .map((c) => {\n const index = deviceNameToIndex(c.deviceName);\n return index;\n });\n await Promise.all(\n toCollect.map((index) =>\n engine\n .withDeviceIndex(index)\n .collectWrappingKeyFragment(wrappingKey)\n .then(() => logger.info(`Collected Wrapping Key ${index}`)),\n ),\n );\n return engine.client.onboarding.commitWrappingKey.mutate({ onboardingId });\n },\n\n /**\n * Init Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION_INIT: async ({ engine, state }) =>\n engine.client.onboarding.startMasterAdminsRegistration.mutate({ onboardingId: state.id }),\n\n /**\n * Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"MASTER_ADMIN\") return false;\n const hasRegistered = !!state.masterAdmins.find(\n /* v8 ignore next -- @preserve */\n (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"ADMIN\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.createMasterAdminGroup.mutate({ onboardingId });\n },\n\n /**\n * Init Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION_INIT: async ({ engine, state }) => {\n checkHsmHostingMode(state, \"HOSTED\");\n return engine.client.onboarding.startSharedOwnersRegistration.mutate({\n onboardingId: state.id,\n });\n },\n\n /**\n * Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"SHARED_OWNER\") return false;\n const hasRegistered = !!state.sharedOwners.find(\n /* v8 ignore next -- @preserve */ (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"SHARED_OWNER\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.commitSharedOwnersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Review by master admins\n */\n PENDING_REVIEW_BY_MASTER_ADMINS: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startReviewByMasterAdmins.mutate({ onboardingId });\n const toCollect = state.masterAdmins.filter((admin) => !admin.review?.signature);\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.review?.challenge;\n await engine.withDeviceIndex(index).reviewSharedOwner(challenge!);\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitReviewByMasterAdmins.mutate({ onboardingId });\n },\n\n PENDING_EXTERNAL_SIGNERS_REGISTRATION: async (\n { state, engine, externalSigners, debugAuthToken },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n invariant(externalSigners && externalSigners.length > 0, \"External signers must exist\");\n const { id: onboardingId } = state;\n if (debugAuthToken) {\n const masterSeed = await getMasterSeed(engine.__options.salt);\n await engine.createClient({ debugAuthToken }).debug.insertExternalSignerSeed.mutate({\n workspaceName: state.workspaceName,\n seed: Buffer.from(masterSeed).toString(\"base64\"),\n });\n logger.info(\"Inserted external signer seed\");\n }\n state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\n externalSigners,\n });\n const toCollect = state.masterAdmins.filter(\n (admin) => !admin.reviewOfExternalSigners?.signature,\n );\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.reviewOfExternalSigners?.challenge;\n await engine.withDeviceIndex(index).reviewExternalSigners(challenge!); // same as review for shared owner, but with different challenge\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitExternalSignersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Seed provisioning\n */\n PENDING_SEED_PROVISIONING: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startSeedProvisioning.mutate({ onboardingId });\n const toCollect = state.sharedOwners.filter((so) => !so.review?.seedFragment);\n await Promise.all(\n toCollect.map(async (so) => {\n const index = deviceNameToIndex(so.name);\n const challenge = so.review?.seedChallenge;\n await engine.withDeviceIndex(index).collectSeedFragment(challenge!);\n logger.info(`Collected fragment for ${so.name}`);\n }),\n );\n return engine.client.onboarding.commitSeedProvisioning.mutate({ onboardingId });\n },\n\n /**\n * Workspace initialization\n */\n PENDING_WORKSPACE_INITIALIZATION: async ({ state, engine }) =>\n engine.client.onboarding.initializeWorkspace.mutate({ onboardingId: state.id }),\n} as const satisfies Record<Exclude<OnboardingStep, \"COMPLETED\">, StepAction>;\n\nexport async function onboard(\n opts: {\n engine: Engine<WithOnboarding>;\n externalSigners?: string[];\n debugAuthToken?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, externalSigners, debugAuthToken, untilStep } = opts;\n\n const { __onboardingId } = engine;\n logger.info(`Joining onboarding ${__onboardingId}`);\n let state = await engine.client.onboarding.getOnboarding.query({\n onboardingId: __onboardingId,\n });\n\n checkExternalSigners(state, externalSigners);\n\n while (state.step !== \"COMPLETED\") {\n if (untilStep && state.step === untilStep) {\n logger.info(\"Skipping the rest of the onboarding\");\n break;\n }\n const step = STEPS[state.step];\n logger.info(step.name);\n state = await step({ engine, state, externalSigners, debugAuthToken }, logger);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"onboarding.cjs","names":["getMasterSeed"],"sources":["../src/onboarding.ts"],"sourcesContent":["import type {\n ClaimedRole,\n HsmHostingMode,\n OnboardingFullStateResponse,\n OnboardingStep,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport { match } from \"ts-pattern\";\n\nimport { getMasterSeed } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\n\nimport type { Engine, WithOnboarding } from \"./engine/types\";\n\ntype StepAction = (\n options: {\n engine: Engine<WithOnboarding>;\n state: OnboardingFullStateResponse;\n externalSigners?: string[];\n debugAuthToken?: string;\n signerSeed?: string;\n },\n logger: Logger,\n) => Promise<OnboardingFullStateResponse>;\n\nconst roleLabels: Record<ClaimedRole, string> = {\n WRAPPING_KEY_OWNER: \"Wrapping Key\",\n MASTER_ADMIN: \"Admin\",\n SHARED_OWNER: \"Shared Owner\",\n};\n\nconst devices: { index: number; role: ClaimedRole; name: string }[] = [\n { index: 1, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 1` },\n { index: 2, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 2` },\n { index: 3, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 3` },\n { index: 4, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 1` },\n { index: 5, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 2` },\n { index: 6, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 3` },\n { index: 7, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 1` },\n { index: 8, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 2` },\n { index: 9, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 3` },\n];\n\nconst deviceNameToIndex = (name: string): number => {\n const index = devices.find((d) => d.name === name)?.index;\n invariant(index !== undefined, `Unknown device ${name}`);\n return index;\n};\n\nconst checkHsmHostingMode = (\n state: OnboardingFullStateResponse,\n expectedMode: HsmHostingMode,\n): void => {\n /* v8 ignore next -- @preserve */\n if (state.hsmHostingMode !== expectedMode) {\n throw new Error(`HSM hosting mode should be ${expectedMode} but is ${state.hsmHostingMode}`);\n }\n};\n\n/* v8 ignore next -- @preserve */\nconst checkExternalSigners = (\n state: OnboardingFullStateResponse,\n externalSigners: string[] | undefined,\n debugAuthToken: string | undefined,\n): void => {\n const hasExternalSigners = externalSigners && externalSigners.length > 0;\n const canFetchExternalSigner = !!debugAuthToken;\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () =>\n !hasExternalSigners ? null : \"Hosted HSM does not support external signers\",\n )\n .with(\"ON_PREM\", () =>\n hasExternalSigners || canFetchExternalSigner\n ? null\n : \"On-premises HSM requires at least 1 external signer or a debug auth token\",\n )\n .exhaustive();\n if (errorMessage !== null) {\n throw new Error(errorMessage);\n }\n};\n\nconst base64ToHex = (value: string): string => Buffer.from(value, \"base64\").toString(\"hex\");\n\nexport const STEPS = {\n /**\n * Devices claiming\n */\n PENDING_DEVICE_CLAIMS: async ({ state, engine }, logger) => {\n const promises: Promise<void>[] = [];\n for (const device of devices) {\n if (state.hsmHostingMode === \"ON_PREM\" && device.role === \"SHARED_OWNER\") {\n continue;\n }\n /* v8 ignore else -- @preserve */\n if (\n state.claimedDevices.find(\n /* v8 ignore next -- @preserve */\n (c) => c.deviceName === device.name,\n ) === undefined\n ) {\n const promise = engine\n .withDeviceIndex(device.index)\n .claimDevice({ role: device.role, deviceName: device.name })\n .then(() => logger.info(`Claimed ${device.name}`));\n promises.push(promise);\n }\n }\n await Promise.all(promises);\n return engine.client.onboarding.commitDeviceClaims.mutate({ onboardingId: state.id });\n },\n\n /**\n * Wrapping Key provisioning\n */\n PENDING_WRAPPING_KEY_PROVISIONING: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startWrappingKeyProvisioning.mutate({ onboardingId });\n const wrappingKey = state.wrappingKey!;\n const toCollect = state.claimedDevices\n .filter((claimed) => {\n if (claimed.role !== \"WRAPPING_KEY_OWNER\") return false;\n const inFragment = !!state.wrappingKey?.fragments.find(\n /* v8 ignore next -- @preserve */\n (f) => f.pubKey === claimed.pubKey,\n );\n return !inFragment;\n })\n .map((c) => {\n const index = deviceNameToIndex(c.deviceName);\n return index;\n });\n await Promise.all(\n toCollect.map((index) =>\n engine\n .withDeviceIndex(index)\n .collectWrappingKeyFragment(wrappingKey)\n .then(() => logger.info(`Collected Wrapping Key ${index}`)),\n ),\n );\n return engine.client.onboarding.commitWrappingKey.mutate({ onboardingId });\n },\n\n /**\n * Init Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION_INIT: async ({ engine, state }) =>\n engine.client.onboarding.startMasterAdminsRegistration.mutate({ onboardingId: state.id }),\n\n /**\n * Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"MASTER_ADMIN\") return false;\n const hasRegistered = !!state.masterAdmins.find(\n /* v8 ignore next -- @preserve */\n (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"ADMIN\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.createMasterAdminGroup.mutate({ onboardingId });\n },\n\n /**\n * Init Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION_INIT: async ({ engine, state }) => {\n checkHsmHostingMode(state, \"HOSTED\");\n return engine.client.onboarding.startSharedOwnersRegistration.mutate({\n onboardingId: state.id,\n });\n },\n\n /**\n * Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"SHARED_OWNER\") return false;\n const hasRegistered = !!state.sharedOwners.find(\n /* v8 ignore next -- @preserve */ (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"SHARED_OWNER\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.commitSharedOwnersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Review by master admins\n */\n PENDING_REVIEW_BY_MASTER_ADMINS: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startReviewByMasterAdmins.mutate({ onboardingId });\n const toCollect = state.masterAdmins.filter((admin) => !admin.review?.signature);\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.review?.challenge;\n await engine.withDeviceIndex(index).reviewSharedOwner(challenge!);\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitReviewByMasterAdmins.mutate({ onboardingId });\n },\n\n PENDING_EXTERNAL_SIGNERS_REGISTRATION: async (\n { state, engine, externalSigners, debugAuthToken, signerSeed },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n const { id: onboardingId } = state;\n let externalSignerPublicKeys = externalSigners;\n if (debugAuthToken) {\n const debugClient = engine.createClient({ debugAuthToken });\n const seed =\n signerSeed ?? Buffer.from(await getMasterSeed(engine.__options.salt)).toString(\"base64\");\n await debugClient.debug.insertExternalSignerSeed.mutate({\n workspaceName: state.workspaceName,\n seed,\n });\n logger.info(\"Inserted external signer seed\");\n\n if (!externalSignerPublicKeys || externalSignerPublicKeys.length === 0) {\n const { publicKey } = await debugClient.debug.getExternalSignerAuthKeypair.query({\n workspaceName: state.workspaceName,\n });\n externalSignerPublicKeys = [base64ToHex(publicKey)];\n logger.info(\"Fetched external signer public key\");\n }\n }\n invariant(\n externalSignerPublicKeys && externalSignerPublicKeys.length > 0,\n \"External signers must exist\",\n );\n state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\n externalSigners: externalSignerPublicKeys,\n });\n const toCollect = state.masterAdmins.filter(\n (admin) => !admin.reviewOfExternalSigners?.signature,\n );\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.reviewOfExternalSigners?.challenge;\n await engine.withDeviceIndex(index).reviewExternalSigners(challenge!); // same as review for shared owner, but with different challenge\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitExternalSignersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Seed provisioning\n */\n PENDING_SEED_PROVISIONING: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startSeedProvisioning.mutate({ onboardingId });\n const toCollect = state.sharedOwners.filter((so) => !so.review?.seedFragment);\n await Promise.all(\n toCollect.map(async (so) => {\n const index = deviceNameToIndex(so.name);\n const challenge = so.review?.seedChallenge;\n await engine.withDeviceIndex(index).collectSeedFragment(challenge!);\n logger.info(`Collected fragment for ${so.name}`);\n }),\n );\n return engine.client.onboarding.commitSeedProvisioning.mutate({ onboardingId });\n },\n\n /**\n * Workspace initialization\n */\n PENDING_WORKSPACE_INITIALIZATION: async ({ state, engine }) =>\n engine.client.onboarding.initializeWorkspace.mutate({ onboardingId: state.id }),\n} as const satisfies Record<Exclude<OnboardingStep, \"COMPLETED\">, StepAction>;\n\nexport async function onboard(\n opts: {\n engine: Engine<WithOnboarding>;\n externalSigners?: string[];\n debugAuthToken?: string;\n signerSeed?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, externalSigners, debugAuthToken, signerSeed, untilStep } = opts;\n\n const { __onboardingId } = engine;\n logger.info(`Joining onboarding ${__onboardingId}`);\n let state = await engine.client.onboarding.getOnboarding.query({\n onboardingId: __onboardingId,\n });\n\n checkExternalSigners(state, externalSigners, debugAuthToken);\n\n while (state.step !== \"COMPLETED\") {\n if (untilStep && state.step === untilStep) {\n logger.info(\"Skipping the rest of the onboarding\");\n break;\n }\n const step = STEPS[state.step];\n logger.info(step.name);\n state = await step({ engine, state, externalSigners, debugAuthToken, signerSeed }, logger);\n }\n}\n"],"mappings":"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"}
|
package/lib/onboarding.d.cts
CHANGED
|
@@ -15,6 +15,7 @@ declare const STEPS: {
|
|
|
15
15
|
state: OnboardingFullStateResponse;
|
|
16
16
|
externalSigners?: string[];
|
|
17
17
|
debugAuthToken?: string;
|
|
18
|
+
signerSeed?: string;
|
|
18
19
|
}, logger: Logger) => Promise<{
|
|
19
20
|
id: string;
|
|
20
21
|
workspaceName: string;
|
|
@@ -208,6 +209,7 @@ declare const STEPS: {
|
|
|
208
209
|
state: OnboardingFullStateResponse;
|
|
209
210
|
externalSigners?: string[];
|
|
210
211
|
debugAuthToken?: string;
|
|
212
|
+
signerSeed?: string;
|
|
211
213
|
}, logger: Logger) => Promise<{
|
|
212
214
|
id: string;
|
|
213
215
|
workspaceName: string;
|
|
@@ -401,6 +403,7 @@ declare const STEPS: {
|
|
|
401
403
|
state: OnboardingFullStateResponse;
|
|
402
404
|
externalSigners?: string[];
|
|
403
405
|
debugAuthToken?: string;
|
|
406
|
+
signerSeed?: string;
|
|
404
407
|
}) => Promise<{
|
|
405
408
|
id: string;
|
|
406
409
|
workspaceName: string;
|
|
@@ -594,6 +597,7 @@ declare const STEPS: {
|
|
|
594
597
|
state: OnboardingFullStateResponse;
|
|
595
598
|
externalSigners?: string[];
|
|
596
599
|
debugAuthToken?: string;
|
|
600
|
+
signerSeed?: string;
|
|
597
601
|
}, logger: Logger) => Promise<{
|
|
598
602
|
id: string;
|
|
599
603
|
workspaceName: string;
|
|
@@ -787,6 +791,7 @@ declare const STEPS: {
|
|
|
787
791
|
state: OnboardingFullStateResponse;
|
|
788
792
|
externalSigners?: string[];
|
|
789
793
|
debugAuthToken?: string;
|
|
794
|
+
signerSeed?: string;
|
|
790
795
|
}) => Promise<{
|
|
791
796
|
id: string;
|
|
792
797
|
workspaceName: string;
|
|
@@ -980,6 +985,7 @@ declare const STEPS: {
|
|
|
980
985
|
state: OnboardingFullStateResponse;
|
|
981
986
|
externalSigners?: string[];
|
|
982
987
|
debugAuthToken?: string;
|
|
988
|
+
signerSeed?: string;
|
|
983
989
|
}, logger: Logger) => Promise<{
|
|
984
990
|
id: string;
|
|
985
991
|
workspaceName: string;
|
|
@@ -1173,6 +1179,7 @@ declare const STEPS: {
|
|
|
1173
1179
|
state: OnboardingFullStateResponse;
|
|
1174
1180
|
externalSigners?: string[];
|
|
1175
1181
|
debugAuthToken?: string;
|
|
1182
|
+
signerSeed?: string;
|
|
1176
1183
|
}, logger: Logger) => Promise<{
|
|
1177
1184
|
id: string;
|
|
1178
1185
|
workspaceName: string;
|
|
@@ -1359,12 +1366,14 @@ declare const STEPS: {
|
|
|
1359
1366
|
state,
|
|
1360
1367
|
engine,
|
|
1361
1368
|
externalSigners,
|
|
1362
|
-
debugAuthToken
|
|
1369
|
+
debugAuthToken,
|
|
1370
|
+
signerSeed
|
|
1363
1371
|
}: {
|
|
1364
1372
|
engine: Engine<WithOnboarding>;
|
|
1365
1373
|
state: OnboardingFullStateResponse;
|
|
1366
1374
|
externalSigners?: string[];
|
|
1367
1375
|
debugAuthToken?: string;
|
|
1376
|
+
signerSeed?: string;
|
|
1368
1377
|
}, logger: Logger) => Promise<{
|
|
1369
1378
|
id: string;
|
|
1370
1379
|
workspaceName: string;
|
|
@@ -1558,6 +1567,7 @@ declare const STEPS: {
|
|
|
1558
1567
|
state: OnboardingFullStateResponse;
|
|
1559
1568
|
externalSigners?: string[];
|
|
1560
1569
|
debugAuthToken?: string;
|
|
1570
|
+
signerSeed?: string;
|
|
1561
1571
|
}, logger: Logger) => Promise<{
|
|
1562
1572
|
id: string;
|
|
1563
1573
|
workspaceName: string;
|
|
@@ -1751,6 +1761,7 @@ declare const STEPS: {
|
|
|
1751
1761
|
state: OnboardingFullStateResponse;
|
|
1752
1762
|
externalSigners?: string[];
|
|
1753
1763
|
debugAuthToken?: string;
|
|
1764
|
+
signerSeed?: string;
|
|
1754
1765
|
}) => Promise<{
|
|
1755
1766
|
id: string;
|
|
1756
1767
|
workspaceName: string;
|
|
@@ -1938,6 +1949,7 @@ declare function onboard(opts: {
|
|
|
1938
1949
|
engine: Engine<WithOnboarding>;
|
|
1939
1950
|
externalSigners?: string[];
|
|
1940
1951
|
debugAuthToken?: string;
|
|
1952
|
+
signerSeed?: string;
|
|
1941
1953
|
untilStep?: OnboardingStep;
|
|
1942
1954
|
}, logger: Logger): Promise<void>;
|
|
1943
1955
|
//#endregion
|
package/lib/onboarding.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ declare const STEPS: {
|
|
|
15
15
|
state: OnboardingFullStateResponse;
|
|
16
16
|
externalSigners?: string[];
|
|
17
17
|
debugAuthToken?: string;
|
|
18
|
+
signerSeed?: string;
|
|
18
19
|
}, logger: Logger) => Promise<{
|
|
19
20
|
id: string;
|
|
20
21
|
workspaceName: string;
|
|
@@ -208,6 +209,7 @@ declare const STEPS: {
|
|
|
208
209
|
state: OnboardingFullStateResponse;
|
|
209
210
|
externalSigners?: string[];
|
|
210
211
|
debugAuthToken?: string;
|
|
212
|
+
signerSeed?: string;
|
|
211
213
|
}, logger: Logger) => Promise<{
|
|
212
214
|
id: string;
|
|
213
215
|
workspaceName: string;
|
|
@@ -401,6 +403,7 @@ declare const STEPS: {
|
|
|
401
403
|
state: OnboardingFullStateResponse;
|
|
402
404
|
externalSigners?: string[];
|
|
403
405
|
debugAuthToken?: string;
|
|
406
|
+
signerSeed?: string;
|
|
404
407
|
}) => Promise<{
|
|
405
408
|
id: string;
|
|
406
409
|
workspaceName: string;
|
|
@@ -594,6 +597,7 @@ declare const STEPS: {
|
|
|
594
597
|
state: OnboardingFullStateResponse;
|
|
595
598
|
externalSigners?: string[];
|
|
596
599
|
debugAuthToken?: string;
|
|
600
|
+
signerSeed?: string;
|
|
597
601
|
}, logger: Logger) => Promise<{
|
|
598
602
|
id: string;
|
|
599
603
|
workspaceName: string;
|
|
@@ -787,6 +791,7 @@ declare const STEPS: {
|
|
|
787
791
|
state: OnboardingFullStateResponse;
|
|
788
792
|
externalSigners?: string[];
|
|
789
793
|
debugAuthToken?: string;
|
|
794
|
+
signerSeed?: string;
|
|
790
795
|
}) => Promise<{
|
|
791
796
|
id: string;
|
|
792
797
|
workspaceName: string;
|
|
@@ -980,6 +985,7 @@ declare const STEPS: {
|
|
|
980
985
|
state: OnboardingFullStateResponse;
|
|
981
986
|
externalSigners?: string[];
|
|
982
987
|
debugAuthToken?: string;
|
|
988
|
+
signerSeed?: string;
|
|
983
989
|
}, logger: Logger) => Promise<{
|
|
984
990
|
id: string;
|
|
985
991
|
workspaceName: string;
|
|
@@ -1173,6 +1179,7 @@ declare const STEPS: {
|
|
|
1173
1179
|
state: OnboardingFullStateResponse;
|
|
1174
1180
|
externalSigners?: string[];
|
|
1175
1181
|
debugAuthToken?: string;
|
|
1182
|
+
signerSeed?: string;
|
|
1176
1183
|
}, logger: Logger) => Promise<{
|
|
1177
1184
|
id: string;
|
|
1178
1185
|
workspaceName: string;
|
|
@@ -1359,12 +1366,14 @@ declare const STEPS: {
|
|
|
1359
1366
|
state,
|
|
1360
1367
|
engine,
|
|
1361
1368
|
externalSigners,
|
|
1362
|
-
debugAuthToken
|
|
1369
|
+
debugAuthToken,
|
|
1370
|
+
signerSeed
|
|
1363
1371
|
}: {
|
|
1364
1372
|
engine: Engine<WithOnboarding>;
|
|
1365
1373
|
state: OnboardingFullStateResponse;
|
|
1366
1374
|
externalSigners?: string[];
|
|
1367
1375
|
debugAuthToken?: string;
|
|
1376
|
+
signerSeed?: string;
|
|
1368
1377
|
}, logger: Logger) => Promise<{
|
|
1369
1378
|
id: string;
|
|
1370
1379
|
workspaceName: string;
|
|
@@ -1558,6 +1567,7 @@ declare const STEPS: {
|
|
|
1558
1567
|
state: OnboardingFullStateResponse;
|
|
1559
1568
|
externalSigners?: string[];
|
|
1560
1569
|
debugAuthToken?: string;
|
|
1570
|
+
signerSeed?: string;
|
|
1561
1571
|
}, logger: Logger) => Promise<{
|
|
1562
1572
|
id: string;
|
|
1563
1573
|
workspaceName: string;
|
|
@@ -1751,6 +1761,7 @@ declare const STEPS: {
|
|
|
1751
1761
|
state: OnboardingFullStateResponse;
|
|
1752
1762
|
externalSigners?: string[];
|
|
1753
1763
|
debugAuthToken?: string;
|
|
1764
|
+
signerSeed?: string;
|
|
1754
1765
|
}) => Promise<{
|
|
1755
1766
|
id: string;
|
|
1756
1767
|
workspaceName: string;
|
|
@@ -1938,6 +1949,7 @@ declare function onboard(opts: {
|
|
|
1938
1949
|
engine: Engine<WithOnboarding>;
|
|
1939
1950
|
externalSigners?: string[];
|
|
1940
1951
|
debugAuthToken?: string;
|
|
1952
|
+
signerSeed?: string;
|
|
1941
1953
|
untilStep?: OnboardingStep;
|
|
1942
1954
|
}, logger: Logger): Promise<void>;
|
|
1943
1955
|
//#endregion
|
package/lib/onboarding.js
CHANGED
|
@@ -64,11 +64,13 @@ const checkHsmHostingMode = (state, expectedMode) => {
|
|
|
64
64
|
if (state.hsmHostingMode !== expectedMode) throw new Error(`HSM hosting mode should be ${expectedMode} but is ${state.hsmHostingMode}`);
|
|
65
65
|
};
|
|
66
66
|
/* v8 ignore next -- @preserve */
|
|
67
|
-
const checkExternalSigners = (state, externalSigners) => {
|
|
67
|
+
const checkExternalSigners = (state, externalSigners, debugAuthToken) => {
|
|
68
68
|
const hasExternalSigners = externalSigners && externalSigners.length > 0;
|
|
69
|
-
const
|
|
69
|
+
const canFetchExternalSigner = !!debugAuthToken;
|
|
70
|
+
const errorMessage = match(state.hsmHostingMode).with("HOSTED", () => !hasExternalSigners ? null : "Hosted HSM does not support external signers").with("ON_PREM", () => hasExternalSigners || canFetchExternalSigner ? null : "On-premises HSM requires at least 1 external signer or a debug auth token").exhaustive();
|
|
70
71
|
if (errorMessage !== null) throw new Error(errorMessage);
|
|
71
72
|
};
|
|
73
|
+
const base64ToHex = (value) => Buffer.from(value, "base64").toString("hex");
|
|
72
74
|
const STEPS = {
|
|
73
75
|
PENDING_DEVICE_CLAIMS: async ({ state, engine }, logger) => {
|
|
74
76
|
const promises = [];
|
|
@@ -161,21 +163,28 @@ const STEPS = {
|
|
|
161
163
|
}));
|
|
162
164
|
return engine.client.onboarding.commitReviewByMasterAdmins.mutate({ onboardingId });
|
|
163
165
|
},
|
|
164
|
-
PENDING_EXTERNAL_SIGNERS_REGISTRATION: async ({ state, engine, externalSigners, debugAuthToken }, logger) => {
|
|
166
|
+
PENDING_EXTERNAL_SIGNERS_REGISTRATION: async ({ state, engine, externalSigners, debugAuthToken, signerSeed }, logger) => {
|
|
165
167
|
checkHsmHostingMode(state, "ON_PREM");
|
|
166
|
-
invariant(externalSigners && externalSigners.length > 0, "External signers must exist");
|
|
167
168
|
const { id: onboardingId } = state;
|
|
169
|
+
let externalSignerPublicKeys = externalSigners;
|
|
168
170
|
if (debugAuthToken) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
+
const debugClient = engine.createClient({ debugAuthToken });
|
|
172
|
+
const seed = signerSeed ?? Buffer.from(await getMasterSeed(engine.__options.salt)).toString("base64");
|
|
173
|
+
await debugClient.debug.insertExternalSignerSeed.mutate({
|
|
171
174
|
workspaceName: state.workspaceName,
|
|
172
|
-
seed
|
|
175
|
+
seed
|
|
173
176
|
});
|
|
174
177
|
logger.info("Inserted external signer seed");
|
|
178
|
+
if (!externalSignerPublicKeys || externalSignerPublicKeys.length === 0) {
|
|
179
|
+
const { publicKey } = await debugClient.debug.getExternalSignerAuthKeypair.query({ workspaceName: state.workspaceName });
|
|
180
|
+
externalSignerPublicKeys = [base64ToHex(publicKey)];
|
|
181
|
+
logger.info("Fetched external signer public key");
|
|
182
|
+
}
|
|
175
183
|
}
|
|
184
|
+
invariant(externalSignerPublicKeys && externalSignerPublicKeys.length > 0, "External signers must exist");
|
|
176
185
|
state = await engine.client.onboarding.startExternalSignersRegistration.mutate({
|
|
177
186
|
onboardingId,
|
|
178
|
-
externalSigners
|
|
187
|
+
externalSigners: externalSignerPublicKeys
|
|
179
188
|
});
|
|
180
189
|
const toCollect = state.masterAdmins.filter((admin) => !admin.reviewOfExternalSigners?.signature);
|
|
181
190
|
await Promise.all(toCollect.map(async (admin) => {
|
|
@@ -202,11 +211,11 @@ const STEPS = {
|
|
|
202
211
|
PENDING_WORKSPACE_INITIALIZATION: async ({ state, engine }) => engine.client.onboarding.initializeWorkspace.mutate({ onboardingId: state.id })
|
|
203
212
|
};
|
|
204
213
|
async function onboard(opts, logger) {
|
|
205
|
-
const { engine, externalSigners, debugAuthToken, untilStep } = opts;
|
|
214
|
+
const { engine, externalSigners, debugAuthToken, signerSeed, untilStep } = opts;
|
|
206
215
|
const { __onboardingId } = engine;
|
|
207
216
|
logger.info(`Joining onboarding ${__onboardingId}`);
|
|
208
217
|
let state = await engine.client.onboarding.getOnboarding.query({ onboardingId: __onboardingId });
|
|
209
|
-
checkExternalSigners(state, externalSigners);
|
|
218
|
+
checkExternalSigners(state, externalSigners, debugAuthToken);
|
|
210
219
|
while (state.step !== "COMPLETED") {
|
|
211
220
|
if (untilStep && state.step === untilStep) {
|
|
212
221
|
logger.info("Skipping the rest of the onboarding");
|
|
@@ -218,7 +227,8 @@ async function onboard(opts, logger) {
|
|
|
218
227
|
engine,
|
|
219
228
|
state,
|
|
220
229
|
externalSigners,
|
|
221
|
-
debugAuthToken
|
|
230
|
+
debugAuthToken,
|
|
231
|
+
signerSeed
|
|
222
232
|
}, logger);
|
|
223
233
|
}
|
|
224
234
|
}
|
package/lib/onboarding.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboarding.js","names":[],"sources":["../src/onboarding.ts"],"sourcesContent":["import type {\n ClaimedRole,\n HsmHostingMode,\n OnboardingFullStateResponse,\n OnboardingStep,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport { match } from \"ts-pattern\";\n\nimport { getMasterSeed } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\n\nimport type { Engine, WithOnboarding } from \"./engine/types\";\n\ntype StepAction = (\n options: {\n engine: Engine<WithOnboarding>;\n state: OnboardingFullStateResponse;\n externalSigners?: string[];\n debugAuthToken?: string;\n },\n logger: Logger,\n) => Promise<OnboardingFullStateResponse>;\n\nconst roleLabels: Record<ClaimedRole, string> = {\n WRAPPING_KEY_OWNER: \"Wrapping Key\",\n MASTER_ADMIN: \"Admin\",\n SHARED_OWNER: \"Shared Owner\",\n};\n\nconst devices: { index: number; role: ClaimedRole; name: string }[] = [\n { index: 1, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 1` },\n { index: 2, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 2` },\n { index: 3, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 3` },\n { index: 4, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 1` },\n { index: 5, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 2` },\n { index: 6, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 3` },\n { index: 7, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 1` },\n { index: 8, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 2` },\n { index: 9, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 3` },\n];\n\nconst deviceNameToIndex = (name: string): number => {\n const index = devices.find((d) => d.name === name)?.index;\n invariant(index !== undefined, `Unknown device ${name}`);\n return index;\n};\n\nconst checkHsmHostingMode = (\n state: OnboardingFullStateResponse,\n expectedMode: HsmHostingMode,\n): void => {\n /* v8 ignore next -- @preserve */\n if (state.hsmHostingMode !== expectedMode) {\n throw new Error(`HSM hosting mode should be ${expectedMode} but is ${state.hsmHostingMode}`);\n }\n};\n\n/* v8 ignore next -- @preserve */\nconst checkExternalSigners = (\n state: OnboardingFullStateResponse,\n externalSigners: string[] | undefined,\n): void => {\n const hasExternalSigners = externalSigners && externalSigners.length > 0;\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () =>\n !hasExternalSigners ? null : \"Hosted HSM does not support external signers\",\n )\n .with(\"ON_PREM\", () =>\n hasExternalSigners ? null : \"On-premises HSM requires at least 1 external signer\",\n )\n .exhaustive();\n if (errorMessage !== null) {\n throw new Error(errorMessage);\n }\n};\n\nexport const STEPS = {\n /**\n * Devices claiming\n */\n PENDING_DEVICE_CLAIMS: async ({ state, engine }, logger) => {\n const promises: Promise<void>[] = [];\n for (const device of devices) {\n if (state.hsmHostingMode === \"ON_PREM\" && device.role === \"SHARED_OWNER\") {\n continue;\n }\n /* v8 ignore else -- @preserve */\n if (\n state.claimedDevices.find(\n /* v8 ignore next -- @preserve */\n (c) => c.deviceName === device.name,\n ) === undefined\n ) {\n const promise = engine\n .withDeviceIndex(device.index)\n .claimDevice({ role: device.role, deviceName: device.name })\n .then(() => logger.info(`Claimed ${device.name}`));\n promises.push(promise);\n }\n }\n await Promise.all(promises);\n return engine.client.onboarding.commitDeviceClaims.mutate({ onboardingId: state.id });\n },\n\n /**\n * Wrapping Key provisioning\n */\n PENDING_WRAPPING_KEY_PROVISIONING: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startWrappingKeyProvisioning.mutate({ onboardingId });\n const wrappingKey = state.wrappingKey!;\n const toCollect = state.claimedDevices\n .filter((claimed) => {\n if (claimed.role !== \"WRAPPING_KEY_OWNER\") return false;\n const inFragment = !!state.wrappingKey?.fragments.find(\n /* v8 ignore next -- @preserve */\n (f) => f.pubKey === claimed.pubKey,\n );\n return !inFragment;\n })\n .map((c) => {\n const index = deviceNameToIndex(c.deviceName);\n return index;\n });\n await Promise.all(\n toCollect.map((index) =>\n engine\n .withDeviceIndex(index)\n .collectWrappingKeyFragment(wrappingKey)\n .then(() => logger.info(`Collected Wrapping Key ${index}`)),\n ),\n );\n return engine.client.onboarding.commitWrappingKey.mutate({ onboardingId });\n },\n\n /**\n * Init Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION_INIT: async ({ engine, state }) =>\n engine.client.onboarding.startMasterAdminsRegistration.mutate({ onboardingId: state.id }),\n\n /**\n * Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"MASTER_ADMIN\") return false;\n const hasRegistered = !!state.masterAdmins.find(\n /* v8 ignore next -- @preserve */\n (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"ADMIN\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.createMasterAdminGroup.mutate({ onboardingId });\n },\n\n /**\n * Init Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION_INIT: async ({ engine, state }) => {\n checkHsmHostingMode(state, \"HOSTED\");\n return engine.client.onboarding.startSharedOwnersRegistration.mutate({\n onboardingId: state.id,\n });\n },\n\n /**\n * Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"SHARED_OWNER\") return false;\n const hasRegistered = !!state.sharedOwners.find(\n /* v8 ignore next -- @preserve */ (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"SHARED_OWNER\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.commitSharedOwnersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Review by master admins\n */\n PENDING_REVIEW_BY_MASTER_ADMINS: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startReviewByMasterAdmins.mutate({ onboardingId });\n const toCollect = state.masterAdmins.filter((admin) => !admin.review?.signature);\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.review?.challenge;\n await engine.withDeviceIndex(index).reviewSharedOwner(challenge!);\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitReviewByMasterAdmins.mutate({ onboardingId });\n },\n\n PENDING_EXTERNAL_SIGNERS_REGISTRATION: async (\n { state, engine, externalSigners, debugAuthToken },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n invariant(externalSigners && externalSigners.length > 0, \"External signers must exist\");\n const { id: onboardingId } = state;\n if (debugAuthToken) {\n const masterSeed = await getMasterSeed(engine.__options.salt);\n await engine.createClient({ debugAuthToken }).debug.insertExternalSignerSeed.mutate({\n workspaceName: state.workspaceName,\n seed: Buffer.from(masterSeed).toString(\"base64\"),\n });\n logger.info(\"Inserted external signer seed\");\n }\n state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\n externalSigners,\n });\n const toCollect = state.masterAdmins.filter(\n (admin) => !admin.reviewOfExternalSigners?.signature,\n );\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.reviewOfExternalSigners?.challenge;\n await engine.withDeviceIndex(index).reviewExternalSigners(challenge!); // same as review for shared owner, but with different challenge\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitExternalSignersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Seed provisioning\n */\n PENDING_SEED_PROVISIONING: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startSeedProvisioning.mutate({ onboardingId });\n const toCollect = state.sharedOwners.filter((so) => !so.review?.seedFragment);\n await Promise.all(\n toCollect.map(async (so) => {\n const index = deviceNameToIndex(so.name);\n const challenge = so.review?.seedChallenge;\n await engine.withDeviceIndex(index).collectSeedFragment(challenge!);\n logger.info(`Collected fragment for ${so.name}`);\n }),\n );\n return engine.client.onboarding.commitSeedProvisioning.mutate({ onboardingId });\n },\n\n /**\n * Workspace initialization\n */\n PENDING_WORKSPACE_INITIALIZATION: async ({ state, engine }) =>\n engine.client.onboarding.initializeWorkspace.mutate({ onboardingId: state.id }),\n} as const satisfies Record<Exclude<OnboardingStep, \"COMPLETED\">, StepAction>;\n\nexport async function onboard(\n opts: {\n engine: Engine<WithOnboarding>;\n externalSigners?: string[];\n debugAuthToken?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, externalSigners, debugAuthToken, untilStep } = opts;\n\n const { __onboardingId } = engine;\n logger.info(`Joining onboarding ${__onboardingId}`);\n let state = await engine.client.onboarding.getOnboarding.query({\n onboardingId: __onboardingId,\n });\n\n checkExternalSigners(state, externalSigners);\n\n while (state.step !== \"COMPLETED\") {\n if (untilStep && state.step === untilStep) {\n logger.info(\"Skipping the rest of the onboarding\");\n break;\n }\n const step = STEPS[state.step];\n logger.info(step.name);\n state = await step({ engine, state, externalSigners, debugAuthToken }, logger);\n }\n}\n"],"mappings":";;;;AAwBA,MAAM,aAA0C;CAC9C,oBAAoB;CACpB,cAAc;CACd,cAAc;CACf;AAED,MAAM,UAAgE;CACpE;EAAE,OAAO;EAAG,MAAM;EAAsB,MAAM,GAAG,WAAW,mBAAmB;EAAK;CACpF;EAAE,OAAO;EAAG,MAAM;EAAsB,MAAM,GAAG,WAAW,mBAAmB;EAAK;CACpF;EAAE,OAAO;EAAG,MAAM;EAAsB,MAAM,GAAG,WAAW,mBAAmB;EAAK;CACpF;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;EAAK;CACxE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;EAAK;CACxE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;EAAK;CACxE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;EAAK;CACxE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;EAAK;CACxE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;EAAK;CACzE;AAED,MAAM,qBAAqB,SAAyB;CAClD,MAAM,QAAQ,QAAQ,MAAM,MAAM,EAAE,SAAS,KAAK,EAAE;AACpD,WAAU,UAAU,KAAA,GAAW,kBAAkB,OAAO;AACxD,QAAO;;AAGT,MAAM,uBACJ,OACA,iBACS;;AAET,KAAI,MAAM,mBAAmB,aAC3B,OAAM,IAAI,MAAM,8BAA8B,aAAa,UAAU,MAAM,iBAAiB;;;AAKhG,MAAM,wBACJ,OACA,oBACS;CACT,MAAM,qBAAqB,mBAAmB,gBAAgB,SAAS;CACvE,MAAM,eAAe,MAAM,MAAM,eAAe,CAC7C,KAAK,gBACJ,CAAC,qBAAqB,OAAO,+CAC9B,CACA,KAAK,iBACJ,qBAAqB,OAAO,sDAC7B,CACA,YAAY;AACf,KAAI,iBAAiB,KACnB,OAAM,IAAI,MAAM,aAAa;;AAIjC,MAAa,QAAQ;CAInB,uBAAuB,OAAO,EAAE,OAAO,UAAU,WAAW;EAC1D,MAAM,WAA4B,EAAE;AACpC,OAAK,MAAM,UAAU,SAAS;AAC5B,OAAI,MAAM,mBAAmB,aAAa,OAAO,SAAS,eACxD;;AAGF,OACE,MAAM,eAAe;;KAElB,MAAM,EAAE,eAAe,OAAO;IAChC,KAAK,KAAA,GACN;IACA,MAAM,UAAU,OACb,gBAAgB,OAAO,MAAM,CAC7B,YAAY;KAAE,MAAM,OAAO;KAAM,YAAY,OAAO;KAAM,CAAC,CAC3D,WAAW,OAAO,KAAK,WAAW,OAAO,OAAO,CAAC;AACpD,aAAS,KAAK,QAAQ;;;AAG1B,QAAM,QAAQ,IAAI,SAAS;AAC3B,SAAO,OAAO,OAAO,WAAW,mBAAmB,OAAO,EAAE,cAAc,MAAM,IAAI,CAAC;;CAMvF,mCAAmC,OAAO,EAAE,OAAO,UAAU,WAAW;EACtE,MAAM,EAAE,IAAI,iBAAiB;AAC7B,UAAQ,MAAM,OAAO,OAAO,WAAW,6BAA6B,OAAO,EAAE,cAAc,CAAC;EAC5F,MAAM,cAAc,MAAM;EAC1B,MAAM,YAAY,MAAM,eACrB,QAAQ,YAAY;AACnB,OAAI,QAAQ,SAAS,qBAAsB,QAAO;AAKlD,UAAO,CAJY,CAAC,CAAC,MAAM,aAAa,UAAU;;KAE/C,MAAM,EAAE,WAAW,QAAQ;IAC7B;IAED,CACD,KAAK,MAAM;AAEV,UADc,kBAAkB,EAAE,WAAW;IAE7C;AACJ,QAAM,QAAQ,IACZ,UAAU,KAAK,UACb,OACG,gBAAgB,MAAM,CACtB,2BAA2B,YAAY,CACvC,WAAW,OAAO,KAAK,0BAA0B,QAAQ,CAAC,CAC9D,CACF;AACD,SAAO,OAAO,OAAO,WAAW,kBAAkB,OAAO,EAAE,cAAc,CAAC;;CAM5E,yCAAyC,OAAO,EAAE,QAAQ,YACxD,OAAO,OAAO,WAAW,8BAA8B,OAAO,EAAE,cAAc,MAAM,IAAI,CAAC;CAK3F,oCAAoC,OAAO,EAAE,OAAO,UAAU,WAAW;EACvE,MAAM,EAAE,IAAI,iBAAiB;EAC7B,MAAM,aAAa,MAAM,eAAe,QAAQ,YAAY;AAC1D,OAAI,QAAQ,SAAS,eAAgB,QAAO;AAK5C,UAAO,CAJe,CAAC,CAAC,MAAM,aAAa;;KAExC,MAAM,EAAE,WAAW,QAAQ;IAC7B;IAED;AACF,QAAM,QAAQ,IACZ,WAAW,IAAI,OAAO,EAAE,YAAY,WAAW;GAC7C,MAAM,QAAQ,kBAAkB,KAAK;AACrC,SAAM,OAAO,gBAAgB,MAAM,CAAC,eAAe;IAAE,MAAM;IAAS;IAAM,CAAC;AAC3E,UAAO,KAAK,cAAc,OAAO;IACjC,CACH;AACD,SAAO,OAAO,OAAO,WAAW,uBAAuB,OAAO,EAAE,cAAc,CAAC;;CAMjF,yCAAyC,OAAO,EAAE,QAAQ,YAAY;AACpE,sBAAoB,OAAO,SAAS;AACpC,SAAO,OAAO,OAAO,WAAW,8BAA8B,OAAO,EACnE,cAAc,MAAM,IACrB,CAAC;;CAMJ,oCAAoC,OAAO,EAAE,OAAO,UAAU,WAAW;AACvE,sBAAoB,OAAO,SAAS;EACpC,MAAM,EAAE,IAAI,iBAAiB;EAC7B,MAAM,aAAa,MAAM,eAAe,QAAQ,YAAY;AAC1D,OAAI,QAAQ,SAAS,eAAgB,QAAO;AAI5C,UAAO,CAHe,CAAC,CAAC,MAAM,aAAa;;KACN,MAAM,EAAE,WAAW,QAAQ;IAC/D;IAED;AACF,QAAM,QAAQ,IACZ,WAAW,IAAI,OAAO,EAAE,YAAY,WAAW;GAC7C,MAAM,QAAQ,kBAAkB,KAAK;AACrC,SAAM,OAAO,gBAAgB,MAAM,CAAC,eAAe;IAAE,MAAM;IAAgB;IAAM,CAAC;AAClF,UAAO,KAAK,cAAc,OAAO;IACjC,CACH;AACD,SAAO,OAAO,OAAO,WAAW,+BAA+B,OAAO,EAAE,cAAc,CAAC;;CAMzF,iCAAiC,OAAO,EAAE,OAAO,UAAU,WAAW;EACpE,MAAM,EAAE,IAAI,iBAAiB;AAC7B,UAAQ,MAAM,OAAO,OAAO,WAAW,0BAA0B,OAAO,EAAE,cAAc,CAAC;EACzF,MAAM,YAAY,MAAM,aAAa,QAAQ,UAAU,CAAC,MAAM,QAAQ,UAAU;AAChF,QAAM,QAAQ,IACZ,UAAU,IAAI,OAAO,UAAU;GAC7B,MAAM,QAAQ,kBAAkB,MAAM,KAAK;GAC3C,MAAM,YAAY,MAAM,QAAQ;AAChC,SAAM,OAAO,gBAAgB,MAAM,CAAC,kBAAkB,UAAW;AACjE,UAAO,KAAK,iBAAiB,MAAM,OAAO;IAC1C,CACH;AACD,SAAO,OAAO,OAAO,WAAW,2BAA2B,OAAO,EAAE,cAAc,CAAC;;CAGrF,uCAAuC,OACrC,EAAE,OAAO,QAAQ,iBAAiB,kBAClC,WACG;AACH,sBAAoB,OAAO,UAAU;AACrC,YAAU,mBAAmB,gBAAgB,SAAS,GAAG,8BAA8B;EACvF,MAAM,EAAE,IAAI,iBAAiB;AAC7B,MAAI,gBAAgB;GAClB,MAAM,aAAa,MAAM,cAAc,OAAO,UAAU,KAAK;AAC7D,SAAM,OAAO,aAAa,EAAE,gBAAgB,CAAC,CAAC,MAAM,yBAAyB,OAAO;IAClF,eAAe,MAAM;IACrB,MAAM,OAAO,KAAK,WAAW,CAAC,SAAS,SAAS;IACjD,CAAC;AACF,UAAO,KAAK,gCAAgC;;AAE9C,UAAQ,MAAM,OAAO,OAAO,WAAW,iCAAiC,OAAO;GAC7E;GACA;GACD,CAAC;EACF,MAAM,YAAY,MAAM,aAAa,QAClC,UAAU,CAAC,MAAM,yBAAyB,UAC5C;AACD,QAAM,QAAQ,IACZ,UAAU,IAAI,OAAO,UAAU;GAC7B,MAAM,QAAQ,kBAAkB,MAAM,KAAK;GAC3C,MAAM,YAAY,MAAM,yBAAyB;AACjD,SAAM,OAAO,gBAAgB,MAAM,CAAC,sBAAsB,UAAW;AACrE,UAAO,KAAK,iBAAiB,MAAM,OAAO;IAC1C,CACH;AACD,SAAO,OAAO,OAAO,WAAW,kCAAkC,OAAO,EAAE,cAAc,CAAC;;CAM5F,2BAA2B,OAAO,EAAE,OAAO,UAAU,WAAW;AAC9D,sBAAoB,OAAO,SAAS;EACpC,MAAM,EAAE,IAAI,iBAAiB;AAC7B,UAAQ,MAAM,OAAO,OAAO,WAAW,sBAAsB,OAAO,EAAE,cAAc,CAAC;EACrF,MAAM,YAAY,MAAM,aAAa,QAAQ,OAAO,CAAC,GAAG,QAAQ,aAAa;AAC7E,QAAM,QAAQ,IACZ,UAAU,IAAI,OAAO,OAAO;GAC1B,MAAM,QAAQ,kBAAkB,GAAG,KAAK;GACxC,MAAM,YAAY,GAAG,QAAQ;AAC7B,SAAM,OAAO,gBAAgB,MAAM,CAAC,oBAAoB,UAAW;AACnE,UAAO,KAAK,0BAA0B,GAAG,OAAO;IAChD,CACH;AACD,SAAO,OAAO,OAAO,WAAW,uBAAuB,OAAO,EAAE,cAAc,CAAC;;CAMjF,kCAAkC,OAAO,EAAE,OAAO,aAChD,OAAO,OAAO,WAAW,oBAAoB,OAAO,EAAE,cAAc,MAAM,IAAI,CAAC;CAClF;AAED,eAAsB,QACpB,MAMA,QACe;CACf,MAAM,EAAE,QAAQ,iBAAiB,gBAAgB,cAAc;CAE/D,MAAM,EAAE,mBAAmB;AAC3B,QAAO,KAAK,sBAAsB,iBAAiB;CACnD,IAAI,QAAQ,MAAM,OAAO,OAAO,WAAW,cAAc,MAAM,EAC7D,cAAc,gBACf,CAAC;AAEF,sBAAqB,OAAO,gBAAgB;AAE5C,QAAO,MAAM,SAAS,aAAa;AACjC,MAAI,aAAa,MAAM,SAAS,WAAW;AACzC,UAAO,KAAK,sCAAsC;AAClD;;EAEF,MAAM,OAAO,MAAM,MAAM;AACzB,SAAO,KAAK,KAAK,KAAK;AACtB,UAAQ,MAAM,KAAK;GAAE;GAAQ;GAAO;GAAiB;GAAgB,EAAE,OAAO"}
|
|
1
|
+
{"version":3,"file":"onboarding.js","names":[],"sources":["../src/onboarding.ts"],"sourcesContent":["import type {\n ClaimedRole,\n HsmHostingMode,\n OnboardingFullStateResponse,\n OnboardingStep,\n} from \"@ledgerhq/revault-api\";\nimport invariant from \"invariant\";\nimport { match } from \"ts-pattern\";\n\nimport { getMasterSeed } from \"@/crypto\";\nimport type { Logger } from \"@/logger\";\n\nimport type { Engine, WithOnboarding } from \"./engine/types\";\n\ntype StepAction = (\n options: {\n engine: Engine<WithOnboarding>;\n state: OnboardingFullStateResponse;\n externalSigners?: string[];\n debugAuthToken?: string;\n signerSeed?: string;\n },\n logger: Logger,\n) => Promise<OnboardingFullStateResponse>;\n\nconst roleLabels: Record<ClaimedRole, string> = {\n WRAPPING_KEY_OWNER: \"Wrapping Key\",\n MASTER_ADMIN: \"Admin\",\n SHARED_OWNER: \"Shared Owner\",\n};\n\nconst devices: { index: number; role: ClaimedRole; name: string }[] = [\n { index: 1, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 1` },\n { index: 2, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 2` },\n { index: 3, role: \"WRAPPING_KEY_OWNER\", name: `${roleLabels.WRAPPING_KEY_OWNER} 3` },\n { index: 4, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 1` },\n { index: 5, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 2` },\n { index: 6, role: \"MASTER_ADMIN\", name: `${roleLabels.MASTER_ADMIN} 3` },\n { index: 7, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 1` },\n { index: 8, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 2` },\n { index: 9, role: \"SHARED_OWNER\", name: `${roleLabels.SHARED_OWNER} 3` },\n];\n\nconst deviceNameToIndex = (name: string): number => {\n const index = devices.find((d) => d.name === name)?.index;\n invariant(index !== undefined, `Unknown device ${name}`);\n return index;\n};\n\nconst checkHsmHostingMode = (\n state: OnboardingFullStateResponse,\n expectedMode: HsmHostingMode,\n): void => {\n /* v8 ignore next -- @preserve */\n if (state.hsmHostingMode !== expectedMode) {\n throw new Error(`HSM hosting mode should be ${expectedMode} but is ${state.hsmHostingMode}`);\n }\n};\n\n/* v8 ignore next -- @preserve */\nconst checkExternalSigners = (\n state: OnboardingFullStateResponse,\n externalSigners: string[] | undefined,\n debugAuthToken: string | undefined,\n): void => {\n const hasExternalSigners = externalSigners && externalSigners.length > 0;\n const canFetchExternalSigner = !!debugAuthToken;\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () =>\n !hasExternalSigners ? null : \"Hosted HSM does not support external signers\",\n )\n .with(\"ON_PREM\", () =>\n hasExternalSigners || canFetchExternalSigner\n ? null\n : \"On-premises HSM requires at least 1 external signer or a debug auth token\",\n )\n .exhaustive();\n if (errorMessage !== null) {\n throw new Error(errorMessage);\n }\n};\n\nconst base64ToHex = (value: string): string => Buffer.from(value, \"base64\").toString(\"hex\");\n\nexport const STEPS = {\n /**\n * Devices claiming\n */\n PENDING_DEVICE_CLAIMS: async ({ state, engine }, logger) => {\n const promises: Promise<void>[] = [];\n for (const device of devices) {\n if (state.hsmHostingMode === \"ON_PREM\" && device.role === \"SHARED_OWNER\") {\n continue;\n }\n /* v8 ignore else -- @preserve */\n if (\n state.claimedDevices.find(\n /* v8 ignore next -- @preserve */\n (c) => c.deviceName === device.name,\n ) === undefined\n ) {\n const promise = engine\n .withDeviceIndex(device.index)\n .claimDevice({ role: device.role, deviceName: device.name })\n .then(() => logger.info(`Claimed ${device.name}`));\n promises.push(promise);\n }\n }\n await Promise.all(promises);\n return engine.client.onboarding.commitDeviceClaims.mutate({ onboardingId: state.id });\n },\n\n /**\n * Wrapping Key provisioning\n */\n PENDING_WRAPPING_KEY_PROVISIONING: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startWrappingKeyProvisioning.mutate({ onboardingId });\n const wrappingKey = state.wrappingKey!;\n const toCollect = state.claimedDevices\n .filter((claimed) => {\n if (claimed.role !== \"WRAPPING_KEY_OWNER\") return false;\n const inFragment = !!state.wrappingKey?.fragments.find(\n /* v8 ignore next -- @preserve */\n (f) => f.pubKey === claimed.pubKey,\n );\n return !inFragment;\n })\n .map((c) => {\n const index = deviceNameToIndex(c.deviceName);\n return index;\n });\n await Promise.all(\n toCollect.map((index) =>\n engine\n .withDeviceIndex(index)\n .collectWrappingKeyFragment(wrappingKey)\n .then(() => logger.info(`Collected Wrapping Key ${index}`)),\n ),\n );\n return engine.client.onboarding.commitWrappingKey.mutate({ onboardingId });\n },\n\n /**\n * Init Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION_INIT: async ({ engine, state }) =>\n engine.client.onboarding.startMasterAdminsRegistration.mutate({ onboardingId: state.id }),\n\n /**\n * Master Admins registration\n */\n PENDING_MASTER_ADMINS_REGISTRATION: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"MASTER_ADMIN\") return false;\n const hasRegistered = !!state.masterAdmins.find(\n /* v8 ignore next -- @preserve */\n (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"ADMIN\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.createMasterAdminGroup.mutate({ onboardingId });\n },\n\n /**\n * Init Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION_INIT: async ({ engine, state }) => {\n checkHsmHostingMode(state, \"HOSTED\");\n return engine.client.onboarding.startSharedOwnersRegistration.mutate({\n onboardingId: state.id,\n });\n },\n\n /**\n * Shared Owners registration\n */\n PENDING_SHARED_OWNERS_REGISTRATION: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n const toRegister = state.claimedDevices.filter((claimed) => {\n if (claimed.role !== \"SHARED_OWNER\") return false;\n const hasRegistered = !!state.sharedOwners.find(\n /* v8 ignore next -- @preserve */ (a) => a.pubKey === claimed.pubKey,\n );\n return !hasRegistered;\n });\n await Promise.all(\n toRegister.map(async ({ deviceName: name }) => {\n const index = deviceNameToIndex(name);\n await engine.withDeviceIndex(index).registerDevice({ role: \"SHARED_OWNER\", name });\n logger.info(`Registered ${name}`);\n }),\n );\n return engine.client.onboarding.commitSharedOwnersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Review by master admins\n */\n PENDING_REVIEW_BY_MASTER_ADMINS: async ({ state, engine }, logger) => {\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startReviewByMasterAdmins.mutate({ onboardingId });\n const toCollect = state.masterAdmins.filter((admin) => !admin.review?.signature);\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.review?.challenge;\n await engine.withDeviceIndex(index).reviewSharedOwner(challenge!);\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitReviewByMasterAdmins.mutate({ onboardingId });\n },\n\n PENDING_EXTERNAL_SIGNERS_REGISTRATION: async (\n { state, engine, externalSigners, debugAuthToken, signerSeed },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n const { id: onboardingId } = state;\n let externalSignerPublicKeys = externalSigners;\n if (debugAuthToken) {\n const debugClient = engine.createClient({ debugAuthToken });\n const seed =\n signerSeed ?? Buffer.from(await getMasterSeed(engine.__options.salt)).toString(\"base64\");\n await debugClient.debug.insertExternalSignerSeed.mutate({\n workspaceName: state.workspaceName,\n seed,\n });\n logger.info(\"Inserted external signer seed\");\n\n if (!externalSignerPublicKeys || externalSignerPublicKeys.length === 0) {\n const { publicKey } = await debugClient.debug.getExternalSignerAuthKeypair.query({\n workspaceName: state.workspaceName,\n });\n externalSignerPublicKeys = [base64ToHex(publicKey)];\n logger.info(\"Fetched external signer public key\");\n }\n }\n invariant(\n externalSignerPublicKeys && externalSignerPublicKeys.length > 0,\n \"External signers must exist\",\n );\n state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\n externalSigners: externalSignerPublicKeys,\n });\n const toCollect = state.masterAdmins.filter(\n (admin) => !admin.reviewOfExternalSigners?.signature,\n );\n await Promise.all(\n toCollect.map(async (admin) => {\n const index = deviceNameToIndex(admin.name);\n const challenge = admin.reviewOfExternalSigners?.challenge;\n await engine.withDeviceIndex(index).reviewExternalSigners(challenge!); // same as review for shared owner, but with different challenge\n logger.info(`Approved with ${admin.name}`);\n }),\n );\n return engine.client.onboarding.commitExternalSignersRegistration.mutate({ onboardingId });\n },\n\n /**\n * Seed provisioning\n */\n PENDING_SEED_PROVISIONING: async ({ state, engine }, logger) => {\n checkHsmHostingMode(state, \"HOSTED\");\n const { id: onboardingId } = state;\n state = await engine.client.onboarding.startSeedProvisioning.mutate({ onboardingId });\n const toCollect = state.sharedOwners.filter((so) => !so.review?.seedFragment);\n await Promise.all(\n toCollect.map(async (so) => {\n const index = deviceNameToIndex(so.name);\n const challenge = so.review?.seedChallenge;\n await engine.withDeviceIndex(index).collectSeedFragment(challenge!);\n logger.info(`Collected fragment for ${so.name}`);\n }),\n );\n return engine.client.onboarding.commitSeedProvisioning.mutate({ onboardingId });\n },\n\n /**\n * Workspace initialization\n */\n PENDING_WORKSPACE_INITIALIZATION: async ({ state, engine }) =>\n engine.client.onboarding.initializeWorkspace.mutate({ onboardingId: state.id }),\n} as const satisfies Record<Exclude<OnboardingStep, \"COMPLETED\">, StepAction>;\n\nexport async function onboard(\n opts: {\n engine: Engine<WithOnboarding>;\n externalSigners?: string[];\n debugAuthToken?: string;\n signerSeed?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, externalSigners, debugAuthToken, signerSeed, untilStep } = opts;\n\n const { __onboardingId } = engine;\n logger.info(`Joining onboarding ${__onboardingId}`);\n let state = await engine.client.onboarding.getOnboarding.query({\n onboardingId: __onboardingId,\n });\n\n checkExternalSigners(state, externalSigners, debugAuthToken);\n\n while (state.step !== \"COMPLETED\") {\n if (untilStep && state.step === untilStep) {\n logger.info(\"Skipping the rest of the onboarding\");\n break;\n }\n const step = STEPS[state.step];\n logger.info(step.name);\n state = await step({ engine, state, externalSigners, debugAuthToken, signerSeed }, logger);\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/revault-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"ts-pattern": "^5.9.0",
|
|
65
65
|
"uuid": "^14.0.0",
|
|
66
66
|
"zod": "^4.3.6",
|
|
67
|
-
"@ledgerhq/revault-api": "1.
|
|
67
|
+
"@ledgerhq/revault-api": "1.63.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@eslint/js": "^9.39.4",
|