@ledgerhq/revault-sdk 0.28.1 → 0.28.2
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 +1 -0
- package/lib/onboarding.cjs.map +1 -1
- package/lib/onboarding.d.cts +10 -0
- package/lib/onboarding.d.ts +10 -0
- package/lib/onboarding.js +1 -0
- package/lib/onboarding.js.map +1 -1
- package/package.json +2 -2
package/lib/onboarding.cjs
CHANGED
|
@@ -79,6 +79,7 @@ const STEPS = {
|
|
|
79
79
|
const promises = [];
|
|
80
80
|
for (const device of devices) {
|
|
81
81
|
if (state.hsmHostingMode === "ON_PREM" && device.role === "SHARED_OWNER") continue;
|
|
82
|
+
if (state.skipWrappingKey && device.role === "WRAPPING_KEY_OWNER") continue;
|
|
82
83
|
/* v8 ignore else -- @preserve */
|
|
83
84
|
if (state.claimedDevices.find(
|
|
84
85
|
/* v8 ignore next -- @preserve */
|
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 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 debugAuthToken: string | undefined,\n): void => {\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () => null)\n .with(\"ON_PREM\", () => (debugAuthToken ? null : \"On-premises HSM requires a debug auth token\"))\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, debugAuthToken, signerSeed },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n const { id: onboardingId } = state;\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 state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\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 debugAuthToken?: string;\n signerSeed?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, 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, 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, debugAuthToken, signerSeed }, 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 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 debugAuthToken: string | undefined,\n): void => {\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () => null)\n .with(\"ON_PREM\", () => (debugAuthToken ? null : \"On-premises HSM requires a debug auth token\"))\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 if (state.skipWrappingKey && device.role === \"WRAPPING_KEY_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, debugAuthToken, signerSeed },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n const { id: onboardingId } = state;\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 state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\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 debugAuthToken?: string;\n signerSeed?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, 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, 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, debugAuthToken, signerSeed }, logger);\n }\n}\n"],"mappings":"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"}
|
package/lib/onboarding.d.cts
CHANGED
|
@@ -20,6 +20,7 @@ declare const STEPS: {
|
|
|
20
20
|
workspaceName: string;
|
|
21
21
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
22
22
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
23
|
+
skipWrappingKey: boolean;
|
|
23
24
|
claimedDevices: {
|
|
24
25
|
pubKey: string;
|
|
25
26
|
deviceUserId: string;
|
|
@@ -213,6 +214,7 @@ declare const STEPS: {
|
|
|
213
214
|
workspaceName: string;
|
|
214
215
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
215
216
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
217
|
+
skipWrappingKey: boolean;
|
|
216
218
|
claimedDevices: {
|
|
217
219
|
pubKey: string;
|
|
218
220
|
deviceUserId: string;
|
|
@@ -406,6 +408,7 @@ declare const STEPS: {
|
|
|
406
408
|
workspaceName: string;
|
|
407
409
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
408
410
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
411
|
+
skipWrappingKey: boolean;
|
|
409
412
|
claimedDevices: {
|
|
410
413
|
pubKey: string;
|
|
411
414
|
deviceUserId: string;
|
|
@@ -599,6 +602,7 @@ declare const STEPS: {
|
|
|
599
602
|
workspaceName: string;
|
|
600
603
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
601
604
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
605
|
+
skipWrappingKey: boolean;
|
|
602
606
|
claimedDevices: {
|
|
603
607
|
pubKey: string;
|
|
604
608
|
deviceUserId: string;
|
|
@@ -792,6 +796,7 @@ declare const STEPS: {
|
|
|
792
796
|
workspaceName: string;
|
|
793
797
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
794
798
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
799
|
+
skipWrappingKey: boolean;
|
|
795
800
|
claimedDevices: {
|
|
796
801
|
pubKey: string;
|
|
797
802
|
deviceUserId: string;
|
|
@@ -985,6 +990,7 @@ declare const STEPS: {
|
|
|
985
990
|
workspaceName: string;
|
|
986
991
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
987
992
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
993
|
+
skipWrappingKey: boolean;
|
|
988
994
|
claimedDevices: {
|
|
989
995
|
pubKey: string;
|
|
990
996
|
deviceUserId: string;
|
|
@@ -1178,6 +1184,7 @@ declare const STEPS: {
|
|
|
1178
1184
|
workspaceName: string;
|
|
1179
1185
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1180
1186
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1187
|
+
skipWrappingKey: boolean;
|
|
1181
1188
|
claimedDevices: {
|
|
1182
1189
|
pubKey: string;
|
|
1183
1190
|
deviceUserId: string;
|
|
@@ -1370,6 +1377,7 @@ declare const STEPS: {
|
|
|
1370
1377
|
workspaceName: string;
|
|
1371
1378
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1372
1379
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1380
|
+
skipWrappingKey: boolean;
|
|
1373
1381
|
claimedDevices: {
|
|
1374
1382
|
pubKey: string;
|
|
1375
1383
|
deviceUserId: string;
|
|
@@ -1563,6 +1571,7 @@ declare const STEPS: {
|
|
|
1563
1571
|
workspaceName: string;
|
|
1564
1572
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1565
1573
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1574
|
+
skipWrappingKey: boolean;
|
|
1566
1575
|
claimedDevices: {
|
|
1567
1576
|
pubKey: string;
|
|
1568
1577
|
deviceUserId: string;
|
|
@@ -1756,6 +1765,7 @@ declare const STEPS: {
|
|
|
1756
1765
|
workspaceName: string;
|
|
1757
1766
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1758
1767
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1768
|
+
skipWrappingKey: boolean;
|
|
1759
1769
|
claimedDevices: {
|
|
1760
1770
|
pubKey: string;
|
|
1761
1771
|
deviceUserId: string;
|
package/lib/onboarding.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ declare const STEPS: {
|
|
|
20
20
|
workspaceName: string;
|
|
21
21
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
22
22
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
23
|
+
skipWrappingKey: boolean;
|
|
23
24
|
claimedDevices: {
|
|
24
25
|
pubKey: string;
|
|
25
26
|
deviceUserId: string;
|
|
@@ -213,6 +214,7 @@ declare const STEPS: {
|
|
|
213
214
|
workspaceName: string;
|
|
214
215
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
215
216
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
217
|
+
skipWrappingKey: boolean;
|
|
216
218
|
claimedDevices: {
|
|
217
219
|
pubKey: string;
|
|
218
220
|
deviceUserId: string;
|
|
@@ -406,6 +408,7 @@ declare const STEPS: {
|
|
|
406
408
|
workspaceName: string;
|
|
407
409
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
408
410
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
411
|
+
skipWrappingKey: boolean;
|
|
409
412
|
claimedDevices: {
|
|
410
413
|
pubKey: string;
|
|
411
414
|
deviceUserId: string;
|
|
@@ -599,6 +602,7 @@ declare const STEPS: {
|
|
|
599
602
|
workspaceName: string;
|
|
600
603
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
601
604
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
605
|
+
skipWrappingKey: boolean;
|
|
602
606
|
claimedDevices: {
|
|
603
607
|
pubKey: string;
|
|
604
608
|
deviceUserId: string;
|
|
@@ -792,6 +796,7 @@ declare const STEPS: {
|
|
|
792
796
|
workspaceName: string;
|
|
793
797
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
794
798
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
799
|
+
skipWrappingKey: boolean;
|
|
795
800
|
claimedDevices: {
|
|
796
801
|
pubKey: string;
|
|
797
802
|
deviceUserId: string;
|
|
@@ -985,6 +990,7 @@ declare const STEPS: {
|
|
|
985
990
|
workspaceName: string;
|
|
986
991
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
987
992
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
993
|
+
skipWrappingKey: boolean;
|
|
988
994
|
claimedDevices: {
|
|
989
995
|
pubKey: string;
|
|
990
996
|
deviceUserId: string;
|
|
@@ -1178,6 +1184,7 @@ declare const STEPS: {
|
|
|
1178
1184
|
workspaceName: string;
|
|
1179
1185
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1180
1186
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1187
|
+
skipWrappingKey: boolean;
|
|
1181
1188
|
claimedDevices: {
|
|
1182
1189
|
pubKey: string;
|
|
1183
1190
|
deviceUserId: string;
|
|
@@ -1370,6 +1377,7 @@ declare const STEPS: {
|
|
|
1370
1377
|
workspaceName: string;
|
|
1371
1378
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1372
1379
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1380
|
+
skipWrappingKey: boolean;
|
|
1373
1381
|
claimedDevices: {
|
|
1374
1382
|
pubKey: string;
|
|
1375
1383
|
deviceUserId: string;
|
|
@@ -1563,6 +1571,7 @@ declare const STEPS: {
|
|
|
1563
1571
|
workspaceName: string;
|
|
1564
1572
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1565
1573
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1574
|
+
skipWrappingKey: boolean;
|
|
1566
1575
|
claimedDevices: {
|
|
1567
1576
|
pubKey: string;
|
|
1568
1577
|
deviceUserId: string;
|
|
@@ -1756,6 +1765,7 @@ declare const STEPS: {
|
|
|
1756
1765
|
workspaceName: string;
|
|
1757
1766
|
hsmHostingMode: "HOSTED" | "ON_PREM";
|
|
1758
1767
|
step: "COMPLETED" | "PENDING_DEVICE_CLAIMS" | "PENDING_EXTERNAL_SIGNERS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION" | "PENDING_MASTER_ADMINS_REGISTRATION_INIT" | "PENDING_REVIEW_BY_MASTER_ADMINS" | "PENDING_SEED_PROVISIONING" | "PENDING_SHARED_OWNERS_REGISTRATION" | "PENDING_SHARED_OWNERS_REGISTRATION_INIT" | "PENDING_WORKSPACE_INITIALIZATION" | "PENDING_WRAPPING_KEY_PROVISIONING";
|
|
1768
|
+
skipWrappingKey: boolean;
|
|
1759
1769
|
claimedDevices: {
|
|
1760
1770
|
pubKey: string;
|
|
1761
1771
|
deviceUserId: string;
|
package/lib/onboarding.js
CHANGED
|
@@ -76,6 +76,7 @@ const STEPS = {
|
|
|
76
76
|
const promises = [];
|
|
77
77
|
for (const device of devices) {
|
|
78
78
|
if (state.hsmHostingMode === "ON_PREM" && device.role === "SHARED_OWNER") continue;
|
|
79
|
+
if (state.skipWrappingKey && device.role === "WRAPPING_KEY_OWNER") continue;
|
|
79
80
|
/* v8 ignore else -- @preserve */
|
|
80
81
|
if (state.claimedDevices.find(
|
|
81
82
|
/* v8 ignore next -- @preserve */
|
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 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 debugAuthToken: string | undefined,\n): void => {\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () => null)\n .with(\"ON_PREM\", () => (debugAuthToken ? null : \"On-premises HSM requires a debug auth token\"))\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, debugAuthToken, signerSeed },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n const { id: onboardingId } = state;\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 state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\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 debugAuthToken?: string;\n signerSeed?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, 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, 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, debugAuthToken, signerSeed }, logger);\n }\n}\n"],"mappings":";;;;AAwBA,MAAM,aAA0C;CAC9C,oBAAoB;CACpB,cAAc;CACd,cAAc;AAChB;AAEA,MAAM,UAAgE;CACpE;EAAE,OAAO;EAAG,MAAM;EAAsB,MAAM,GAAG,WAAW,mBAAmB;CAAI;CACnF;EAAE,OAAO;EAAG,MAAM;EAAsB,MAAM,GAAG,WAAW,mBAAmB;CAAI;CACnF;EAAE,OAAO;EAAG,MAAM;EAAsB,MAAM,GAAG,WAAW,mBAAmB;CAAI;CACnF;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;CAAI;CACvE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;CAAI;CACvE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;CAAI;CACvE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;CAAI;CACvE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;CAAI;CACvE;EAAE,OAAO;EAAG,MAAM;EAAgB,MAAM,GAAG,WAAW,aAAa;CAAI;AACzE;AAEA,MAAM,qBAAqB,SAAyB;CAClD,MAAM,QAAQ,QAAQ,MAAM,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE;CACpD,UAAU,UAAU,KAAA,GAAW,kBAAkB,MAAM;CACvD,OAAO;AACT;AAEA,MAAM,uBACJ,OACA,iBACS;;CAET,IAAI,MAAM,mBAAmB,cAC3B,MAAM,IAAI,MAAM,8BAA8B,aAAa,UAAU,MAAM,gBAAgB;AAE/F;;AAGA,MAAM,wBACJ,OACA,mBACS;CACT,MAAM,eAAe,MAAM,MAAM,cAAc,CAAC,CAC7C,KAAK,gBAAgB,IAAI,CAAC,CAC1B,KAAK,iBAAkB,iBAAiB,OAAO,6CAA8C,CAAC,CAC9F,WAAW;CACd,IAAI,iBAAiB,MACnB,MAAM,IAAI,MAAM,YAAY;AAEhC;AAEA,MAAa,QAAQ;;;;CAInB,uBAAuB,OAAO,EAAE,OAAO,UAAU,WAAW;EAC1D,MAAM,WAA4B,CAAC;EACnC,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,MAAM,mBAAmB,aAAa,OAAO,SAAS,gBACxD;;GAGF,IACE,MAAM,eAAe;;KAElB,MAAM,EAAE,eAAe,OAAO;GACjC,MAAM,KAAA,GACN;IACA,MAAM,UAAU,OACb,gBAAgB,OAAO,KAAK,CAAC,CAC7B,YAAY;KAAE,MAAM,OAAO;KAAM,YAAY,OAAO;IAAK,CAAC,CAAC,CAC3D,WAAW,OAAO,KAAK,WAAW,OAAO,MAAM,CAAC;IACnD,SAAS,KAAK,OAAO;GACvB;EACF;EACA,MAAM,QAAQ,IAAI,QAAQ;EAC1B,OAAO,OAAO,OAAO,WAAW,mBAAmB,OAAO,EAAE,cAAc,MAAM,GAAG,CAAC;CACtF;;;;CAKA,mCAAmC,OAAO,EAAE,OAAO,UAAU,WAAW;EACtE,MAAM,EAAE,IAAI,iBAAiB;EAC7B,QAAQ,MAAM,OAAO,OAAO,WAAW,6BAA6B,OAAO,EAAE,aAAa,CAAC;EAC3F,MAAM,cAAc,MAAM;EAC1B,MAAM,YAAY,MAAM,eACrB,QAAQ,YAAY;GACnB,IAAI,QAAQ,SAAS,sBAAsB,OAAO;GAKlD,OAAO,CAAC,CAJY,CAAC,MAAM,aAAa,UAAU;;KAE/C,MAAM,EAAE,WAAW,QAAQ;GAC9B;EAEF,CAAC,CAAC,CACD,KAAK,MAAM;GAEV,OADc,kBAAkB,EAAE,UACvB;EACb,CAAC;EACH,MAAM,QAAQ,IACZ,UAAU,KAAK,UACb,OACG,gBAAgB,KAAK,CAAC,CACtB,2BAA2B,WAAW,CAAC,CACvC,WAAW,OAAO,KAAK,0BAA0B,OAAO,CAAC,CAC9D,CACF;EACA,OAAO,OAAO,OAAO,WAAW,kBAAkB,OAAO,EAAE,aAAa,CAAC;CAC3E;;;;CAKA,yCAAyC,OAAO,EAAE,QAAQ,YACxD,OAAO,OAAO,WAAW,8BAA8B,OAAO,EAAE,cAAc,MAAM,GAAG,CAAC;;;;CAK1F,oCAAoC,OAAO,EAAE,OAAO,UAAU,WAAW;EACvE,MAAM,EAAE,IAAI,iBAAiB;EAC7B,MAAM,aAAa,MAAM,eAAe,QAAQ,YAAY;GAC1D,IAAI,QAAQ,SAAS,gBAAgB,OAAO;GAK5C,OAAO,CAAC,CAJe,CAAC,MAAM,aAAa;;KAExC,MAAM,EAAE,WAAW,QAAQ;GAC9B;EAEF,CAAC;EACD,MAAM,QAAQ,IACZ,WAAW,IAAI,OAAO,EAAE,YAAY,WAAW;GAC7C,MAAM,QAAQ,kBAAkB,IAAI;GACpC,MAAM,OAAO,gBAAgB,KAAK,CAAC,CAAC,eAAe;IAAE,MAAM;IAAS;GAAK,CAAC;GAC1E,OAAO,KAAK,cAAc,MAAM;EAClC,CAAC,CACH;EACA,OAAO,OAAO,OAAO,WAAW,uBAAuB,OAAO,EAAE,aAAa,CAAC;CAChF;;;;CAKA,yCAAyC,OAAO,EAAE,QAAQ,YAAY;EACpE,oBAAoB,OAAO,QAAQ;EACnC,OAAO,OAAO,OAAO,WAAW,8BAA8B,OAAO,EACnE,cAAc,MAAM,GACtB,CAAC;CACH;;;;CAKA,oCAAoC,OAAO,EAAE,OAAO,UAAU,WAAW;EACvE,oBAAoB,OAAO,QAAQ;EACnC,MAAM,EAAE,IAAI,iBAAiB;EAC7B,MAAM,aAAa,MAAM,eAAe,QAAQ,YAAY;GAC1D,IAAI,QAAQ,SAAS,gBAAgB,OAAO;GAI5C,OAAO,CAAC,CAHe,CAAC,MAAM,aAAa;;KACN,MAAM,EAAE,WAAW,QAAQ;GAChE;EAEF,CAAC;EACD,MAAM,QAAQ,IACZ,WAAW,IAAI,OAAO,EAAE,YAAY,WAAW;GAC7C,MAAM,QAAQ,kBAAkB,IAAI;GACpC,MAAM,OAAO,gBAAgB,KAAK,CAAC,CAAC,eAAe;IAAE,MAAM;IAAgB;GAAK,CAAC;GACjF,OAAO,KAAK,cAAc,MAAM;EAClC,CAAC,CACH;EACA,OAAO,OAAO,OAAO,WAAW,+BAA+B,OAAO,EAAE,aAAa,CAAC;CACxF;;;;CAKA,iCAAiC,OAAO,EAAE,OAAO,UAAU,WAAW;EACpE,MAAM,EAAE,IAAI,iBAAiB;EAC7B,QAAQ,MAAM,OAAO,OAAO,WAAW,0BAA0B,OAAO,EAAE,aAAa,CAAC;EACxF,MAAM,YAAY,MAAM,aAAa,QAAQ,UAAU,CAAC,MAAM,QAAQ,SAAS;EAC/E,MAAM,QAAQ,IACZ,UAAU,IAAI,OAAO,UAAU;GAC7B,MAAM,QAAQ,kBAAkB,MAAM,IAAI;GAC1C,MAAM,YAAY,MAAM,QAAQ;GAChC,MAAM,OAAO,gBAAgB,KAAK,CAAC,CAAC,kBAAkB,SAAU;GAChE,OAAO,KAAK,iBAAiB,MAAM,MAAM;EAC3C,CAAC,CACH;EACA,OAAO,OAAO,OAAO,WAAW,2BAA2B,OAAO,EAAE,aAAa,CAAC;CACpF;CAEA,uCAAuC,OACrC,EAAE,OAAO,QAAQ,gBAAgB,cACjC,WACG;EACH,oBAAoB,OAAO,SAAS;EACpC,MAAM,EAAE,IAAI,iBAAiB;EAC7B,IAAI,gBAAgB;GAClB,MAAM,cAAc,OAAO,aAAa,EAAE,eAAe,CAAC;GAC1D,MAAM,OACJ,cAAc,OAAO,KAAK,MAAM,cAAc,OAAO,UAAU,IAAI,CAAC,CAAC,CAAC,SAAS,QAAQ;GACzF,MAAM,YAAY,MAAM,yBAAyB,OAAO;IACtD,eAAe,MAAM;IACrB;GACF,CAAC;GACD,OAAO,KAAK,+BAA+B;EAC7C;EACA,QAAQ,MAAM,OAAO,OAAO,WAAW,iCAAiC,OAAO,EAC7E,aACF,CAAC;EACD,MAAM,YAAY,MAAM,aAAa,QAClC,UAAU,CAAC,MAAM,yBAAyB,SAC7C;EACA,MAAM,QAAQ,IACZ,UAAU,IAAI,OAAO,UAAU;GAC7B,MAAM,QAAQ,kBAAkB,MAAM,IAAI;GAC1C,MAAM,YAAY,MAAM,yBAAyB;GACjD,MAAM,OAAO,gBAAgB,KAAK,CAAC,CAAC,sBAAsB,SAAU;GACpE,OAAO,KAAK,iBAAiB,MAAM,MAAM;EAC3C,CAAC,CACH;EACA,OAAO,OAAO,OAAO,WAAW,kCAAkC,OAAO,EAAE,aAAa,CAAC;CAC3F;;;;CAKA,2BAA2B,OAAO,EAAE,OAAO,UAAU,WAAW;EAC9D,oBAAoB,OAAO,QAAQ;EACnC,MAAM,EAAE,IAAI,iBAAiB;EAC7B,QAAQ,MAAM,OAAO,OAAO,WAAW,sBAAsB,OAAO,EAAE,aAAa,CAAC;EACpF,MAAM,YAAY,MAAM,aAAa,QAAQ,OAAO,CAAC,GAAG,QAAQ,YAAY;EAC5E,MAAM,QAAQ,IACZ,UAAU,IAAI,OAAO,OAAO;GAC1B,MAAM,QAAQ,kBAAkB,GAAG,IAAI;GACvC,MAAM,YAAY,GAAG,QAAQ;GAC7B,MAAM,OAAO,gBAAgB,KAAK,CAAC,CAAC,oBAAoB,SAAU;GAClE,OAAO,KAAK,0BAA0B,GAAG,MAAM;EACjD,CAAC,CACH;EACA,OAAO,OAAO,OAAO,WAAW,uBAAuB,OAAO,EAAE,aAAa,CAAC;CAChF;;;;CAKA,kCAAkC,OAAO,EAAE,OAAO,aAChD,OAAO,OAAO,WAAW,oBAAoB,OAAO,EAAE,cAAc,MAAM,GAAG,CAAC;AAClF;AAEA,eAAsB,QACpB,MAMA,QACe;CACf,MAAM,EAAE,QAAQ,gBAAgB,YAAY,cAAc;CAE1D,MAAM,EAAE,mBAAmB;CAC3B,OAAO,KAAK,sBAAsB,gBAAgB;CAClD,IAAI,QAAQ,MAAM,OAAO,OAAO,WAAW,cAAc,MAAM,EAC7D,cAAc,eAChB,CAAC;CAED,qBAAqB,OAAO,cAAc;CAE1C,OAAO,MAAM,SAAS,aAAa;EACjC,IAAI,aAAa,MAAM,SAAS,WAAW;GACzC,OAAO,KAAK,qCAAqC;GACjD;EACF;EACA,MAAM,OAAO,MAAM,MAAM;EACzB,OAAO,KAAK,KAAK,IAAI;EACrB,QAAQ,MAAM,KAAK;GAAE;GAAQ;GAAO;GAAgB;EAAW,GAAG,MAAM;CAC1E;AACF"}
|
|
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 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 debugAuthToken: string | undefined,\n): void => {\n const errorMessage = match(state.hsmHostingMode)\n .with(\"HOSTED\", () => null)\n .with(\"ON_PREM\", () => (debugAuthToken ? null : \"On-premises HSM requires a debug auth token\"))\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 if (state.skipWrappingKey && device.role === \"WRAPPING_KEY_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, debugAuthToken, signerSeed },\n logger,\n ) => {\n checkHsmHostingMode(state, \"ON_PREM\");\n const { id: onboardingId } = state;\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 state = await engine.client.onboarding.startExternalSignersRegistration.mutate({\n onboardingId,\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 debugAuthToken?: string;\n signerSeed?: string;\n untilStep?: OnboardingStep;\n },\n logger: Logger,\n): Promise<void> {\n const { engine, 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, 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, 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.28.
|
|
3
|
+
"version": "0.28.2",
|
|
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.4.3",
|
|
67
|
-
"@ledgerhq/revault-api": "1.
|
|
67
|
+
"@ledgerhq/revault-api": "1.75.0"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@eslint/js": "^9.39.4",
|