@tearleads/client-sdk 0.1.78 → 0.1.80
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/client/deviceFirst/index.d.ts +1 -1
- package/client/deviceFirst/index.js +1 -1
- package/client/deviceFirst/index.js.map +1 -1
- package/client/runtime/principalMutationApi.js +1 -1
- package/client/runtime/principalMutationApi.js.map +1 -1
- package/client/runtime/principalMutationDispatch.js +1 -1
- package/client/runtime/principalMutationDispatch.js.map +1 -1
- package/client/runtime/rootContainerAdoption.js.map +1 -1
- package/client/runtime/workflowRuntime.d.ts +1 -1
- package/client/runtime/workflowRuntime.js.map +1 -1
- package/client/session/sessionPurgeRecovery.js +1 -1
- package/client/session/sessionPurgeRecovery.js.map +1 -1
- package/data/blobs/attachments/projection.js +2 -3
- package/data/blobs/attachments/projection.js.map +1 -1
- package/data/documents/documentConstants.d.ts +1 -0
- package/data/documents/documentConstants.js +1 -0
- package/data/documents/documentConstants.js.map +1 -1
- package/data/documents/shared/containerKek/containerKekEntryVerification.d.ts +3 -0
- package/data/documents/shared/containerKek/index.d.ts +5 -0
- package/data/documents/shared/containerKek/index.js +9 -0
- package/data/documents/shared/containerKek/index.js.map +1 -0
- package/data/documents/shared/projection/index.d.ts +1 -1
- package/data/documents/shared/projection/index.js +1 -1
- package/data/documents/shared/projection/index.js.map +1 -1
- package/data/{sync → documents/shared/sync}/documentSyncOutgoingBatch.d.ts +1 -1
- package/data/{sync → documents/shared/sync}/documentSyncOutgoingBatch.js +1 -1
- package/data/documents/shared/sync/syncResponseAuthorization.js +1 -1
- package/data/documents/shared/sync/syncResponseAuthorization.js.map +1 -1
- package/data/keyingProjectionVerification/container/containerCreateManifest.d.ts +12 -0
- package/data/keyingProjectionVerification/container/containerDestinationVerification.d.ts +16 -0
- package/data/keyingProjectionVerification/index.d.ts +4 -0
- package/data/keyingProjectionVerification/index.js +5 -1
- package/data/keyingProjectionVerification/index.js.map +1 -1
- package/data/keyingProjectionVerification/principalPolicy/mergeProjectionPolicyEvidence.d.ts +3 -0
- package/data/keyingProjectionVerification/principalPolicy/principalPolicyVerification.d.ts +24 -0
- package/data/persistence/container-contents/documentPlacement.js +1 -1
- package/data/persistence/container-contents/documentPlacement.js.map +1 -1
- package/data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js +1 -1
- package/data/persistence/documents/containerDocumentTombstoneHoldsPersistence.js.map +1 -1
- package/data/persistence/documents/documentsPersistence.d.ts +1 -1
- package/data/persistence/documents/documentsPersistence.js +2 -3
- package/data/persistence/documents/documentsPersistence.js.map +1 -1
- package/data/persistence/documents/internal/containerDocumentTombstones.js +1 -1
- package/data/persistence/documents/internal/containerDocumentTombstones.js.map +1 -1
- package/data/persistence/documents/internal/createDocumentWithHistoryCheckpoint.js +1 -1
- package/data/persistence/documents/internal/createDocumentWithHistoryCheckpoint.js.map +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentProjectionRows.js +1 -2
- package/data/persistence/documents/internal/documentProjectionRows.js.map +1 -1
- package/data/persistence/documents/internal/documentPullContinuationPersistence.js +1 -1
- package/data/persistence/documents/internal/documentPullContinuationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentRows.js +1 -2
- package/data/persistence/documents/internal/documentRows.js.map +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
- package/data/persistence/documents/internal/pendingCreateAdoption.js +1 -1
- package/data/persistence/documents/internal/pendingCreateAdoption.js.map +1 -1
- package/data/persistence/documents/internal/rowQueryPersistence.js +1 -1
- package/data/persistence/documents/internal/rowQueryPersistence.js.map +1 -1
- package/package.json +1 -1
- package/stores/local-projection/localProjectionStore.d.ts +1 -1
- package/stores/local-projection/localProjectionStore.js +1 -1
- package/stores/local-projection/localProjectionStore.js.map +1 -1
- package/stores/local-projection/registry.d.ts +1 -1
- package/stores/local-projection/registry.js.map +1 -1
- package/stores/local-projection/types.d.ts +1 -1
- package/stores/local-projection/types.js.map +1 -1
- package/workflows/blobs/hydration/decrypt.js +1 -2
- package/workflows/blobs/hydration/decrypt.js.map +1 -1
- package/workflows/blobs/hydration/hydrate.d.ts +1 -1
- package/workflows/blobs/hydration/hydrate.js.map +1 -1
- package/workflows/container-contents/container-state/create/createAdoption.js +1 -2
- package/workflows/container-contents/container-state/create/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/purge/purgeTreeScope.js +1 -1
- package/workflows/container-contents/container-state/purge/purgeTreeScope.js.map +1 -1
- package/workflows/container-contents/info/documentInfo.js +1 -1
- package/workflows/container-contents/info/documentInfo.js.map +1 -1
- package/workflows/container-contents/metadata/index.js +1 -2
- package/workflows/container-contents/metadata/index.js.map +1 -1
- package/workflows/container-contents/metadata/metadataMutationPreparation.js +1 -1
- package/workflows/container-contents/metadata/metadataMutationPreparation.js.map +1 -1
- package/workflows/container-contents/metadata/metadataPullContinuationInvalidation.js +1 -1
- package/workflows/container-contents/metadata/metadataPullContinuationInvalidation.js.map +1 -1
- package/workflows/container-contents/metadata/metadataSyncErrors.js +1 -1
- package/workflows/container-contents/metadata/metadataSyncErrors.js.map +1 -1
- package/workflows/container-contents/metadata/metadataSyncSettlement.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataSyncSettlement.js.map +1 -1
- package/workflows/container-contents/metadata/metadataTypes.d.ts +1 -1
- package/workflows/container-contents/metadata/metadataTypes.js.map +1 -1
- package/workflows/container-contents/pendingWrites/index.js +1 -1
- package/workflows/container-contents/pendingWrites/index.js.map +1 -1
- package/workflows/container-contents/remoteHydration/destination/verifiedDestination.js +1 -3
- package/workflows/container-contents/remoteHydration/destination/verifiedDestination.js.map +1 -1
- package/workflows/containers/child/create/index.js +1 -1
- package/workflows/containers/child/create/index.js.map +1 -1
- package/workflows/containers/child/move/moveRotation.js +1 -1
- package/workflows/containers/child/move/moveRotation.js.map +1 -1
- package/workflows/containers/child/move/moveWraps.js +1 -1
- package/workflows/containers/child/move/moveWraps.js.map +1 -1
- package/workflows/containers/child/rekey/rekeyProjection.js +1 -1
- package/workflows/containers/child/rekey/rekeyProjection.js.map +1 -1
- package/workflows/containers/child/rotation/rotationContext.js +1 -2
- package/workflows/containers/child/rotation/rotationContext.js.map +1 -1
- package/workflows/containers/child/share/shareAncestorRepair.js +1 -2
- package/workflows/containers/child/share/shareAncestorRepair.js.map +1 -1
- package/workflows/containers/index.d.ts +2 -3
- package/workflows/containers/index.js +1 -2
- package/workflows/containers/index.js.map +1 -1
- package/workflows/containers/writeRefusal.js +1 -1
- package/workflows/containers/writeRefusal.js.map +1 -1
- package/workflows/documents/index.d.ts +1 -1
- package/workflows/documents/index.js +1 -1
- package/workflows/documents/index.js.map +1 -1
- package/workflows/documents/linkSet/linkSetProjectionSeed.js +1 -1
- package/workflows/documents/linkSet/linkSetProjectionSeed.js.map +1 -1
- package/workflows/documents/sync/readOnlySync.js +1 -1
- package/workflows/documents/sync/readOnlySync.js.map +1 -1
- package/workflows/documents/sync/syncAttemptPlanning.js +1 -1
- package/workflows/documents/sync/syncAttemptPlanning.js.map +1 -1
- package/workflows/documents/syncPlan/syncPlanMaterial.js +1 -1
- package/workflows/documents/syncPlan/syncPlanMaterial.js.map +1 -1
- package/workflows/documents/syncPlan/syncPlanRequestBounds.js +1 -1
- package/workflows/documents/syncPlan/syncPlanRequestBounds.js.map +1 -1
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js +1 -1
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js.map +1 -1
- package/workflows/organizations/groupMetadata/groupMetadataAccess.js +1 -1
- package/workflows/organizations/groupMetadata/groupMetadataAccess.js.map +1 -1
- package/workflows/organizations/provisioning/createOrganization.d.ts +1 -1
- package/workflows/organizations/provisioning/createOrganization.js +1 -1
- package/workflows/organizations/provisioning/createOrganization.js.map +1 -1
- package/workflows/organizations/provisioning/organizationProvisioningAttempt.d.ts +1 -1
- package/workflows/organizations/provisioning/organizationProvisioningAttempt.js.map +1 -1
- package/workflows/organizations/readModel/listLocalOrganizations.js +1 -1
- package/workflows/organizations/readModel/listLocalOrganizations.js.map +1 -1
- package/workflows/registration/index.d.ts +2 -1
- package/workflows/registration/index.js +2 -1
- package/workflows/registration/index.js.map +1 -1
- package/workflows/registration/organizationProvisioning.d.ts +39 -0
- package/workflows/registration/organizationProvisioning.js +211 -0
- package/workflows/registration/organizationProvisioning.js.map +1 -0
- package/workflows/registration/organizationProvisioningArtifacts.d.ts +2 -3
- package/workflows/registration/organizationProvisioningArtifacts.js.map +1 -1
- package/workflows/registration/provisioningBootstrapBuilders.d.ts +3 -3
- package/workflows/registration/provisioningBootstrapBuilders.js +3 -4
- package/workflows/registration/provisioningBootstrapBuilders.js.map +1 -1
- package/workflows/registration/registerIdentity.d.ts +2 -39
- package/workflows/registration/registerIdentity.js +2 -207
- package/workflows/registration/registerIdentity.js.map +1 -1
- package/workflows/sync/remoteResetPlans.js +2 -2
- package/workflows/sync/remoteResetPlans.js.map +1 -1
- package/data/persistence/documents/internal/constants.d.ts +0 -1
- package/data/persistence/documents/internal/constants.js +0 -2
- package/data/persistence/documents/internal/constants.js.map +0 -1
- /package/data/{sync → documents/shared/sync}/documentSyncOutgoingBatch.js.map +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createOrganization.js","sourceRoot":"","sources":["createOrganization.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,wCAAwC,GACzC,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EACL,sCAAsC,EAItC,oCAAoC,GACrC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,0CAA0C,EAC1C,kDAAkD,GACnD,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,kCAAkC,EAAE,MAAM,uCAAuC,CAAC;AAE3F,OAAO,EAAE,kDAAkD,EAAE,CAAC;AAoD9D,SAAS,4BAA4B,CAAC,KAIrC;IACC,IACE,KAAK,CAAC,QAAQ,CAAC,cAAc,KAAK,KAAK,CAAC,OAAO,CAAC,cAAc;QAC9D,KAAK,CAAC,QAAQ,CAAC,eAAe,KAAK,KAAK,CAAC,OAAO,CAAC,eAAe,EAChE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,CAAC,KAAK,CAAC,QAAQ,CAAC,sBAAsB;QACtC,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,QAAQ,CAAC,MAAM,EAC/C,CAAC;QACD,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,CAClB,qCAAqC,KAAK,CAAC,QAAQ,CAAC,cAAc,GAAG,CACtE,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,KAA8B,EAC9B,eAAuB;IAEvB,MAAM,cAAc,GAA2C;QAC7D,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;QAChD,uBAAuB,EAAE,KAAK,CAAC,uBAAuB;QACtD,2BAA2B,EAAE,KAAK,CAAC,2BAA2B;QAC9D,eAAe;QACf,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;QAClD,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;IACF,MAAM,SAAS,GACb,MAAM,sCAAsC,CAAC,cAAc,CAAC,CAAC;IAE/D,IAAI,KAAK,CAAC,sBAAsB,EAAE,CAAC;QACjC,SAAS,CAAC,wBAAwB;YAChC,MAAM,wCAAwC,CAC5C;gBACE,GAAG,SAAS;gBACZ,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;gBACpD,eAAe;gBACf,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,EACD,KAAK,CAAC,cAAc,CACrB,CAAC;IACN,CAAC;IAED,IACE,KAAK,CAAC,sBAAsB;QAC5B,KAAK,CAAC,iBAAiB;QACvB,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAC1B,CAAC;QACD,KAAK,CAAC,GAAG,EAAE,CACT,0EAA0E,CAC3E,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA8B;IAE9B,KAAK,CAAC,GAAG,EAAE,CAAC,0BAA0B,CAAC,CAAC;IAExC,MAAM,eAAe,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5C,MAAM,kBAAkB,GAAG,MAAM,0BAA0B,CACzD,KAAK,EACL,eAAe,CAChB,CAAC;IAEF,IAAI,CAAC,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,cAAc,GAAG,MAAM,0CAA0C,CAAC;QACtE,SAAS,EAAE,kBAAkB;QAC7B,uBAAuB,EAAE,KAAK,CAAC,iBAAiB;QAChD,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;QAC1D,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,eAAe;QACf,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IACH,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,KAAK,CAAC,GAAG,EAAE,CACT,yEAAyE,CAC1E,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EACJ,SAAS,EACT,OAAO,EACP,eAAe,EAAE,sBAAsB,GACxC,GAAG,cAAc,CAAC;IAEnB,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC1D,KAAK,CAAC,GAAG,EAAE,CACT,qEAAqE,CACtE,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACnE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC1D,KAAK,CAAC,GAAG,EAAE,CACT,sEAAsE,CACvE,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IACE,KAAK,CAAC,sBAAsB;QAC5B,CAAC,CAAC,MAAM,kCAAkC,CAAC;YACzC,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;YACpD,QAAQ;YACR,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,gBAAgB;YACvD,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC;YACtC,YAAY,EAAE,KAAK,CAAC,iBAAiB;SACtC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IAEd,IAAI,4BAA4B,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QACzE,yEAAyE;QACzE,4DAA4D;QAC5D,yEAAyE;QACzE,0EAA0E;QAC1E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,GAAG,EAAE,CAAC,yBAAyB,QAAQ,CAAC,cAAc,GAAG,CAAC,CAAC;IACjE,MAAM,oCAAoC,CAAC;QACzC,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,uBAAuB,EAAE,KAAK,CAAC,iBAAiB;QAChD,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,WAAW,EAAE,sBAAsB;QACnC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;QAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;QAChD,yBAAyB,EAAE,SAAS,CAAC,yBAAyB;QAC9D,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,6BAA6B,EAAE,SAAS,CAAC,6BAA6B;QACtE,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;QAClD,QAAQ;QACR,aAAa,EAAE,SAAS,CAAC,aAAa;QACtC,oBAAoB,EAAE,SAAS,CAAC,oBAAoB;QACpD,2BAA2B,EAAE,SAAS,CAAC,2BAA2B;QAClE,sBAAsB,EAAE,SAAS,CAAC,sBAAsB;QACxD,yBAAyB,EAAE,SAAS,CAAC,yBAAyB;KAC/D,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import {\n type EncapsulationKeyPair,\n type SigningKeyPair,\n signOrganizationReplacementAuthorization,\n} from \"@tearleads/crypto\";\nimport type { CreateOrganizationRequest } from \"@tearleads/validators/request\";\nimport type { CreateOrganizationResponse } from \"@tearleads/validators/response\";\nimport type { DocumentProjectorRegistryInput } from \"../../../data/documents/documentKinds\";\nimport type { ExecSqlClientLike } from \"../../../data/sqlite/sqlSchema\";\nimport { createExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { ProvisionedPrincipalHistoryPrimer } from \"../../registration/provisionedPrincipalHistory\";\nimport {\n buildOrganizationProvisioningArtifacts,\n type OrganizationProvisioningArtifacts,\n type OrganizationProvisioningArtifactsInput,\n type ProvisionedSystemContainerSpec,\n persistOrganizationProvisioningState,\n} from \"../../registration/registerIdentity\";\nimport {\n makeOrganizationProvisioningAttemptDurable,\n removeNativeSubscriptionRestoreProvisioningAttempt,\n} from \"./organizationProvisioningAttempt\";\nimport { pinOrganizationReplacementResponse } from \"./organizationReplacementVerification\";\n\nexport { removeNativeSubscriptionRestoreProvisioningAttempt };\n\nexport interface CreateOrganizationApi {\n createOrganization(\n request: CreateOrganizationRequest,\n ): Promise<CreateOrganizationResponse | null>;\n}\n\nexport interface CreateOrganizationInput {\n apiClient: CreateOrganizationApi;\n dbClient: ExecSqlClientLike;\n documentProjectors?: DocumentProjectorRegistryInput | undefined;\n encapsulationKeyPair: EncapsulationKeyPair;\n /**\n * Returns false once the identity that supplied the key pairs is no longer\n * active. Checked before the remote create (so a stale request is never\n * submitted) and again before local persistence: an identity switch closes\n * or renews the captured database client, so persisting would write another\n * identity's bootstrap — or throw — after the org already exists remotely.\n * The caller discards the result.\n */\n isIdentityCurrent?: (() => boolean) | undefined;\n /** @internal Forwarded to the bootstrap persist; test-only seam. */\n onPersistQueued?: (() => void) | undefined;\n log?: ((message: string) => void) | undefined;\n logError?: ((message: string | Error, cause?: unknown) => void) | undefined;\n /** Overrides the seeded organization profile name; see registration. */\n organizationProfileName?: string | undefined;\n /** Seeds verified recovery progress for the founding policy heads. */\n primePrincipalHistory?: ProvisionedPrincipalHistoryPrimer | undefined;\n /**\n * App-owned system containers to provision atomically with the new\n * organization (e.g. a trash bin). See registration.\n */\n provisionedSystemContainers?:\n | ReadonlyArray<ProvisionedSystemContainerSpec>\n | undefined;\n /** Purged organization whose personal-org generation this replaces. */\n replacesOrganizationId?: string | undefined;\n /** Marks and durably replays a fresh native-subscription restore target. */\n nativeSubscriptionRestore?: boolean | undefined;\n /** Overrides the seeded self roster-profile nickname; see registration. */\n rosterProfileNickname?: string | undefined;\n signingKeyPair: SigningKeyPair;\n /**\n * The already-registered user creating the organization; they become its\n * founding admin. The server independently requires this to match the\n * authenticated session.\n */\n userId: string;\n}\n\nfunction isAdoptedReplacementResponse(input: {\n creation: CreateOrganizationInput;\n request: CreateOrganizationRequest;\n response: CreateOrganizationResponse;\n}): boolean {\n if (\n input.response.organizationId === input.request.organizationId &&\n input.response.rootContainerId === input.request.rootContainerId\n ) {\n return false;\n }\n if (\n !input.creation.replacesOrganizationId ||\n input.response.userId !== input.creation.userId\n ) {\n throw new Error(\n \"Organization provisioning returned an unexpected organization\",\n );\n }\n input.creation.log?.(\n `Organization replacement adopted (${input.response.organizationId})`,\n );\n return true;\n}\n\nasync function buildOrganizationCandidate(\n input: CreateOrganizationInput,\n rootContainerId: string,\n): Promise<OrganizationProvisioningArtifacts | null> {\n const artifactsInput: OrganizationProvisioningArtifactsInput = {\n encapsulationKeyPair: input.encapsulationKeyPair,\n organizationProfileName: input.organizationProfileName,\n provisionedSystemContainers: input.provisionedSystemContainers,\n rootContainerId,\n rosterProfileNickname: input.rosterProfileNickname,\n signingKeyPair: input.signingKeyPair,\n userId: input.userId,\n };\n const artifacts: OrganizationProvisioningArtifacts =\n await buildOrganizationProvisioningArtifacts(artifactsInput);\n\n if (input.replacesOrganizationId) {\n artifacts.replacementAuthorization =\n await signOrganizationReplacementAuthorization(\n {\n ...artifacts,\n replacesOrganizationId: input.replacesOrganizationId,\n rootContainerId,\n userId: input.userId,\n },\n input.signingKeyPair,\n );\n }\n\n if (\n input.replacesOrganizationId &&\n input.isIdentityCurrent &&\n !input.isIdentityCurrent()\n ) {\n input.log?.(\n \"Organization creation aborted: identity changed while building artifacts\",\n );\n return null;\n }\n\n return artifacts;\n}\n\n/**\n * Provisions an additional organization for an already-registered user, reusing\n * the exact artifact-build and local-persistence path as registration\n * ({@link buildOrganizationProvisioningArtifacts} /\n * {@link persistOrganizationProvisioningState}). Unlike registration it mints a\n * fresh root container id, signs with the caller's existing identity, and needs\n * no auth challenge — the user is already authenticated.\n */\nexport async function createOrganization(\n input: CreateOrganizationInput,\n): Promise<CreateOrganizationResponse | null> {\n input.log?.(\"Creating organization...\");\n\n const rootContainerId = crypto.randomUUID();\n const candidateArtifacts = await buildOrganizationCandidate(\n input,\n rootContainerId,\n );\n\n if (!candidateArtifacts) return null;\n\n const durableAttempt = await makeOrganizationProvisioningAttemptDurable({\n artifacts: candidateArtifacts,\n canStartDurableMutation: input.isIdentityCurrent,\n dbClient: input.dbClient,\n nativeSubscriptionRestore: input.nativeSubscriptionRestore,\n replacesOrganizationId: input.replacesOrganizationId,\n rootContainerId,\n userId: input.userId,\n });\n if (!durableAttempt) {\n input.log?.(\n \"Organization creation aborted: identity changed before saving artifacts\",\n );\n return null;\n }\n const {\n artifacts,\n request,\n rootContainerId: durableRootContainerId,\n } = durableAttempt;\n\n if (input.isIdentityCurrent && !input.isIdentityCurrent()) {\n input.log?.(\n \"Organization creation aborted: identity changed before provisioning\",\n );\n return null;\n }\n\n const response = await input.apiClient.createOrganization(request);\n if (!response) {\n return null;\n }\n\n if (input.isIdentityCurrent && !input.isIdentityCurrent()) {\n input.log?.(\n \"Organization creation discarded: identity changed while provisioning\",\n );\n return null;\n }\n\n if (\n input.replacesOrganizationId &&\n !(await pinOrganizationReplacementResponse({\n replacesOrganizationId: input.replacesOrganizationId,\n response,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n userId: input.userId,\n execSql: createExecSql(input.dbClient),\n stillCurrent: input.isIdentityCurrent,\n }))\n )\n return null;\n\n if (isAdoptedReplacementResponse({ creation: input, request, response })) {\n // Another device authorized this winning genesis with the same identity.\n // Its encrypted bootstrap will hydrate normally; persisting\n // this device's losing candidate would instead create an unrelated local\n // root. The session reset rebinds retained local data to the winning ids.\n return response;\n }\n\n input.log?.(`Organization created (${response.organizationId})`);\n await persistOrganizationProvisioningState({\n bootstrap: artifacts.bootstrap,\n canStartDurableMutation: input.isIdentityCurrent,\n onPersistQueued: input.onPersistQueued,\n containerId: durableRootContainerId,\n dbClient: input.dbClient,\n documentProjectors: input.documentProjectors,\n initialAdminGroup: artifacts.initialAdminGroup,\n initialMemberGroup: artifacts.initialMemberGroup,\n initialOrganizationPolicy: artifacts.initialOrganizationPolicy,\n log: input.log,\n logError: input.logError,\n organizationMetadataBootstrap: artifacts.organizationMetadataBootstrap,\n primePrincipalHistory: input.primePrincipalHistory,\n response,\n rootContainer: artifacts.rootContainer,\n rootMetadataDocument: artifacts.rootMetadataDocument,\n rootMetadataDocumentRequest: artifacts.rootMetadataDocumentRequest,\n rosterProfileBootstrap: artifacts.rosterProfileBootstrap,\n systemContainerBootstraps: artifacts.systemContainerBootstraps,\n });\n\n return response;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"createOrganization.js","sourceRoot":"","sources":["createOrganization.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type EncapsulationKeyPair,\n type SigningKeyPair,\n signOrganizationReplacementAuthorization,\n} from \"@tearleads/crypto\";\nimport type { CreateOrganizationRequest } from \"@tearleads/validators/request\";\nimport type { CreateOrganizationResponse } from \"@tearleads/validators/response\";\nimport type { DocumentProjectorRegistryInput } from \"../../../data/documents/documentKinds\";\nimport type { ExecSqlClientLike } from \"../../../data/sqlite/sqlSchema\";\nimport { createExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n buildOrganizationProvisioningArtifacts,\n type OrganizationProvisioningArtifacts,\n type OrganizationProvisioningArtifactsInput,\n type ProvisionedSystemContainerSpec,\n persistOrganizationProvisioningState,\n} from \"../../registration/organizationProvisioning\";\nimport type { ProvisionedPrincipalHistoryPrimer } from \"../../registration/provisionedPrincipalHistory\";\nimport {\n makeOrganizationProvisioningAttemptDurable,\n removeNativeSubscriptionRestoreProvisioningAttempt,\n} from \"./organizationProvisioningAttempt\";\nimport { pinOrganizationReplacementResponse } from \"./organizationReplacementVerification\";\n\nexport { removeNativeSubscriptionRestoreProvisioningAttempt };\n\nexport interface CreateOrganizationApi {\n createOrganization(\n request: CreateOrganizationRequest,\n ): Promise<CreateOrganizationResponse | null>;\n}\n\nexport interface CreateOrganizationInput {\n apiClient: CreateOrganizationApi;\n dbClient: ExecSqlClientLike;\n documentProjectors?: DocumentProjectorRegistryInput | undefined;\n encapsulationKeyPair: EncapsulationKeyPair;\n /**\n * Returns false once the identity that supplied the key pairs is no longer\n * active. Checked before the remote create (so a stale request is never\n * submitted) and again before local persistence: an identity switch closes\n * or renews the captured database client, so persisting would write another\n * identity's bootstrap — or throw — after the org already exists remotely.\n * The caller discards the result.\n */\n isIdentityCurrent?: (() => boolean) | undefined;\n /** @internal Forwarded to the bootstrap persist; test-only seam. */\n onPersistQueued?: (() => void) | undefined;\n log?: ((message: string) => void) | undefined;\n logError?: ((message: string | Error, cause?: unknown) => void) | undefined;\n /** Overrides the seeded organization profile name; see registration. */\n organizationProfileName?: string | undefined;\n /** Seeds verified recovery progress for the founding policy heads. */\n primePrincipalHistory?: ProvisionedPrincipalHistoryPrimer | undefined;\n /**\n * App-owned system containers to provision atomically with the new\n * organization (e.g. a trash bin). See registration.\n */\n provisionedSystemContainers?:\n | ReadonlyArray<ProvisionedSystemContainerSpec>\n | undefined;\n /** Purged organization whose personal-org generation this replaces. */\n replacesOrganizationId?: string | undefined;\n /** Marks and durably replays a fresh native-subscription restore target. */\n nativeSubscriptionRestore?: boolean | undefined;\n /** Overrides the seeded self roster-profile nickname; see registration. */\n rosterProfileNickname?: string | undefined;\n signingKeyPair: SigningKeyPair;\n /**\n * The already-registered user creating the organization; they become its\n * founding admin. The server independently requires this to match the\n * authenticated session.\n */\n userId: string;\n}\n\nfunction isAdoptedReplacementResponse(input: {\n creation: CreateOrganizationInput;\n request: CreateOrganizationRequest;\n response: CreateOrganizationResponse;\n}): boolean {\n if (\n input.response.organizationId === input.request.organizationId &&\n input.response.rootContainerId === input.request.rootContainerId\n ) {\n return false;\n }\n if (\n !input.creation.replacesOrganizationId ||\n input.response.userId !== input.creation.userId\n ) {\n throw new Error(\n \"Organization provisioning returned an unexpected organization\",\n );\n }\n input.creation.log?.(\n `Organization replacement adopted (${input.response.organizationId})`,\n );\n return true;\n}\n\nasync function buildOrganizationCandidate(\n input: CreateOrganizationInput,\n rootContainerId: string,\n): Promise<OrganizationProvisioningArtifacts | null> {\n const artifactsInput: OrganizationProvisioningArtifactsInput = {\n encapsulationKeyPair: input.encapsulationKeyPair,\n organizationProfileName: input.organizationProfileName,\n provisionedSystemContainers: input.provisionedSystemContainers,\n rootContainerId,\n rosterProfileNickname: input.rosterProfileNickname,\n signingKeyPair: input.signingKeyPair,\n userId: input.userId,\n };\n const artifacts: OrganizationProvisioningArtifacts =\n await buildOrganizationProvisioningArtifacts(artifactsInput);\n\n if (input.replacesOrganizationId) {\n artifacts.replacementAuthorization =\n await signOrganizationReplacementAuthorization(\n {\n ...artifacts,\n replacesOrganizationId: input.replacesOrganizationId,\n rootContainerId,\n userId: input.userId,\n },\n input.signingKeyPair,\n );\n }\n\n if (\n input.replacesOrganizationId &&\n input.isIdentityCurrent &&\n !input.isIdentityCurrent()\n ) {\n input.log?.(\n \"Organization creation aborted: identity changed while building artifacts\",\n );\n return null;\n }\n\n return artifacts;\n}\n\n/**\n * Provisions an additional organization for an already-registered user, reusing\n * the exact artifact-build and local-persistence path as registration\n * ({@link buildOrganizationProvisioningArtifacts} /\n * {@link persistOrganizationProvisioningState}). Unlike registration it mints a\n * fresh root container id, signs with the caller's existing identity, and needs\n * no auth challenge — the user is already authenticated.\n */\nexport async function createOrganization(\n input: CreateOrganizationInput,\n): Promise<CreateOrganizationResponse | null> {\n input.log?.(\"Creating organization...\");\n\n const rootContainerId = crypto.randomUUID();\n const candidateArtifacts = await buildOrganizationCandidate(\n input,\n rootContainerId,\n );\n\n if (!candidateArtifacts) return null;\n\n const durableAttempt = await makeOrganizationProvisioningAttemptDurable({\n artifacts: candidateArtifacts,\n canStartDurableMutation: input.isIdentityCurrent,\n dbClient: input.dbClient,\n nativeSubscriptionRestore: input.nativeSubscriptionRestore,\n replacesOrganizationId: input.replacesOrganizationId,\n rootContainerId,\n userId: input.userId,\n });\n if (!durableAttempt) {\n input.log?.(\n \"Organization creation aborted: identity changed before saving artifacts\",\n );\n return null;\n }\n const {\n artifacts,\n request,\n rootContainerId: durableRootContainerId,\n } = durableAttempt;\n\n if (input.isIdentityCurrent && !input.isIdentityCurrent()) {\n input.log?.(\n \"Organization creation aborted: identity changed before provisioning\",\n );\n return null;\n }\n\n const response = await input.apiClient.createOrganization(request);\n if (!response) {\n return null;\n }\n\n if (input.isIdentityCurrent && !input.isIdentityCurrent()) {\n input.log?.(\n \"Organization creation discarded: identity changed while provisioning\",\n );\n return null;\n }\n\n if (\n input.replacesOrganizationId &&\n !(await pinOrganizationReplacementResponse({\n replacesOrganizationId: input.replacesOrganizationId,\n response,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n userId: input.userId,\n execSql: createExecSql(input.dbClient),\n stillCurrent: input.isIdentityCurrent,\n }))\n )\n return null;\n\n if (isAdoptedReplacementResponse({ creation: input, request, response })) {\n // Another device authorized this winning genesis with the same identity.\n // Its encrypted bootstrap will hydrate normally; persisting\n // this device's losing candidate would instead create an unrelated local\n // root. The session reset rebinds retained local data to the winning ids.\n return response;\n }\n\n input.log?.(`Organization created (${response.organizationId})`);\n await persistOrganizationProvisioningState({\n bootstrap: artifacts.bootstrap,\n canStartDurableMutation: input.isIdentityCurrent,\n onPersistQueued: input.onPersistQueued,\n containerId: durableRootContainerId,\n dbClient: input.dbClient,\n documentProjectors: input.documentProjectors,\n initialAdminGroup: artifacts.initialAdminGroup,\n initialMemberGroup: artifacts.initialMemberGroup,\n initialOrganizationPolicy: artifacts.initialOrganizationPolicy,\n log: input.log,\n logError: input.logError,\n organizationMetadataBootstrap: artifacts.organizationMetadataBootstrap,\n primePrincipalHistory: input.primePrincipalHistory,\n response,\n rootContainer: artifacts.rootContainer,\n rootMetadataDocument: artifacts.rootMetadataDocument,\n rootMetadataDocumentRequest: artifacts.rootMetadataDocumentRequest,\n rosterProfileBootstrap: artifacts.rosterProfileBootstrap,\n systemContainerBootstraps: artifacts.systemContainerBootstraps,\n });\n\n return response;\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type CreateOrganizationRequest } from "../../../internal/validators/request/index.js";
|
|
2
2
|
import type { ExecSql, ExecSqlClientLike } from "../../../data/sqlite/sqlSchema.js";
|
|
3
|
-
import type { OrganizationProvisioningArtifacts } from "../../registration/
|
|
3
|
+
import type { OrganizationProvisioningArtifacts } from "../../registration/organizationProvisioning.js";
|
|
4
4
|
interface DurableOrganizationProvisioningAttempt {
|
|
5
5
|
readonly artifacts: OrganizationProvisioningArtifacts;
|
|
6
6
|
readonly request: CreateOrganizationRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationProvisioningAttempt.js","sourceRoot":"","sources":["organizationProvisioningAttempt.ts"],"names":[],"mappings":"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","sourcesContent":["import { base64ToBytes, bytesToBase64 } from \"@tearleads/encoding\";\nimport { isPlainObject } from \"@tearleads/validators/isPlainObject\";\nimport {\n type CreateOrganizationRequest,\n isCreateOrganizationRequest,\n} from \"@tearleads/validators/request\";\nimport { isOrganizationReplacementAuthorization } from \"@tearleads/validators/util\";\nimport { sqlOrganizationProvisioningAttemptPersistence } from \"../../../data/persistence/organizations/organizationProvisioningAttemptPersistence\";\nimport type {\n ExecSql,\n ExecSqlClientLike,\n} from \"../../../data/sqlite/sqlSchema\";\nimport { createExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { OrganizationProvisioningArtifacts } from \"../../registration/registerIdentity\";\n\nconst BYTE_MARKER = \"__tearleadsProvisioningBytes\";\n\ninterface DurableOrganizationProvisioningAttempt {\n readonly artifacts: OrganizationProvisioningArtifacts;\n readonly request: CreateOrganizationRequest;\n readonly rootContainerId: string;\n}\n\nfunction buildCreateOrganizationRequest(input: {\n artifacts: OrganizationProvisioningArtifacts;\n finalizeReplacement?: boolean | undefined;\n nativeSubscriptionRestore?: boolean | undefined;\n replacesOrganizationId?: string | undefined;\n rootContainerId: string;\n userId: string;\n}): CreateOrganizationRequest {\n const { artifacts } = input;\n return {\n userId: input.userId,\n ...(artifacts.replacementAuthorization\n ? { replacementAuthorization: artifacts.replacementAuthorization }\n : {}),\n organizationId: artifacts.organizationId,\n rootContainerId: input.rootContainerId,\n initialAdminGroup: artifacts.initialAdminGroup,\n initialMemberGroup: artifacts.initialMemberGroup,\n initialOrganizationPolicy: artifacts.initialOrganizationPolicy,\n initialRootContainer: artifacts.initialRootContainer,\n initialRootMetadataDocument: artifacts.rootMetadataDocumentRequest,\n initialRosterProfileContainer:\n artifacts.rosterProfileBootstrap.containerRequest,\n initialRosterProfileDocument:\n artifacts.rosterProfileBootstrap.profileDocumentRequest,\n initialOrganizationMetadataContainer:\n artifacts.organizationMetadataBootstrap.containerRequest,\n initialOrganizationProfileDocument:\n artifacts.organizationMetadataBootstrap\n .organizationProfileDocumentRequest,\n initialSystemContainers: artifacts.systemContainerBootstraps.map(\n (systemContainer) => systemContainer.containerRequest,\n ),\n ...(input.finalizeReplacement ? { finalizeReplacement: true } : {}),\n ...(input.nativeSubscriptionRestore\n ? { nativeSubscriptionRestore: true as const }\n : {}),\n ...(input.replacesOrganizationId\n ? { replacesOrganizationId: input.replacesOrganizationId }\n : {}),\n };\n}\n\nexport async function loadOrganizationReplacementFinalizationRequest(input: {\n execSql: ExecSql;\n replacedOrganizationId: string;\n userId: string;\n}): Promise<CreateOrganizationRequest> {\n const stored = await sqlOrganizationProvisioningAttemptPersistence.load(\n input.execSql,\n input.replacedOrganizationId,\n );\n if (!stored) {\n throw new Error(\"Organization replacement attempt is unavailable\");\n }\n if (stored.userId !== input.userId) {\n throw new Error(\n \"Stored organization provisioning attempt belongs to another user\",\n );\n }\n const artifacts = deserializeArtifacts(stored.serializedArtifacts);\n const request = buildCreateOrganizationRequest({\n artifacts,\n finalizeReplacement: true,\n replacesOrganizationId: input.replacedOrganizationId,\n rootContainerId: stored.rootContainerId,\n userId: stored.userId,\n });\n if (\n artifacts.organizationId !== stored.organizationId ||\n request.organizationId !== stored.organizationId ||\n request.rootContainerId !== stored.rootContainerId ||\n !isCreateOrganizationRequest(request)\n ) {\n throw new Error(\"Stored organization provisioning attempt is inconsistent\");\n }\n return request;\n}\n\nfunction serializeArtifacts(artifacts: OrganizationProvisioningArtifacts) {\n return JSON.stringify(artifacts, (_key, value: unknown) => {\n if (value instanceof Uint8Array) {\n return { [BYTE_MARKER]: bytesToBase64(value) };\n }\n return value;\n });\n}\n\nfunction hasRecord(value: Record<string, unknown>, key: string): boolean {\n return isPlainObject(Reflect.get(value, key));\n}\n\nfunction hasBytes(value: Record<string, unknown>, key: string): boolean {\n return Reflect.get(value, key) instanceof Uint8Array;\n}\n\nfunction isMaterializedDocument(value: unknown): boolean {\n return (\n isPlainObject(value) &&\n hasBytes(value, \"contentKey\") &&\n hasRecord(value, \"plan\")\n );\n}\n\nfunction isMaterializedContainer(value: unknown): boolean {\n return (\n isPlainObject(value) &&\n hasBytes(value, \"containerKey\") &&\n hasRecord(value, \"plan\")\n );\n}\n\nfunction hasContainerBootstrapCore(value: Record<string, unknown>): boolean {\n return (\n typeof Reflect.get(value, \"containerId\") === \"string\" &&\n isMaterializedDocument(Reflect.get(value, \"containerMetadataDocument\")) &&\n hasBytes(value, \"containerMetadataInitialUpdate\") &&\n isMaterializedContainer(Reflect.get(value, \"containerPlan\")) &&\n hasRecord(value, \"containerRequest\") &&\n Reflect.get(value, \"systemSlot\") !== undefined\n );\n}\n\nfunction isOrganizationProvisioningArtifacts(\n value: unknown,\n): value is OrganizationProvisioningArtifacts {\n if (!isPlainObject(value)) return false;\n const bootstrap = Reflect.get(value, \"bootstrap\");\n const roster = Reflect.get(value, \"rosterProfileBootstrap\");\n const metadata = Reflect.get(value, \"organizationMetadataBootstrap\");\n const systemContainers = Reflect.get(value, \"systemContainerBootstraps\");\n return (\n (Reflect.get(value, \"replacementAuthorization\") === null ||\n isOrganizationReplacementAuthorization(\n Reflect.get(value, \"replacementAuthorization\"),\n )) &&\n typeof Reflect.get(value, \"organizationId\") === \"string\" &&\n isPlainObject(bootstrap) &&\n hasBytes(bootstrap, \"initialUpdate\") &&\n typeof Reflect.get(bootstrap, \"metadataDocumentId\") === \"string\" &&\n hasRecord(value, \"initialAdminGroup\") &&\n hasRecord(value, \"initialMemberGroup\") &&\n hasRecord(value, \"initialOrganizationPolicy\") &&\n hasRecord(value, \"initialRootContainer\") &&\n isMaterializedContainer(Reflect.get(value, \"rootContainer\")) &&\n isMaterializedDocument(Reflect.get(value, \"rootMetadataDocument\")) &&\n hasRecord(value, \"rootMetadataDocumentRequest\") &&\n isPlainObject(roster) &&\n hasContainerBootstrapCore(roster) &&\n isMaterializedDocument(Reflect.get(roster, \"profileDocument\")) &&\n hasBytes(roster, \"profileDocumentInitialUpdate\") &&\n hasRecord(roster, \"profileDocumentRequest\") &&\n isPlainObject(metadata) &&\n hasContainerBootstrapCore(metadata) &&\n isMaterializedDocument(\n Reflect.get(metadata, \"organizationProfileDocument\"),\n ) &&\n hasRecord(metadata, \"organizationProfileDocumentRequest\") &&\n typeof Reflect.get(metadata, \"organizationProfileSnapshot\") === \"string\" &&\n Array.isArray(systemContainers) &&\n systemContainers.every(\n (container) =>\n isPlainObject(container) && hasContainerBootstrapCore(container),\n )\n );\n}\n\nfunction deserializeArtifacts(\n value: string,\n): OrganizationProvisioningArtifacts {\n const parsed: unknown = JSON.parse(value, (_key, candidate: unknown) => {\n if (\n typeof candidate === \"object\" &&\n candidate !== null &&\n Object.keys(candidate).length === 1 &&\n BYTE_MARKER in candidate\n ) {\n const encoded = Reflect.get(candidate, BYTE_MARKER);\n if (typeof encoded === \"string\") {\n return base64ToBytes(encoded);\n }\n }\n return candidate;\n });\n if (!isOrganizationProvisioningArtifacts(parsed)) {\n throw new Error(\"Stored organization provisioning attempt is invalid\");\n }\n return parsed;\n}\n\nexport async function makeOrganizationProvisioningAttemptDurable(input: {\n artifacts: OrganizationProvisioningArtifacts;\n canStartDurableMutation?: (() => boolean) | undefined;\n dbClient: ExecSqlClientLike;\n nativeSubscriptionRestore?: boolean | undefined;\n replacesOrganizationId?: string | undefined;\n rootContainerId: string;\n userId: string;\n}): Promise<DurableOrganizationProvisioningAttempt | null> {\n const attemptKey =\n input.replacesOrganizationId ??\n (input.nativeSubscriptionRestore\n ? `native-subscription-restore:${input.userId}`\n : null);\n if (!attemptKey) {\n return {\n artifacts: input.artifacts,\n request: buildCreateOrganizationRequest(input),\n rootContainerId: input.rootContainerId,\n };\n }\n const stored = await sqlOrganizationProvisioningAttemptPersistence.loadOrSave(\n createExecSql(input.dbClient),\n {\n replacedOrganizationId: attemptKey,\n userId: input.userId,\n organizationId: input.artifacts.organizationId,\n rootContainerId: input.rootContainerId,\n serializedArtifacts: serializeArtifacts(input.artifacts),\n },\n input.canStartDurableMutation,\n );\n if (!stored) return null;\n if (stored.userId !== input.userId) {\n throw new Error(\n \"Stored organization provisioning attempt belongs to another user\",\n );\n }\n const artifacts = deserializeArtifacts(stored.serializedArtifacts);\n const request = buildCreateOrganizationRequest({\n artifacts,\n nativeSubscriptionRestore: input.nativeSubscriptionRestore,\n replacesOrganizationId: input.replacesOrganizationId,\n rootContainerId: stored.rootContainerId,\n userId: stored.userId,\n });\n if (\n artifacts.organizationId !== stored.organizationId ||\n request.organizationId !== stored.organizationId ||\n request.rootContainerId !== stored.rootContainerId ||\n !isCreateOrganizationRequest(request)\n ) {\n throw new Error(\"Stored organization provisioning attempt is inconsistent\");\n }\n return { artifacts, request, rootContainerId: stored.rootContainerId };\n}\n\nexport async function removeNativeSubscriptionRestoreProvisioningAttempt(input: {\n canCommit?: (() => boolean) | undefined;\n dbClient: ExecSqlClientLike;\n organizationId: string;\n userId: string;\n}): Promise<boolean> {\n const attemptKey = `native-subscription-restore:${input.userId}`;\n const execSql = createExecSql(input.dbClient);\n const stored = await sqlOrganizationProvisioningAttemptPersistence.load(\n execSql,\n attemptKey,\n );\n if (!stored) return true;\n if (\n stored.userId !== input.userId ||\n stored.organizationId !== input.organizationId\n ) {\n throw new Error(\n \"Stored native restore organization provisioning attempt is inconsistent\",\n );\n }\n return removeOrganizationProvisioningAttempt({\n canCommit: input.canCommit,\n execSql,\n organizationId: input.organizationId,\n replacedOrganizationId: attemptKey,\n userId: input.userId,\n });\n}\n\nexport async function removeOrganizationProvisioningAttempt(input: {\n canCommit?: (() => boolean) | undefined;\n execSql: ExecSql;\n organizationId?: string | undefined;\n replacedOrganizationId: string;\n userId: string;\n}): Promise<boolean> {\n return sqlOrganizationProvisioningAttemptPersistence.remove(\n input.execSql,\n input,\n input.canCommit,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"organizationProvisioningAttempt.js","sourceRoot":"","sources":["organizationProvisioningAttempt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAEL,2BAA2B,GAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,sCAAsC,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,6CAA6C,EAAE,MAAM,oFAAoF,CAAC;AAKnJ,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAG/D,MAAM,WAAW,GAAG,8BAA8B,CAAC;AAQnD,SAAS,8BAA8B,CAAC,KAOvC;IACC,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5B,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,GAAG,CAAC,SAAS,CAAC,wBAAwB;YACpC,CAAC,CAAC,EAAE,wBAAwB,EAAE,SAAS,CAAC,wBAAwB,EAAE;YAClE,CAAC,CAAC,EAAE,CAAC;QACP,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;QAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;QAChD,yBAAyB,EAAE,SAAS,CAAC,yBAAyB;QAC9D,oBAAoB,EAAE,SAAS,CAAC,oBAAoB;QACpD,2BAA2B,EAAE,SAAS,CAAC,2BAA2B;QAClE,6BAA6B,EAC3B,SAAS,CAAC,sBAAsB,CAAC,gBAAgB;QACnD,4BAA4B,EAC1B,SAAS,CAAC,sBAAsB,CAAC,sBAAsB;QACzD,oCAAoC,EAClC,SAAS,CAAC,6BAA6B,CAAC,gBAAgB;QAC1D,kCAAkC,EAChC,SAAS,CAAC,6BAA6B;aACpC,kCAAkC;QACvC,uBAAuB,EAAE,SAAS,CAAC,yBAAyB,CAAC,GAAG,CAC9D,CAAC,eAAe,EAAE,EAAE,CAAC,eAAe,CAAC,gBAAgB,CACtD;QACD,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,KAAK,CAAC,yBAAyB;YACjC,CAAC,CAAC,EAAE,yBAAyB,EAAE,IAAa,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,sBAAsB;YAC9B,CAAC,CAAC,EAAE,sBAAsB,EAAE,KAAK,CAAC,sBAAsB,EAAE;YAC1D,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8CAA8C,CAAC,KAIpE;IACC,MAAM,MAAM,GAAG,MAAM,6CAA6C,CAAC,IAAI,CACrE,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,sBAAsB,CAC7B,CAAC;IACF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,oBAAoB,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,8BAA8B,CAAC;QAC7C,SAAS;QACT,mBAAmB,EAAE,IAAI;QACzB,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAC;IACH,IACE,SAAS,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAClD,OAAO,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAChD,OAAO,CAAC,eAAe,KAAK,MAAM,CAAC,eAAe;QAClD,CAAC,2BAA2B,CAAC,OAAO,CAAC,EACrC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,kBAAkB,CAAC,SAA4C;IACtE,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,KAAc,EAAE,EAAE;QACxD,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAAC,KAA8B,EAAE,GAAW;IAC5D,OAAO,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,QAAQ,CAAC,KAA8B,EAAE,GAAW;IAC3D,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,YAAY,UAAU,CAAC;AACvD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc;IAC5C,OAAO,CACL,aAAa,CAAC,KAAK,CAAC;QACpB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;QAC7B,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CACzB,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc;IAC7C,OAAO,CACL,aAAa,CAAC,KAAK,CAAC;QACpB,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;QAC/B,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CACzB,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAAC,KAA8B;IAC/D,OAAO,CACL,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,KAAK,QAAQ;QACrD,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;QACvE,QAAQ,CAAC,KAAK,EAAE,gCAAgC,CAAC;QACjD,uBAAuB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAC5D,SAAS,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,SAAS,CAC/C,CAAC;AACJ,CAAC;AAED,SAAS,mCAAmC,CAC1C,KAAc;IAEd,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,+BAA+B,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;IACzE,OAAO,CACL,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,0BAA0B,CAAC,KAAK,IAAI;QACtD,sCAAsC,CACpC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAC/C,CAAC;QACJ,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,KAAK,QAAQ;QACxD,aAAa,CAAC,SAAS,CAAC;QACxB,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;QACpC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,oBAAoB,CAAC,KAAK,QAAQ;QAChE,SAAS,CAAC,KAAK,EAAE,mBAAmB,CAAC;QACrC,SAAS,CAAC,KAAK,EAAE,oBAAoB,CAAC;QACtC,SAAS,CAAC,KAAK,EAAE,2BAA2B,CAAC;QAC7C,SAAS,CAAC,KAAK,EAAE,sBAAsB,CAAC;QACxC,uBAAuB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QAC5D,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;QAClE,SAAS,CAAC,KAAK,EAAE,6BAA6B,CAAC;QAC/C,aAAa,CAAC,MAAM,CAAC;QACrB,yBAAyB,CAAC,MAAM,CAAC;QACjC,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAC9D,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAC;QAChD,SAAS,CAAC,MAAM,EAAE,wBAAwB,CAAC;QAC3C,aAAa,CAAC,QAAQ,CAAC;QACvB,yBAAyB,CAAC,QAAQ,CAAC;QACnC,sBAAsB,CACpB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CACrD;QACD,SAAS,CAAC,QAAQ,EAAE,oCAAoC,CAAC;QACzD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,6BAA6B,CAAC,KAAK,QAAQ;QACxE,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC;QAC/B,gBAAgB,CAAC,KAAK,CACpB,CAAC,SAAS,EAAE,EAAE,CACZ,aAAa,CAAC,SAAS,CAAC,IAAI,yBAAyB,CAAC,SAAS,CAAC,CACnE,CACF,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAC3B,KAAa;IAEb,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,SAAkB,EAAE,EAAE;QACrE,IACE,OAAO,SAAS,KAAK,QAAQ;YAC7B,SAAS,KAAK,IAAI;YAClB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC;YACnC,WAAW,IAAI,SAAS,EACxB,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,mCAAmC,CAAC,MAAM,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0CAA0C,CAAC,KAQhE;IACC,MAAM,UAAU,GACd,KAAK,CAAC,sBAAsB;QAC5B,CAAC,KAAK,CAAC,yBAAyB;YAC9B,CAAC,CAAC,+BAA+B,KAAK,CAAC,MAAM,EAAE;YAC/C,CAAC,CAAC,IAAI,CAAC,CAAC;IACZ,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO;YACL,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,8BAA8B,CAAC,KAAK,CAAC;YAC9C,eAAe,EAAE,KAAK,CAAC,eAAe;SACvC,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,6CAA6C,CAAC,UAAU,CAC3E,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,EAC7B;QACE,sBAAsB,EAAE,UAAU;QAClC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc;QAC9C,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,mBAAmB,EAAE,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC;KACzD,EACD,KAAK,CAAC,uBAAuB,CAC9B,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,oBAAoB,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,8BAA8B,CAAC;QAC7C,SAAS;QACT,yBAAyB,EAAE,KAAK,CAAC,yBAAyB;QAC1D,sBAAsB,EAAE,KAAK,CAAC,sBAAsB;QACpD,eAAe,EAAE,MAAM,CAAC,eAAe;QACvC,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAC;IACH,IACE,SAAS,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAClD,OAAO,CAAC,cAAc,KAAK,MAAM,CAAC,cAAc;QAChD,OAAO,CAAC,eAAe,KAAK,MAAM,CAAC,eAAe;QAClD,CAAC,2BAA2B,CAAC,OAAO,CAAC,EACrC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kDAAkD,CAAC,KAKxE;IACC,MAAM,UAAU,GAAG,+BAA+B,KAAK,CAAC,MAAM,EAAE,CAAC;IACjE,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,6CAA6C,CAAC,IAAI,CACrE,OAAO,EACP,UAAU,CACX,CAAC;IACF,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IACE,MAAM,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAC9B,MAAM,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,EAC9C,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,qCAAqC,CAAC;QAC3C,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO;QACP,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,sBAAsB,EAAE,UAAU;QAClC,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qCAAqC,CAAC,KAM3D;IACC,OAAO,6CAA6C,CAAC,MAAM,CACzD,KAAK,CAAC,OAAO,EACb,KAAK,EACL,KAAK,CAAC,SAAS,CAChB,CAAC;AACJ,CAAC","sourcesContent":["import { base64ToBytes, bytesToBase64 } from \"@tearleads/encoding\";\nimport { isPlainObject } from \"@tearleads/validators/isPlainObject\";\nimport {\n type CreateOrganizationRequest,\n isCreateOrganizationRequest,\n} from \"@tearleads/validators/request\";\nimport { isOrganizationReplacementAuthorization } from \"@tearleads/validators/util\";\nimport { sqlOrganizationProvisioningAttemptPersistence } from \"../../../data/persistence/organizations/organizationProvisioningAttemptPersistence\";\nimport type {\n ExecSql,\n ExecSqlClientLike,\n} from \"../../../data/sqlite/sqlSchema\";\nimport { createExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { OrganizationProvisioningArtifacts } from \"../../registration/organizationProvisioning\";\n\nconst BYTE_MARKER = \"__tearleadsProvisioningBytes\";\n\ninterface DurableOrganizationProvisioningAttempt {\n readonly artifacts: OrganizationProvisioningArtifacts;\n readonly request: CreateOrganizationRequest;\n readonly rootContainerId: string;\n}\n\nfunction buildCreateOrganizationRequest(input: {\n artifacts: OrganizationProvisioningArtifacts;\n finalizeReplacement?: boolean | undefined;\n nativeSubscriptionRestore?: boolean | undefined;\n replacesOrganizationId?: string | undefined;\n rootContainerId: string;\n userId: string;\n}): CreateOrganizationRequest {\n const { artifacts } = input;\n return {\n userId: input.userId,\n ...(artifacts.replacementAuthorization\n ? { replacementAuthorization: artifacts.replacementAuthorization }\n : {}),\n organizationId: artifacts.organizationId,\n rootContainerId: input.rootContainerId,\n initialAdminGroup: artifacts.initialAdminGroup,\n initialMemberGroup: artifacts.initialMemberGroup,\n initialOrganizationPolicy: artifacts.initialOrganizationPolicy,\n initialRootContainer: artifacts.initialRootContainer,\n initialRootMetadataDocument: artifacts.rootMetadataDocumentRequest,\n initialRosterProfileContainer:\n artifacts.rosterProfileBootstrap.containerRequest,\n initialRosterProfileDocument:\n artifacts.rosterProfileBootstrap.profileDocumentRequest,\n initialOrganizationMetadataContainer:\n artifacts.organizationMetadataBootstrap.containerRequest,\n initialOrganizationProfileDocument:\n artifacts.organizationMetadataBootstrap\n .organizationProfileDocumentRequest,\n initialSystemContainers: artifacts.systemContainerBootstraps.map(\n (systemContainer) => systemContainer.containerRequest,\n ),\n ...(input.finalizeReplacement ? { finalizeReplacement: true } : {}),\n ...(input.nativeSubscriptionRestore\n ? { nativeSubscriptionRestore: true as const }\n : {}),\n ...(input.replacesOrganizationId\n ? { replacesOrganizationId: input.replacesOrganizationId }\n : {}),\n };\n}\n\nexport async function loadOrganizationReplacementFinalizationRequest(input: {\n execSql: ExecSql;\n replacedOrganizationId: string;\n userId: string;\n}): Promise<CreateOrganizationRequest> {\n const stored = await sqlOrganizationProvisioningAttemptPersistence.load(\n input.execSql,\n input.replacedOrganizationId,\n );\n if (!stored) {\n throw new Error(\"Organization replacement attempt is unavailable\");\n }\n if (stored.userId !== input.userId) {\n throw new Error(\n \"Stored organization provisioning attempt belongs to another user\",\n );\n }\n const artifacts = deserializeArtifacts(stored.serializedArtifacts);\n const request = buildCreateOrganizationRequest({\n artifacts,\n finalizeReplacement: true,\n replacesOrganizationId: input.replacedOrganizationId,\n rootContainerId: stored.rootContainerId,\n userId: stored.userId,\n });\n if (\n artifacts.organizationId !== stored.organizationId ||\n request.organizationId !== stored.organizationId ||\n request.rootContainerId !== stored.rootContainerId ||\n !isCreateOrganizationRequest(request)\n ) {\n throw new Error(\"Stored organization provisioning attempt is inconsistent\");\n }\n return request;\n}\n\nfunction serializeArtifacts(artifacts: OrganizationProvisioningArtifacts) {\n return JSON.stringify(artifacts, (_key, value: unknown) => {\n if (value instanceof Uint8Array) {\n return { [BYTE_MARKER]: bytesToBase64(value) };\n }\n return value;\n });\n}\n\nfunction hasRecord(value: Record<string, unknown>, key: string): boolean {\n return isPlainObject(Reflect.get(value, key));\n}\n\nfunction hasBytes(value: Record<string, unknown>, key: string): boolean {\n return Reflect.get(value, key) instanceof Uint8Array;\n}\n\nfunction isMaterializedDocument(value: unknown): boolean {\n return (\n isPlainObject(value) &&\n hasBytes(value, \"contentKey\") &&\n hasRecord(value, \"plan\")\n );\n}\n\nfunction isMaterializedContainer(value: unknown): boolean {\n return (\n isPlainObject(value) &&\n hasBytes(value, \"containerKey\") &&\n hasRecord(value, \"plan\")\n );\n}\n\nfunction hasContainerBootstrapCore(value: Record<string, unknown>): boolean {\n return (\n typeof Reflect.get(value, \"containerId\") === \"string\" &&\n isMaterializedDocument(Reflect.get(value, \"containerMetadataDocument\")) &&\n hasBytes(value, \"containerMetadataInitialUpdate\") &&\n isMaterializedContainer(Reflect.get(value, \"containerPlan\")) &&\n hasRecord(value, \"containerRequest\") &&\n Reflect.get(value, \"systemSlot\") !== undefined\n );\n}\n\nfunction isOrganizationProvisioningArtifacts(\n value: unknown,\n): value is OrganizationProvisioningArtifacts {\n if (!isPlainObject(value)) return false;\n const bootstrap = Reflect.get(value, \"bootstrap\");\n const roster = Reflect.get(value, \"rosterProfileBootstrap\");\n const metadata = Reflect.get(value, \"organizationMetadataBootstrap\");\n const systemContainers = Reflect.get(value, \"systemContainerBootstraps\");\n return (\n (Reflect.get(value, \"replacementAuthorization\") === null ||\n isOrganizationReplacementAuthorization(\n Reflect.get(value, \"replacementAuthorization\"),\n )) &&\n typeof Reflect.get(value, \"organizationId\") === \"string\" &&\n isPlainObject(bootstrap) &&\n hasBytes(bootstrap, \"initialUpdate\") &&\n typeof Reflect.get(bootstrap, \"metadataDocumentId\") === \"string\" &&\n hasRecord(value, \"initialAdminGroup\") &&\n hasRecord(value, \"initialMemberGroup\") &&\n hasRecord(value, \"initialOrganizationPolicy\") &&\n hasRecord(value, \"initialRootContainer\") &&\n isMaterializedContainer(Reflect.get(value, \"rootContainer\")) &&\n isMaterializedDocument(Reflect.get(value, \"rootMetadataDocument\")) &&\n hasRecord(value, \"rootMetadataDocumentRequest\") &&\n isPlainObject(roster) &&\n hasContainerBootstrapCore(roster) &&\n isMaterializedDocument(Reflect.get(roster, \"profileDocument\")) &&\n hasBytes(roster, \"profileDocumentInitialUpdate\") &&\n hasRecord(roster, \"profileDocumentRequest\") &&\n isPlainObject(metadata) &&\n hasContainerBootstrapCore(metadata) &&\n isMaterializedDocument(\n Reflect.get(metadata, \"organizationProfileDocument\"),\n ) &&\n hasRecord(metadata, \"organizationProfileDocumentRequest\") &&\n typeof Reflect.get(metadata, \"organizationProfileSnapshot\") === \"string\" &&\n Array.isArray(systemContainers) &&\n systemContainers.every(\n (container) =>\n isPlainObject(container) && hasContainerBootstrapCore(container),\n )\n );\n}\n\nfunction deserializeArtifacts(\n value: string,\n): OrganizationProvisioningArtifacts {\n const parsed: unknown = JSON.parse(value, (_key, candidate: unknown) => {\n if (\n typeof candidate === \"object\" &&\n candidate !== null &&\n Object.keys(candidate).length === 1 &&\n BYTE_MARKER in candidate\n ) {\n const encoded = Reflect.get(candidate, BYTE_MARKER);\n if (typeof encoded === \"string\") {\n return base64ToBytes(encoded);\n }\n }\n return candidate;\n });\n if (!isOrganizationProvisioningArtifacts(parsed)) {\n throw new Error(\"Stored organization provisioning attempt is invalid\");\n }\n return parsed;\n}\n\nexport async function makeOrganizationProvisioningAttemptDurable(input: {\n artifacts: OrganizationProvisioningArtifacts;\n canStartDurableMutation?: (() => boolean) | undefined;\n dbClient: ExecSqlClientLike;\n nativeSubscriptionRestore?: boolean | undefined;\n replacesOrganizationId?: string | undefined;\n rootContainerId: string;\n userId: string;\n}): Promise<DurableOrganizationProvisioningAttempt | null> {\n const attemptKey =\n input.replacesOrganizationId ??\n (input.nativeSubscriptionRestore\n ? `native-subscription-restore:${input.userId}`\n : null);\n if (!attemptKey) {\n return {\n artifacts: input.artifacts,\n request: buildCreateOrganizationRequest(input),\n rootContainerId: input.rootContainerId,\n };\n }\n const stored = await sqlOrganizationProvisioningAttemptPersistence.loadOrSave(\n createExecSql(input.dbClient),\n {\n replacedOrganizationId: attemptKey,\n userId: input.userId,\n organizationId: input.artifacts.organizationId,\n rootContainerId: input.rootContainerId,\n serializedArtifacts: serializeArtifacts(input.artifacts),\n },\n input.canStartDurableMutation,\n );\n if (!stored) return null;\n if (stored.userId !== input.userId) {\n throw new Error(\n \"Stored organization provisioning attempt belongs to another user\",\n );\n }\n const artifacts = deserializeArtifacts(stored.serializedArtifacts);\n const request = buildCreateOrganizationRequest({\n artifacts,\n nativeSubscriptionRestore: input.nativeSubscriptionRestore,\n replacesOrganizationId: input.replacesOrganizationId,\n rootContainerId: stored.rootContainerId,\n userId: stored.userId,\n });\n if (\n artifacts.organizationId !== stored.organizationId ||\n request.organizationId !== stored.organizationId ||\n request.rootContainerId !== stored.rootContainerId ||\n !isCreateOrganizationRequest(request)\n ) {\n throw new Error(\"Stored organization provisioning attempt is inconsistent\");\n }\n return { artifacts, request, rootContainerId: stored.rootContainerId };\n}\n\nexport async function removeNativeSubscriptionRestoreProvisioningAttempt(input: {\n canCommit?: (() => boolean) | undefined;\n dbClient: ExecSqlClientLike;\n organizationId: string;\n userId: string;\n}): Promise<boolean> {\n const attemptKey = `native-subscription-restore:${input.userId}`;\n const execSql = createExecSql(input.dbClient);\n const stored = await sqlOrganizationProvisioningAttemptPersistence.load(\n execSql,\n attemptKey,\n );\n if (!stored) return true;\n if (\n stored.userId !== input.userId ||\n stored.organizationId !== input.organizationId\n ) {\n throw new Error(\n \"Stored native restore organization provisioning attempt is inconsistent\",\n );\n }\n return removeOrganizationProvisioningAttempt({\n canCommit: input.canCommit,\n execSql,\n organizationId: input.organizationId,\n replacedOrganizationId: attemptKey,\n userId: input.userId,\n });\n}\n\nexport async function removeOrganizationProvisioningAttempt(input: {\n canCommit?: (() => boolean) | undefined;\n execSql: ExecSql;\n organizationId?: string | undefined;\n replacedOrganizationId: string;\n userId: string;\n}): Promise<boolean> {\n return sqlOrganizationProvisioningAttemptPersistence.remove(\n input.execSql,\n input,\n input.canCommit,\n );\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { sqlContainerContentsPersistence } from "../../../data/persistence/conta
|
|
|
3
3
|
import { DOCUMENTS_APP_KIND, sqlDocumentsPersistence, } from "../../../data/persistence/documents/documentsPersistence.js";
|
|
4
4
|
import { loadOrganizationProfileDocumentIds } from "../../../data/persistence/organizations/organizationProfileDocumentPointers.js";
|
|
5
5
|
import { findLocalIdByDocumentId } from "../../../data/sqlite/documentPersistence/index.js";
|
|
6
|
-
import { loadPersistedDocumentContent } from "../../documents/
|
|
6
|
+
import { loadPersistedDocumentContent } from "../../documents/index.js";
|
|
7
7
|
import { getOrganizationProfileDocumentLocalId, readOrganizationProfileName, } from "../organizationProfile.js";
|
|
8
8
|
import { deriveOrganizationMetadataContainerSystemSlot } from "../rosterProfileContainer.js";
|
|
9
9
|
// Reads and decrypts the `name` field of the organization_profile document
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listLocalOrganizations.js","sourceRoot":"","sources":["listLocalOrganizations.ts"],"names":[],"mappings":"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","sourcesContent":["import { readStoredDocumentState } from \"../../../data/documents/documentKinds\";\nimport { sqlContainerContentsPersistence } from \"../../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n DOCUMENTS_APP_KIND,\n sqlDocumentsPersistence,\n} from \"../../../data/persistence/documents/documentsPersistence\";\nimport { loadOrganizationProfileDocumentIds } from \"../../../data/persistence/organizations/organizationProfileDocumentPointers\";\nimport { findLocalIdByDocumentId } from \"../../../data/sqlite/documentPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { loadPersistedDocumentContent } from \"../../documents/historyContent\";\nimport {\n getOrganizationProfileDocumentLocalId,\n readOrganizationProfileName,\n} from \"../organizationProfile\";\nimport { deriveOrganizationMetadataContainerSystemSlot } from \"../rosterProfileContainer\";\n\n// Just the container fields this module needs to locate an org's metadata\n// container among the locally-persisted containers.\ninterface LocalContainerForNameLookup {\n id: string;\n systemSlot: string | null;\n}\n\n/**\n * A locally-known organization the user belongs to, derived from its persisted\n * root container. `name` is the decrypted organization-profile display name when\n * one is stored locally, or null when it has not synced yet.\n */\nexport interface LocalOrganizationSummary {\n name: string | null;\n organizationId: string;\n rootContainerId: string;\n}\n\n// Reads and decrypts the `name` field of the organization_profile document\n// persisted under `documentLocalId`, or null if it is absent, empty, or\n// unparseable. A single corrupt profile must not break the whole list, so every\n// failure collapses to a null (unnamed) organization.\nasync function readOrganizationNameFromDocument(\n execSql: ExecSql,\n documentLocalId: string,\n): Promise<string | null> {\n try {\n const doc = await loadPersistedDocumentContent({\n execSql,\n localId: documentLocalId,\n persistence: sqlDocumentsPersistence,\n });\n if (!doc) {\n return null;\n }\n\n return readOrganizationProfileName(\n readStoredDocumentState(doc).structuredFields,\n );\n } catch {\n return null;\n }\n}\n\n/**\n * Resolves an organization's decrypted display name from local state.\n *\n * The same organization_profile document is addressed by several different\n * local-id conventions depending on how it arrived, so one lookup by id is not\n * enough:\n *\n * - The org's own **provisioner** (and any admin who later edits the name)\n * writes the document under the deterministic alias\n * `org-profile:<organizationId>` — resolved by the fast path below.\n * - A **device that only synced it** — a member of another org, or this same\n * user's freshly re-hydrated device after an identity restore — never runs\n * that write. The sync ingest keys the document under the server documentId\n * (there is no local alias to reuse — see `upsertDiscoveredDocumentWithExec`),\n * so the alias lookup misses.\n *\n * Two fallbacks cover the synced case, in order of authority:\n *\n * 1. The **organization read model** records the org's `profileDocumentId`.\n * That pointer is container-independent, so it resolves the name wherever\n * the document happens to be linked — including a profile document created\n * by an admin through the org-manager editor rather than by provisioning.\n * 2. Failing that, locate the org's metadata container by its deterministic\n * system slot and read whichever profile document is linked there. Keying on\n * the system slot (rather than the document kind) keeps it correct even\n * before the projected document kind has been rebuilt from a freshly-synced\n * snapshot, and it still works before the read model has been projected.\n */\nasync function readLocalOrganizationName(\n execSql: ExecSql,\n organizationId: string,\n organizationContainers: ReadonlyArray<LocalContainerForNameLookup>,\n profileDocumentId: string | null,\n): Promise<string | null> {\n const aliasName = await readOrganizationNameFromDocument(\n execSql,\n getOrganizationProfileDocumentLocalId({ organizationId }),\n );\n if (aliasName !== null) {\n return aliasName;\n }\n\n if (profileDocumentId) {\n // Reach the row wherever it landed: a device that only synced the document\n // keys it under the server documentId rather than any local alias.\n const syncedLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n profileDocumentId,\n );\n const syncedName = syncedLocalId\n ? await readOrganizationNameFromDocument(execSql, syncedLocalId)\n : null;\n if (syncedName !== null) {\n return syncedName;\n }\n }\n\n const metadataSystemSlot =\n await deriveOrganizationMetadataContainerSystemSlot({ organizationId });\n const metadataContainer = organizationContainers.find(\n (container) => container.systemSlot === metadataSystemSlot,\n );\n if (!metadataContainer) {\n return null;\n }\n\n const documentLocalIds =\n await sqlDocumentsPersistence.findDocumentLocalIdsByContainerId(\n execSql,\n metadataContainer.id,\n );\n for (const documentLocalId of documentLocalIds) {\n const name = await readOrganizationNameFromDocument(\n execSql,\n documentLocalId,\n );\n if (name !== null) {\n return name;\n }\n }\n return null;\n}\n\n/**\n * Enumerates the organizations the user can manage from local state: one per\n * persisted root container. This is intentionally offline — the Explorer already\n * resolves files across organizations by effective permission, so listing the\n * organizations to manage needs no server round-trip.\n */\nexport async function listLocalOrganizations(input: {\n execSql: ExecSql;\n}): Promise<LocalOrganizationSummary[]> {\n const containers = await sqlContainerContentsPersistence.loadContainers(\n input.execSql,\n );\n // A projected read model is not a precondition for listing organizations, so\n // an unreadable one degrades to the container-derived lookups below.\n const profileDocumentIdsByOrganizationId =\n await loadOrganizationProfileDocumentIds(input.execSql).catch(\n () => new Map<string, string>(),\n );\n\n // Group every persisted container by org so name resolution can locate an\n // org's independent metadata root without a second DB scan.\n const containersByOrganizationId = new Map<\n string,\n LocalContainerForNameLookup[]\n >();\n for (const { container } of containers) {\n const entry: LocalContainerForNameLookup = {\n id: container.id,\n systemSlot: container.systemSlot ?? null,\n };\n const group = containersByOrganizationId.get(container.organizationId);\n if (group) {\n group.push(entry);\n } else {\n containersByOrganizationId.set(container.organizationId, [entry]);\n }\n }\n\n const seen = new Set<string>();\n const rootContainers = containers.filter(({ container }) => {\n if (\n container.parentId !== null ||\n container.systemSlot ||\n seen.has(container.organizationId)\n ) {\n return false;\n }\n seen.add(container.organizationId);\n return true;\n });\n rootContainers.sort(\n (left, right) =>\n (left.container.localCreatedAt ?? \"\").localeCompare(\n right.container.localCreatedAt ?? \"\",\n ) ||\n left.container.organizationId.localeCompare(\n right.container.organizationId,\n ) ||\n left.container.id.localeCompare(right.container.id),\n );\n\n // Read each organization's profile name concurrently; readLocalOrganizationName\n // already falls back to null per organization, so a single corrupt profile\n // cannot reject the batch.\n return Promise.all(\n rootContainers.map(async ({ container }) => ({\n name: await readLocalOrganizationName(\n input.execSql,\n container.organizationId,\n containersByOrganizationId.get(container.organizationId) ?? [],\n profileDocumentIdsByOrganizationId.get(container.organizationId) ??\n null,\n ),\n organizationId: container.organizationId,\n rootContainerId: container.id,\n })),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"listLocalOrganizations.js","sourceRoot":"","sources":["listLocalOrganizations.ts"],"names":[],"mappings":"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","sourcesContent":["import { readStoredDocumentState } from \"../../../data/documents/documentKinds\";\nimport { sqlContainerContentsPersistence } from \"../../../data/persistence/container-contents/containerContentsPersistence\";\nimport {\n DOCUMENTS_APP_KIND,\n sqlDocumentsPersistence,\n} from \"../../../data/persistence/documents/documentsPersistence\";\nimport { loadOrganizationProfileDocumentIds } from \"../../../data/persistence/organizations/organizationProfileDocumentPointers\";\nimport { findLocalIdByDocumentId } from \"../../../data/sqlite/documentPersistence\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport { loadPersistedDocumentContent } from \"../../documents\";\nimport {\n getOrganizationProfileDocumentLocalId,\n readOrganizationProfileName,\n} from \"../organizationProfile\";\nimport { deriveOrganizationMetadataContainerSystemSlot } from \"../rosterProfileContainer\";\n\n// Just the container fields this module needs to locate an org's metadata\n// container among the locally-persisted containers.\ninterface LocalContainerForNameLookup {\n id: string;\n systemSlot: string | null;\n}\n\n/**\n * A locally-known organization the user belongs to, derived from its persisted\n * root container. `name` is the decrypted organization-profile display name when\n * one is stored locally, or null when it has not synced yet.\n */\nexport interface LocalOrganizationSummary {\n name: string | null;\n organizationId: string;\n rootContainerId: string;\n}\n\n// Reads and decrypts the `name` field of the organization_profile document\n// persisted under `documentLocalId`, or null if it is absent, empty, or\n// unparseable. A single corrupt profile must not break the whole list, so every\n// failure collapses to a null (unnamed) organization.\nasync function readOrganizationNameFromDocument(\n execSql: ExecSql,\n documentLocalId: string,\n): Promise<string | null> {\n try {\n const doc = await loadPersistedDocumentContent({\n execSql,\n localId: documentLocalId,\n persistence: sqlDocumentsPersistence,\n });\n if (!doc) {\n return null;\n }\n\n return readOrganizationProfileName(\n readStoredDocumentState(doc).structuredFields,\n );\n } catch {\n return null;\n }\n}\n\n/**\n * Resolves an organization's decrypted display name from local state.\n *\n * The same organization_profile document is addressed by several different\n * local-id conventions depending on how it arrived, so one lookup by id is not\n * enough:\n *\n * - The org's own **provisioner** (and any admin who later edits the name)\n * writes the document under the deterministic alias\n * `org-profile:<organizationId>` — resolved by the fast path below.\n * - A **device that only synced it** — a member of another org, or this same\n * user's freshly re-hydrated device after an identity restore — never runs\n * that write. The sync ingest keys the document under the server documentId\n * (there is no local alias to reuse — see `upsertDiscoveredDocumentWithExec`),\n * so the alias lookup misses.\n *\n * Two fallbacks cover the synced case, in order of authority:\n *\n * 1. The **organization read model** records the org's `profileDocumentId`.\n * That pointer is container-independent, so it resolves the name wherever\n * the document happens to be linked — including a profile document created\n * by an admin through the org-manager editor rather than by provisioning.\n * 2. Failing that, locate the org's metadata container by its deterministic\n * system slot and read whichever profile document is linked there. Keying on\n * the system slot (rather than the document kind) keeps it correct even\n * before the projected document kind has been rebuilt from a freshly-synced\n * snapshot, and it still works before the read model has been projected.\n */\nasync function readLocalOrganizationName(\n execSql: ExecSql,\n organizationId: string,\n organizationContainers: ReadonlyArray<LocalContainerForNameLookup>,\n profileDocumentId: string | null,\n): Promise<string | null> {\n const aliasName = await readOrganizationNameFromDocument(\n execSql,\n getOrganizationProfileDocumentLocalId({ organizationId }),\n );\n if (aliasName !== null) {\n return aliasName;\n }\n\n if (profileDocumentId) {\n // Reach the row wherever it landed: a device that only synced the document\n // keys it under the server documentId rather than any local alias.\n const syncedLocalId = await findLocalIdByDocumentId(\n execSql,\n DOCUMENTS_APP_KIND,\n profileDocumentId,\n );\n const syncedName = syncedLocalId\n ? await readOrganizationNameFromDocument(execSql, syncedLocalId)\n : null;\n if (syncedName !== null) {\n return syncedName;\n }\n }\n\n const metadataSystemSlot =\n await deriveOrganizationMetadataContainerSystemSlot({ organizationId });\n const metadataContainer = organizationContainers.find(\n (container) => container.systemSlot === metadataSystemSlot,\n );\n if (!metadataContainer) {\n return null;\n }\n\n const documentLocalIds =\n await sqlDocumentsPersistence.findDocumentLocalIdsByContainerId(\n execSql,\n metadataContainer.id,\n );\n for (const documentLocalId of documentLocalIds) {\n const name = await readOrganizationNameFromDocument(\n execSql,\n documentLocalId,\n );\n if (name !== null) {\n return name;\n }\n }\n return null;\n}\n\n/**\n * Enumerates the organizations the user can manage from local state: one per\n * persisted root container. This is intentionally offline — the Explorer already\n * resolves files across organizations by effective permission, so listing the\n * organizations to manage needs no server round-trip.\n */\nexport async function listLocalOrganizations(input: {\n execSql: ExecSql;\n}): Promise<LocalOrganizationSummary[]> {\n const containers = await sqlContainerContentsPersistence.loadContainers(\n input.execSql,\n );\n // A projected read model is not a precondition for listing organizations, so\n // an unreadable one degrades to the container-derived lookups below.\n const profileDocumentIdsByOrganizationId =\n await loadOrganizationProfileDocumentIds(input.execSql).catch(\n () => new Map<string, string>(),\n );\n\n // Group every persisted container by org so name resolution can locate an\n // org's independent metadata root without a second DB scan.\n const containersByOrganizationId = new Map<\n string,\n LocalContainerForNameLookup[]\n >();\n for (const { container } of containers) {\n const entry: LocalContainerForNameLookup = {\n id: container.id,\n systemSlot: container.systemSlot ?? null,\n };\n const group = containersByOrganizationId.get(container.organizationId);\n if (group) {\n group.push(entry);\n } else {\n containersByOrganizationId.set(container.organizationId, [entry]);\n }\n }\n\n const seen = new Set<string>();\n const rootContainers = containers.filter(({ container }) => {\n if (\n container.parentId !== null ||\n container.systemSlot ||\n seen.has(container.organizationId)\n ) {\n return false;\n }\n seen.add(container.organizationId);\n return true;\n });\n rootContainers.sort(\n (left, right) =>\n (left.container.localCreatedAt ?? \"\").localeCompare(\n right.container.localCreatedAt ?? \"\",\n ) ||\n left.container.organizationId.localeCompare(\n right.container.organizationId,\n ) ||\n left.container.id.localeCompare(right.container.id),\n );\n\n // Read each organization's profile name concurrently; readLocalOrganizationName\n // already falls back to null per organization, so a single corrupt profile\n // cannot reject the batch.\n return Promise.all(\n rootContainers.map(async ({ container }) => ({\n name: await readLocalOrganizationName(\n input.execSql,\n container.organizationId,\n containersByOrganizationId.get(container.organizationId) ?? [],\n profileDocumentIdsByOrganizationId.get(container.organizationId) ??\n null,\n ),\n organizationId: container.organizationId,\n rootContainerId: container.id,\n })),\n );\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { bootstrapRootContainer } from "./bootstrapRootContainer.js";
|
|
2
|
+
export { buildInitialOrganizationPolicyRequest, type ProvisionedSystemContainerSpec, } from "./organizationProvisioning.js";
|
|
2
3
|
export { persistRegistrationBootstrap } from "./persistRegistrationBootstrap.js";
|
|
3
|
-
export {
|
|
4
|
+
export { type RegisterIdentityInput, type RegistrationApi, registerIdentity, } from "./registerIdentity.js";
|
|
4
5
|
export { principalPolicyBundleFromInitialGroupRequest } from "./registrationPrincipalPolicyPersistence.js";
|
|
5
6
|
export { createInitialRootMetadataBootstrap, type InitialRootMetadataBootstrap, } from "./rootMetadataBootstrap.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { bootstrapRootContainer } from "./bootstrapRootContainer.js";
|
|
2
|
+
export { buildInitialOrganizationPolicyRequest, } from "./organizationProvisioning.js";
|
|
2
3
|
export { persistRegistrationBootstrap } from "./persistRegistrationBootstrap.js";
|
|
3
|
-
export {
|
|
4
|
+
export { registerIdentity, } from "./registerIdentity.js";
|
|
4
5
|
export { principalPolicyBundleFromInitialGroupRequest } from "./registrationPrincipalPolicyPersistence.js";
|
|
5
6
|
export { createInitialRootMetadataBootstrap, } from "./rootMetadataBootstrap.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EACL,qCAAqC,GAEtC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAGL,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,4CAA4C,EAAE,MAAM,0CAA0C,CAAC;AACxG,OAAO,EACL,kCAAkC,GAEnC,MAAM,yBAAyB,CAAC","sourcesContent":["export { bootstrapRootContainer } from \"./bootstrapRootContainer\";\nexport {\n buildInitialOrganizationPolicyRequest,\n type ProvisionedSystemContainerSpec,\n} from \"./organizationProvisioning\";\nexport { persistRegistrationBootstrap } from \"./persistRegistrationBootstrap\";\nexport {\n type RegisterIdentityInput,\n type RegistrationApi,\n registerIdentity,\n} from \"./registerIdentity\";\nexport { principalPolicyBundleFromInitialGroupRequest } from \"./registrationPrincipalPolicyPersistence\";\nexport {\n createInitialRootMetadataBootstrap,\n type InitialRootMetadataBootstrap,\n} from \"./rootMetadataBootstrap\";\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type EncapsulationKeyPair, type ReferencedPrincipalHead, type SigningKeyPair } from "../../internal/crypto/index.js";
|
|
2
|
+
import type { RegistrationRequest } from "../../internal/validators/request/index.js";
|
|
3
|
+
import type { OrganizationProvisioningArtifacts } from "./organizationProvisioningArtifacts.js";
|
|
4
|
+
import { type ProvisionedSystemContainerSpec } from "./provisioningBootstrapBuilders.js";
|
|
5
|
+
export type { OrganizationProvisioningArtifacts } from "./organizationProvisioningArtifacts.js";
|
|
6
|
+
export { persistOrganizationProvisioningState } from "./organizationProvisioningPersistence.js";
|
|
7
|
+
export type { ProvisionedSystemContainerSpec } from "./provisioningBootstrapBuilders.js";
|
|
8
|
+
/**
|
|
9
|
+
* The freshly built provisioning artifacts, shared by registration and
|
|
10
|
+
* additional-organization creation. `registerIdentity` generates a new
|
|
11
|
+
* `userId`; creating an additional organization reuses the caller's existing
|
|
12
|
+
* one. Everything here is derived purely from the caller's key material, so it
|
|
13
|
+
* is identical for both flows.
|
|
14
|
+
*/
|
|
15
|
+
export interface OrganizationProvisioningArtifactsInput {
|
|
16
|
+
encapsulationKeyPair: EncapsulationKeyPair;
|
|
17
|
+
organizationProfileName?: string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* App-owned system containers to provision atomically with the organization
|
|
20
|
+
* (e.g. a trash bin). Omitted/empty leaves the org with only the roster and
|
|
21
|
+
* organization-metadata system containers.
|
|
22
|
+
*/
|
|
23
|
+
provisionedSystemContainers?: ReadonlyArray<ProvisionedSystemContainerSpec> | undefined;
|
|
24
|
+
rootContainerId: string;
|
|
25
|
+
rosterProfileNickname?: string | undefined;
|
|
26
|
+
signingKeyPair: SigningKeyPair;
|
|
27
|
+
userId: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function buildInitialOrganizationPolicyRequest(input: {
|
|
30
|
+
adminGroupId: string;
|
|
31
|
+
groupHeads: readonly ReferencedPrincipalHead[];
|
|
32
|
+
encapsulationPublicKey: Uint8Array;
|
|
33
|
+
memberGroupId: string;
|
|
34
|
+
organizationId: string;
|
|
35
|
+
signingKeyPair: SigningKeyPair;
|
|
36
|
+
userId: string;
|
|
37
|
+
}): Promise<RegistrationRequest["initialOrganizationPolicy"]>;
|
|
38
|
+
/** Builds the signed artifacts shared by registration and org creation. */
|
|
39
|
+
export declare function buildOrganizationProvisioningArtifacts(input: OrganizationProvisioningArtifactsInput): Promise<OrganizationProvisioningArtifacts>;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// Registration and additional-organization creation build and persist an
|
|
2
|
+
// organization's founding policies, system containers, and profile documents
|
|
3
|
+
// through this module.
|
|
4
|
+
import { buildPrincipalStateSigningInput, generateKemSeedAndKeyPair, signPrincipalState, toFingerprint, wrapDekForRecipients, } from "../../internal/crypto/index.js";
|
|
5
|
+
import { bytesToBase64 } from "../../internal/encoding/index.js";
|
|
6
|
+
import { encodeOrganizationAuthorityDescriptor } from "../../data/principals/organizationAuthorityDescriptor.js";
|
|
7
|
+
import { resolveDocumentCreateAuthor } from "../documents/index.js";
|
|
8
|
+
import { groupPolicyMutationHead } from "../organizations/groupPolicy/groupPolicyMutationHead.js";
|
|
9
|
+
import { buildInitialGroupPolicyRequest, buildInitialMemberGroupPolicyRequest, } from "../organizations/principalPolicy/index.js";
|
|
10
|
+
import { buildInitialOrganizationMetadataBootstrap, buildInitialRootProvisioning, buildInitialRosterProfileBootstrap, buildInitialSystemContainerBootstrap, } from "./provisioningBootstrapBuilders.js";
|
|
11
|
+
import { createInitialRootMetadataBootstrap } from "./rootMetadataBootstrap.js";
|
|
12
|
+
export { persistOrganizationProvisioningState } from "./organizationProvisioningPersistence.js";
|
|
13
|
+
export async function buildInitialOrganizationPolicyRequest(input) {
|
|
14
|
+
const organizationKem = generateKemSeedAndKeyPair();
|
|
15
|
+
const signerUserKeyFingerprint = await toFingerprint(input.signingKeyPair.signingPublicKey);
|
|
16
|
+
const userEncapsulationKeyFingerprint = await toFingerprint(input.encapsulationPublicKey);
|
|
17
|
+
const projection = [
|
|
18
|
+
{
|
|
19
|
+
userId: input.userId,
|
|
20
|
+
role: "admin",
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
const payloadCiphertext = encodeOrganizationAuthorityDescriptor({
|
|
24
|
+
version: 2,
|
|
25
|
+
organizationId: input.organizationId,
|
|
26
|
+
adminGroupId: input.adminGroupId,
|
|
27
|
+
memberGroupId: input.memberGroupId,
|
|
28
|
+
groupHeads: input.groupHeads.map((head) => {
|
|
29
|
+
if (head.principalType !== "group") {
|
|
30
|
+
throw new Error("Organization directory can contain only group heads");
|
|
31
|
+
}
|
|
32
|
+
return { ...head, principalType: "group" };
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
const [memberEnvelope] = await wrapDekForRecipients(organizationKem.secretKey, [input.encapsulationPublicKey]);
|
|
36
|
+
if (!memberEnvelope) {
|
|
37
|
+
throw new Error("Failed to wrap organization key for registering user");
|
|
38
|
+
}
|
|
39
|
+
const memberEnvelopes = [
|
|
40
|
+
{
|
|
41
|
+
userId: input.userId,
|
|
42
|
+
memberKeyFingerprint: userEncapsulationKeyFingerprint,
|
|
43
|
+
kemCipherText: bytesToBase64(memberEnvelope.kemCipherText),
|
|
44
|
+
wrappedKey: bytesToBase64(memberEnvelope.wrappedKey),
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const state = await signPrincipalState(await buildPrincipalStateSigningInput({
|
|
48
|
+
principalType: "organization",
|
|
49
|
+
principalId: input.organizationId,
|
|
50
|
+
version: 1,
|
|
51
|
+
prevStateHash: null,
|
|
52
|
+
keyEpoch: 1,
|
|
53
|
+
encapsulationPublicKey: bytesToBase64(organizationKem.publicKey),
|
|
54
|
+
keyFingerprint: await toFingerprint(organizationKem.publicKey),
|
|
55
|
+
members: [{ userId: input.userId }],
|
|
56
|
+
memberEnvelopes,
|
|
57
|
+
projection,
|
|
58
|
+
grants: [],
|
|
59
|
+
payloadCiphertext,
|
|
60
|
+
externalAuthority: null,
|
|
61
|
+
signedAt: new Date().toISOString(),
|
|
62
|
+
signerUserId: input.userId,
|
|
63
|
+
signerUserKeyFingerprint,
|
|
64
|
+
}), input.signingKeyPair.signingPrivateKey);
|
|
65
|
+
return {
|
|
66
|
+
state,
|
|
67
|
+
encryptedPayload: {
|
|
68
|
+
cipherSuite: "aes-256-gcm",
|
|
69
|
+
ciphertext: payloadCiphertext,
|
|
70
|
+
ciphertextHash: state.payloadCiphertextHash,
|
|
71
|
+
},
|
|
72
|
+
projection,
|
|
73
|
+
grants: [],
|
|
74
|
+
memberEnvelopes,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function createOrganizationPrincipalPolicies(input) {
|
|
78
|
+
const organizationId = crypto.randomUUID();
|
|
79
|
+
const signingFingerprint = await toFingerprint(input.signingKeyPair.signingPublicKey);
|
|
80
|
+
const initialAdminGroup = await buildInitialGroupPolicyRequest({
|
|
81
|
+
creatorEncapsulationKeyPair: input.encapsulationKeyPair,
|
|
82
|
+
groupId: crypto.randomUUID(),
|
|
83
|
+
grants: [
|
|
84
|
+
{ containerId: input.rootContainerId, accessLevel: "admin" },
|
|
85
|
+
{
|
|
86
|
+
containerId: input.organizationMetadataContainerId,
|
|
87
|
+
accessLevel: "admin",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
name: "Admins",
|
|
91
|
+
builtinRole: "admins",
|
|
92
|
+
signerUserId: input.userId,
|
|
93
|
+
signingFingerprint,
|
|
94
|
+
signingKeyPair: input.signingKeyPair,
|
|
95
|
+
});
|
|
96
|
+
const initialMemberGroup = await buildInitialMemberGroupPolicyRequest({
|
|
97
|
+
creatorEncapsulationKeyPair: input.encapsulationKeyPair,
|
|
98
|
+
groupId: crypto.randomUUID(),
|
|
99
|
+
grants: [
|
|
100
|
+
{
|
|
101
|
+
containerId: input.organizationMetadataContainerId,
|
|
102
|
+
accessLevel: "read",
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
signerUserId: input.userId,
|
|
106
|
+
signingFingerprint,
|
|
107
|
+
signingKeyPair: input.signingKeyPair,
|
|
108
|
+
});
|
|
109
|
+
const initialOrganizationPolicy = await buildInitialOrganizationPolicyRequest({
|
|
110
|
+
adminGroupId: initialAdminGroup.groupId,
|
|
111
|
+
encapsulationPublicKey: input.encapsulationKeyPair.publicKey,
|
|
112
|
+
groupHeads: await Promise.all([
|
|
113
|
+
groupPolicyMutationHead(initialAdminGroup.initialGroupPolicy),
|
|
114
|
+
groupPolicyMutationHead(initialMemberGroup.initialGroupPolicy),
|
|
115
|
+
]),
|
|
116
|
+
memberGroupId: initialMemberGroup.groupId,
|
|
117
|
+
organizationId,
|
|
118
|
+
signingKeyPair: input.signingKeyPair,
|
|
119
|
+
userId: input.userId,
|
|
120
|
+
});
|
|
121
|
+
return {
|
|
122
|
+
initialAdminGroup,
|
|
123
|
+
initialMemberGroup,
|
|
124
|
+
initialOrganizationPolicy,
|
|
125
|
+
organizationId,
|
|
126
|
+
signingFingerprint,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function requireOrganizationProvisioningAuthor(input) {
|
|
130
|
+
const author = resolveDocumentCreateAuthor({
|
|
131
|
+
auth: { organizationId: input.organizationId, userId: input.userId },
|
|
132
|
+
crypto: {
|
|
133
|
+
signingFingerprint: input.signingFingerprint,
|
|
134
|
+
signingKeyPair: input.signingKeyPair,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
if (!author) {
|
|
138
|
+
throw new Error(`Organization provisioning document author context is unavailable for user ${input.userId} in organization ${input.organizationId}.`);
|
|
139
|
+
}
|
|
140
|
+
return author;
|
|
141
|
+
}
|
|
142
|
+
/** Builds the signed artifacts shared by registration and org creation. */
|
|
143
|
+
export async function buildOrganizationProvisioningArtifacts(input) {
|
|
144
|
+
const bootstrap = await createInitialRootMetadataBootstrap(input.rootContainerId);
|
|
145
|
+
const organizationMetadataContainerId = crypto.randomUUID();
|
|
146
|
+
const { initialAdminGroup, initialMemberGroup, initialOrganizationPolicy, organizationId, signingFingerprint, } = await createOrganizationPrincipalPolicies({
|
|
147
|
+
encapsulationKeyPair: input.encapsulationKeyPair,
|
|
148
|
+
organizationMetadataContainerId,
|
|
149
|
+
rootContainerId: input.rootContainerId,
|
|
150
|
+
signingKeyPair: input.signingKeyPair,
|
|
151
|
+
userId: input.userId,
|
|
152
|
+
});
|
|
153
|
+
const author = requireOrganizationProvisioningAuthor({
|
|
154
|
+
organizationId,
|
|
155
|
+
signingFingerprint,
|
|
156
|
+
signingKeyPair: input.signingKeyPair,
|
|
157
|
+
userId: input.userId,
|
|
158
|
+
});
|
|
159
|
+
const { rootContainer, rootContainerProjection, rootMetadataDocument, rootMetadataDocumentRequest, } = await buildInitialRootProvisioning({
|
|
160
|
+
adminGroup: initialAdminGroup,
|
|
161
|
+
author,
|
|
162
|
+
bootstrap,
|
|
163
|
+
recipientEncapsulationPublicKey: input.encapsulationKeyPair.publicKey,
|
|
164
|
+
rootContainerId: input.rootContainerId,
|
|
165
|
+
targetSecretKey: input.encapsulationKeyPair.secretKey,
|
|
166
|
+
});
|
|
167
|
+
const rosterProfileBootstrap = await buildInitialRosterProfileBootstrap({
|
|
168
|
+
author,
|
|
169
|
+
encapsulationPublicKey: input.encapsulationKeyPair.publicKey,
|
|
170
|
+
initialAdminGroup,
|
|
171
|
+
rosterProfileNickname: input.rosterProfileNickname,
|
|
172
|
+
rootContainer,
|
|
173
|
+
rootContainerProjection,
|
|
174
|
+
targetSecretKey: input.encapsulationKeyPair.secretKey,
|
|
175
|
+
});
|
|
176
|
+
const organizationMetadataBootstrap = await buildInitialOrganizationMetadataBootstrap({
|
|
177
|
+
author,
|
|
178
|
+
containerId: organizationMetadataContainerId,
|
|
179
|
+
initialAdminGroup,
|
|
180
|
+
initialMemberGroup,
|
|
181
|
+
organizationProfileName: input.organizationProfileName,
|
|
182
|
+
rootContainer,
|
|
183
|
+
rootContainerProjection,
|
|
184
|
+
targetSecretKey: input.encapsulationKeyPair.secretKey,
|
|
185
|
+
});
|
|
186
|
+
const systemContainerBootstraps = await Promise.all((input.provisionedSystemContainers ?? []).map((spec) => buildInitialSystemContainerBootstrap({
|
|
187
|
+
author,
|
|
188
|
+
initialAdminGroup,
|
|
189
|
+
rootContainer,
|
|
190
|
+
rootContainerProjection,
|
|
191
|
+
signingPrivateKey: input.signingKeyPair.signingPrivateKey,
|
|
192
|
+
spec,
|
|
193
|
+
targetSecretKey: input.encapsulationKeyPair.secretKey,
|
|
194
|
+
})));
|
|
195
|
+
return {
|
|
196
|
+
replacementAuthorization: null,
|
|
197
|
+
bootstrap,
|
|
198
|
+
initialAdminGroup,
|
|
199
|
+
initialMemberGroup,
|
|
200
|
+
initialOrganizationPolicy,
|
|
201
|
+
initialRootContainer: rootContainer.plan.request,
|
|
202
|
+
organizationId,
|
|
203
|
+
organizationMetadataBootstrap,
|
|
204
|
+
rootContainer,
|
|
205
|
+
rootMetadataDocument,
|
|
206
|
+
rootMetadataDocumentRequest,
|
|
207
|
+
rosterProfileBootstrap,
|
|
208
|
+
systemContainerBootstraps,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=organizationProvisioning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organizationProvisioning.js","sourceRoot":"","sources":["organizationProvisioning.ts"],"names":[],"mappings":"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","sourcesContent":["// Registration and additional-organization creation build and persist an\n// organization's founding policies, system containers, and profile documents\n// through this module.\nimport {\n buildPrincipalStateSigningInput,\n type EncapsulationKeyPair,\n generateKemSeedAndKeyPair,\n type ReferencedPrincipalHead,\n type SigningKeyPair,\n signPrincipalState,\n toFingerprint,\n wrapDekForRecipients,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n CreateOrganizationGroupRequest,\n RegistrationRequest,\n} from \"@tearleads/validators/request\";\nimport { encodeOrganizationAuthorityDescriptor } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { resolveDocumentCreateAuthor } from \"../documents\";\nimport { groupPolicyMutationHead } from \"../organizations/groupPolicy/groupPolicyMutationHead\";\nimport {\n buildInitialGroupPolicyRequest,\n buildInitialMemberGroupPolicyRequest,\n} from \"../organizations/principalPolicy\";\nimport type { OrganizationProvisioningArtifacts } from \"./organizationProvisioningArtifacts\";\nimport {\n buildInitialOrganizationMetadataBootstrap,\n buildInitialRootProvisioning,\n buildInitialRosterProfileBootstrap,\n buildInitialSystemContainerBootstrap,\n type ProvisionedSystemContainerSpec,\n} from \"./provisioningBootstrapBuilders\";\nimport { createInitialRootMetadataBootstrap } from \"./rootMetadataBootstrap\";\n\nexport type { OrganizationProvisioningArtifacts } from \"./organizationProvisioningArtifacts\";\nexport { persistOrganizationProvisioningState } from \"./organizationProvisioningPersistence\";\nexport type { ProvisionedSystemContainerSpec } from \"./provisioningBootstrapBuilders\";\n\ninterface OrganizationProvisioningPrincipalPolicies {\n initialAdminGroup: CreateOrganizationGroupRequest;\n initialMemberGroup: CreateOrganizationGroupRequest;\n initialOrganizationPolicy: RegistrationRequest[\"initialOrganizationPolicy\"];\n organizationId: string;\n signingFingerprint: string;\n}\n\n/**\n * The freshly built provisioning artifacts, shared by registration and\n * additional-organization creation. `registerIdentity` generates a new\n * `userId`; creating an additional organization reuses the caller's existing\n * one. Everything here is derived purely from the caller's key material, so it\n * is identical for both flows.\n */\nexport interface OrganizationProvisioningArtifactsInput {\n encapsulationKeyPair: EncapsulationKeyPair;\n organizationProfileName?: string | undefined;\n /**\n * App-owned system containers to provision atomically with the organization\n * (e.g. a trash bin). Omitted/empty leaves the org with only the roster and\n * organization-metadata system containers.\n */\n provisionedSystemContainers?:\n | ReadonlyArray<ProvisionedSystemContainerSpec>\n | undefined;\n rootContainerId: string;\n rosterProfileNickname?: string | undefined;\n signingKeyPair: SigningKeyPair;\n userId: string;\n}\n\nexport async function buildInitialOrganizationPolicyRequest(input: {\n adminGroupId: string;\n groupHeads: readonly ReferencedPrincipalHead[];\n encapsulationPublicKey: Uint8Array;\n memberGroupId: string;\n organizationId: string;\n signingKeyPair: SigningKeyPair;\n userId: string;\n}): Promise<RegistrationRequest[\"initialOrganizationPolicy\"]> {\n const organizationKem = generateKemSeedAndKeyPair();\n const signerUserKeyFingerprint = await toFingerprint(\n input.signingKeyPair.signingPublicKey,\n );\n const userEncapsulationKeyFingerprint = await toFingerprint(\n input.encapsulationPublicKey,\n );\n const projection = [\n {\n userId: input.userId,\n role: \"admin\" as const,\n },\n ];\n const payloadCiphertext = encodeOrganizationAuthorityDescriptor({\n version: 2,\n organizationId: input.organizationId,\n adminGroupId: input.adminGroupId,\n memberGroupId: input.memberGroupId,\n groupHeads: input.groupHeads.map((head) => {\n if (head.principalType !== \"group\") {\n throw new Error(\"Organization directory can contain only group heads\");\n }\n return { ...head, principalType: \"group\" };\n }),\n });\n const [memberEnvelope] = await wrapDekForRecipients(\n organizationKem.secretKey,\n [input.encapsulationPublicKey],\n );\n\n if (!memberEnvelope) {\n throw new Error(\"Failed to wrap organization key for registering user\");\n }\n const memberEnvelopes = [\n {\n userId: input.userId,\n memberKeyFingerprint: userEncapsulationKeyFingerprint,\n kemCipherText: bytesToBase64(memberEnvelope.kemCipherText),\n wrappedKey: bytesToBase64(memberEnvelope.wrappedKey),\n },\n ];\n const state = await signPrincipalState(\n await buildPrincipalStateSigningInput({\n principalType: \"organization\",\n principalId: input.organizationId,\n version: 1,\n prevStateHash: null,\n keyEpoch: 1,\n encapsulationPublicKey: bytesToBase64(organizationKem.publicKey),\n keyFingerprint: await toFingerprint(organizationKem.publicKey),\n members: [{ userId: input.userId }],\n memberEnvelopes,\n projection,\n grants: [],\n payloadCiphertext,\n externalAuthority: null,\n signedAt: new Date().toISOString(),\n signerUserId: input.userId,\n signerUserKeyFingerprint,\n }),\n input.signingKeyPair.signingPrivateKey,\n );\n\n return {\n state,\n encryptedPayload: {\n cipherSuite: \"aes-256-gcm\",\n ciphertext: payloadCiphertext,\n ciphertextHash: state.payloadCiphertextHash,\n },\n projection,\n grants: [],\n memberEnvelopes,\n };\n}\n\nasync function createOrganizationPrincipalPolicies(input: {\n encapsulationKeyPair: EncapsulationKeyPair;\n organizationMetadataContainerId: string;\n rootContainerId: string;\n signingKeyPair: SigningKeyPair;\n userId: string;\n}): Promise<OrganizationProvisioningPrincipalPolicies> {\n const organizationId = crypto.randomUUID();\n const signingFingerprint = await toFingerprint(\n input.signingKeyPair.signingPublicKey,\n );\n const initialAdminGroup = await buildInitialGroupPolicyRequest({\n creatorEncapsulationKeyPair: input.encapsulationKeyPair,\n groupId: crypto.randomUUID(),\n grants: [\n { containerId: input.rootContainerId, accessLevel: \"admin\" },\n {\n containerId: input.organizationMetadataContainerId,\n accessLevel: \"admin\",\n },\n ],\n name: \"Admins\",\n builtinRole: \"admins\",\n signerUserId: input.userId,\n signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n const initialMemberGroup = await buildInitialMemberGroupPolicyRequest({\n creatorEncapsulationKeyPair: input.encapsulationKeyPair,\n groupId: crypto.randomUUID(),\n grants: [\n {\n containerId: input.organizationMetadataContainerId,\n accessLevel: \"read\",\n },\n ],\n signerUserId: input.userId,\n signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n const initialOrganizationPolicy = await buildInitialOrganizationPolicyRequest(\n {\n adminGroupId: initialAdminGroup.groupId,\n encapsulationPublicKey: input.encapsulationKeyPair.publicKey,\n groupHeads: await Promise.all([\n groupPolicyMutationHead(initialAdminGroup.initialGroupPolicy),\n groupPolicyMutationHead(initialMemberGroup.initialGroupPolicy),\n ]),\n memberGroupId: initialMemberGroup.groupId,\n organizationId,\n signingKeyPair: input.signingKeyPair,\n userId: input.userId,\n },\n );\n\n return {\n initialAdminGroup,\n initialMemberGroup,\n initialOrganizationPolicy,\n organizationId,\n signingFingerprint,\n };\n}\n\nfunction requireOrganizationProvisioningAuthor(input: {\n readonly organizationId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n readonly userId: string;\n}) {\n const author = resolveDocumentCreateAuthor({\n auth: { organizationId: input.organizationId, userId: input.userId },\n crypto: {\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n },\n });\n if (!author) {\n throw new Error(\n `Organization provisioning document author context is unavailable for user ${input.userId} in organization ${input.organizationId}.`,\n );\n }\n return author;\n}\n\n/** Builds the signed artifacts shared by registration and org creation. */\nexport async function buildOrganizationProvisioningArtifacts(\n input: OrganizationProvisioningArtifactsInput,\n): Promise<OrganizationProvisioningArtifacts> {\n const bootstrap = await createInitialRootMetadataBootstrap(\n input.rootContainerId,\n );\n const organizationMetadataContainerId = crypto.randomUUID();\n const {\n initialAdminGroup,\n initialMemberGroup,\n initialOrganizationPolicy,\n organizationId,\n signingFingerprint,\n } = await createOrganizationPrincipalPolicies({\n encapsulationKeyPair: input.encapsulationKeyPair,\n organizationMetadataContainerId,\n rootContainerId: input.rootContainerId,\n signingKeyPair: input.signingKeyPair,\n userId: input.userId,\n });\n const author = requireOrganizationProvisioningAuthor({\n organizationId,\n signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n userId: input.userId,\n });\n\n const {\n rootContainer,\n rootContainerProjection,\n rootMetadataDocument,\n rootMetadataDocumentRequest,\n } = await buildInitialRootProvisioning({\n adminGroup: initialAdminGroup,\n author,\n bootstrap,\n recipientEncapsulationPublicKey: input.encapsulationKeyPair.publicKey,\n rootContainerId: input.rootContainerId,\n targetSecretKey: input.encapsulationKeyPair.secretKey,\n });\n const rosterProfileBootstrap = await buildInitialRosterProfileBootstrap({\n author,\n encapsulationPublicKey: input.encapsulationKeyPair.publicKey,\n initialAdminGroup,\n rosterProfileNickname: input.rosterProfileNickname,\n rootContainer,\n rootContainerProjection,\n targetSecretKey: input.encapsulationKeyPair.secretKey,\n });\n const organizationMetadataBootstrap =\n await buildInitialOrganizationMetadataBootstrap({\n author,\n containerId: organizationMetadataContainerId,\n initialAdminGroup,\n initialMemberGroup,\n organizationProfileName: input.organizationProfileName,\n rootContainer,\n rootContainerProjection,\n targetSecretKey: input.encapsulationKeyPair.secretKey,\n });\n const systemContainerBootstraps = await Promise.all(\n (input.provisionedSystemContainers ?? []).map((spec) =>\n buildInitialSystemContainerBootstrap({\n author,\n initialAdminGroup,\n rootContainer,\n rootContainerProjection,\n signingPrivateKey: input.signingKeyPair.signingPrivateKey,\n spec,\n targetSecretKey: input.encapsulationKeyPair.secretKey,\n }),\n ),\n );\n\n return {\n replacementAuthorization: null,\n bootstrap,\n initialAdminGroup,\n initialMemberGroup,\n initialOrganizationPolicy,\n initialRootContainer: rootContainer.plan.request,\n organizationId,\n organizationMetadataBootstrap,\n rootContainer,\n rootMetadataDocument,\n rootMetadataDocumentRequest,\n rosterProfileBootstrap,\n systemContainerBootstraps,\n };\n}\n"]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { ContainerSystemSlot } from "../../internal/validators/containerSystemSlot.js";
|
|
2
2
|
import type { CreateOrganizationGroupRequest, ProvisionedDocumentRequest, ProvisionedSystemContainerRequest, RegistrationRequest } from "../../internal/validators/request/index.js";
|
|
3
3
|
import type { OrganizationReplacementAuthorization } from "../../internal/validators/util/index.js";
|
|
4
|
-
import type { buildContainerCreatePlan } from "../containers/
|
|
5
|
-
import type {
|
|
6
|
-
import type { buildMaterializedDocumentCreatePlan } from "../documents/create/index.js";
|
|
4
|
+
import type { buildContainerCreatePlan, buildRootContainerCreatePlan } from "../containers/index.js";
|
|
5
|
+
import type { buildMaterializedDocumentCreatePlan } from "../documents/index.js";
|
|
7
6
|
import type { createInitialRootMetadataBootstrap } from "./rootMetadataBootstrap.js";
|
|
8
7
|
export type InitialRootMetadataDocument = Awaited<ReturnType<typeof buildMaterializedDocumentCreatePlan>>;
|
|
9
8
|
export type InitialRootContainerCreatePlan = Awaited<ReturnType<typeof buildRootContainerCreatePlan>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationProvisioningArtifacts.js","sourceRoot":"","sources":["organizationProvisioningArtifacts.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n CreateOrganizationGroupRequest,\n ProvisionedDocumentRequest,\n ProvisionedSystemContainerRequest,\n RegistrationRequest,\n} from \"@tearleads/validators/request\";\nimport type { OrganizationReplacementAuthorization } from \"@tearleads/validators/util\";\nimport type {
|
|
1
|
+
{"version":3,"file":"organizationProvisioningArtifacts.js","sourceRoot":"","sources":["organizationProvisioningArtifacts.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n CreateOrganizationGroupRequest,\n ProvisionedDocumentRequest,\n ProvisionedSystemContainerRequest,\n RegistrationRequest,\n} from \"@tearleads/validators/request\";\nimport type { OrganizationReplacementAuthorization } from \"@tearleads/validators/util\";\nimport type {\n buildContainerCreatePlan,\n buildRootContainerCreatePlan,\n} from \"../containers\";\nimport type { buildMaterializedDocumentCreatePlan } from \"../documents\";\nimport type { createInitialRootMetadataBootstrap } from \"./rootMetadataBootstrap\";\n\nexport type InitialRootMetadataDocument = Awaited<\n ReturnType<typeof buildMaterializedDocumentCreatePlan>\n>;\n\nexport type InitialRootContainerCreatePlan = Awaited<\n ReturnType<typeof buildRootContainerCreatePlan>\n>;\n\nexport interface InitialSystemContainerCreatePlan {\n containerKey: Uint8Array;\n plan: Awaited<ReturnType<typeof buildContainerCreatePlan>>;\n}\n\nexport interface InitialRosterProfileBootstrap {\n containerId: string;\n containerMetadataDocument: InitialRootMetadataDocument;\n containerMetadataInitialUpdate: Uint8Array;\n containerPlan: InitialSystemContainerCreatePlan;\n containerRequest: ProvisionedSystemContainerRequest;\n profileDocument: InitialRootMetadataDocument;\n profileDocumentInitialUpdate: Uint8Array;\n profileDocumentRequest: ProvisionedDocumentRequest;\n systemSlot: ContainerSystemSlot;\n}\n\nexport interface InitialSystemContainerBootstrap {\n containerId: string;\n containerMetadataDocument: InitialRootMetadataDocument;\n containerMetadataInitialUpdate: Uint8Array;\n containerPlan: InitialSystemContainerCreatePlan;\n containerRequest: ProvisionedSystemContainerRequest;\n icon: string | null;\n name: string;\n systemSlot: ContainerSystemSlot;\n}\n\nexport interface InitialOrganizationMetadataBootstrap {\n containerId: string;\n containerMetadataDocument: InitialRootMetadataDocument;\n containerMetadataInitialUpdate: Uint8Array;\n containerPlan: InitialSystemContainerCreatePlan;\n containerRequest: ProvisionedSystemContainerRequest;\n organizationProfileDocument: InitialRootMetadataDocument;\n organizationProfileDocumentRequest: ProvisionedDocumentRequest;\n organizationProfileSnapshot: string;\n systemSlot: ContainerSystemSlot;\n}\n\nexport interface OrganizationProvisioningArtifacts {\n replacementAuthorization: OrganizationReplacementAuthorization | null;\n bootstrap: Awaited<ReturnType<typeof createInitialRootMetadataBootstrap>>;\n initialAdminGroup: CreateOrganizationGroupRequest;\n initialMemberGroup: CreateOrganizationGroupRequest;\n initialOrganizationPolicy: RegistrationRequest[\"initialOrganizationPolicy\"];\n initialRootContainer: RegistrationRequest[\"initialRootContainer\"];\n organizationId: string;\n organizationMetadataBootstrap: InitialOrganizationMetadataBootstrap;\n rootContainer: InitialRootContainerCreatePlan;\n rootMetadataDocument: InitialRootMetadataDocument;\n rootMetadataDocumentRequest: ProvisionedDocumentRequest;\n rosterProfileBootstrap: InitialRosterProfileBootstrap;\n systemContainerBootstraps: InitialSystemContainerBootstrap[];\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CreateOrganizationGroupRequest } from "../../internal/validators/request/index.js";
|
|
2
|
-
import { type ContainerSystemSlotDefinition } from "../container-contents/
|
|
3
|
-
import { rootContainerWriterProjectionFromCreatePlan } from "../containers/
|
|
4
|
-
import type { resolveDocumentCreateAuthor } from "../documents/
|
|
2
|
+
import { type ContainerSystemSlotDefinition } from "../container-contents/index.js";
|
|
3
|
+
import { rootContainerWriterProjectionFromCreatePlan } from "../containers/index.js";
|
|
4
|
+
import type { resolveDocumentCreateAuthor } from "../documents/index.js";
|
|
5
5
|
import type { InitialOrganizationMetadataBootstrap, InitialRootContainerCreatePlan, InitialRosterProfileBootstrap, InitialSystemContainerBootstrap } from "./organizationProvisioningArtifacts.js";
|
|
6
6
|
import type { createInitialRootMetadataBootstrap } from "./rootMetadataBootstrap.js";
|
|
7
7
|
type InitialRootContainerProjection = ReturnType<typeof rootContainerWriterProjectionFromCreatePlan>;
|