@tearleads/client-sdk 0.1.88 → 0.1.89
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/index.d.ts +1 -1
- package/client/index.js.map +1 -1
- package/client/organizations/index.d.ts +1 -1
- package/client/organizations/index.js +9 -5
- package/client/organizations/index.js.map +1 -1
- package/client/organizations/organizationMemberships.d.ts +12 -1
- package/client/organizations/organizationMemberships.js +36 -2
- package/client/organizations/organizationMemberships.js.map +1 -1
- package/client/organizations/organizationReadModels.d.ts +7 -1
- package/client/organizations/organizationReadModels.js +15 -6
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelPersistence.js +14 -0
- package/data/persistence/organizations/organizationReadModelPersistence.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelProjection.js +12 -0
- package/data/persistence/organizations/organizationReadModelProjection.js.map +1 -1
- package/data/sqlite/schema/index.d.ts +19 -0
- package/data/sqlite/schema/organizationReadModelSchema.js +2 -0
- package/data/sqlite/schema/organizationReadModelSchema.js.map +1 -1
- package/data/sqlite/schema/organizationReadModelTableRegistry.d.ts +19 -0
- package/index.d.ts +1 -1
- package/index.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +10 -0
- package/internal/api-client/ApiClient.js +8 -2
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/routes/organizations/memberships.js +20 -1
- package/internal/api-client/routes/organizations/memberships.js.map +1 -1
- package/internal/crypto/index.d.ts +1 -0
- package/internal/crypto/index.js +1 -0
- package/internal/crypto/index.js.map +1 -1
- package/internal/crypto/organizationLeaveRequest.d.ts +13 -0
- package/internal/crypto/organizationLeaveRequest.js +39 -0
- package/internal/crypto/organizationLeaveRequest.js.map +1 -0
- package/internal/validators/operation/index.d.ts +1 -1
- package/internal/validators/operation/index.js +1 -1
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/organizationMemberships.d.ts +263 -0
- package/internal/validators/operation/organizationMemberships.js +42 -0
- package/internal/validators/operation/organizationMemberships.js.map +1 -1
- package/internal/validators/operation/organizations.d.ts +48 -0
- package/internal/validators/operation/registry.d.ts +3 -1
- package/internal/validators/operation/registry.js +3 -1
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/response/organization.d.ts +82 -0
- package/internal/validators/response/organization.js +6 -0
- package/internal/validators/response/organization.js.map +1 -1
- package/internal/validators/response/organizationMembership.d.ts +12 -2
- package/internal/validators/response/organizationMembership.js +5 -2
- package/internal/validators/response/organizationMembership.js.map +1 -1
- package/internal/validators/response/organizationReadModel.d.ts +60 -0
- package/internal/validators/util/index.d.ts +1 -0
- package/internal/validators/util/index.js +1 -0
- package/internal/validators/util/index.js.map +1 -1
- package/internal/validators/util/organizationLeaveRequest.d.ts +15 -0
- package/internal/validators/util/organizationLeaveRequest.js +22 -0
- package/internal/validators/util/organizationLeaveRequest.js.map +1 -0
- package/package.json +1 -1
- package/workflows/organizations/index.d.ts +2 -0
- package/workflows/organizations/index.js +2 -0
- package/workflows/organizations/index.js.map +1 -1
- package/workflows/organizations/memberships/leaveRequest.d.ts +31 -0
- package/workflows/organizations/memberships/leaveRequest.js +20 -0
- package/workflows/organizations/memberships/leaveRequest.js.map +1 -0
- package/workflows/organizations/memberships/leaveRequestVerification.d.ts +15 -0
- package/workflows/organizations/memberships/leaveRequestVerification.js +46 -0
- package/workflows/organizations/memberships/leaveRequestVerification.js.map +1 -0
package/client/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type { BrowserLocalKeyringOptions, IndexedDbLocalKeyringManifestStoreOpti
|
|
|
18
18
|
export { createBrowserLocalKeyring, createBrowserLocalKeyringManifestStore, createIndexedDbLocalKeyringManifestStore, createIndexedDbWrappingKeyKeystore, createLocalKeyring, createLocalStorageLocalKeyringManifestStore, createMemoryLocalKeyringManifestStore, createMemoryWrappingKeyKeystore, createWebViewLocalKeyring, decodeLocalKeyringSqliteKey, encodeLocalKeyringSqliteKey, LOCAL_KEYRING_MANIFEST_FORMAT, localKeyringScopeKey, normalizeLocalKeyringScope, parseLocalKeyringManifest, serializeLocalKeyringManifest, WRAPPED_LOCAL_SECRET_FORMAT, } from "./localKeyring/index.js";
|
|
19
19
|
export type { LocalKeyringPinCode, PinCodeBrowserLocalKeyringOptions, PinCodeWrappingKeyKeystoreOptions, } from "./localKeyring/localKeyringPinCode.js";
|
|
20
20
|
export { createPinCodeBrowserLocalKeyring, createPinCodeWrappingKeyKeystore, isPinCodeWrappedLocalSecretEnvelope, } from "./localKeyring/localKeyringPinCode.js";
|
|
21
|
-
export type { AbandonOrganizationPolicyMutationInput, AddOrganizationGroupUserInput, DiscardUnreadableOrganizationPolicyMutationInput, ImportedOrganizationUser, LocalOrganizationSummary, OrganizationBilling, OrganizationBillingHistory, OrganizationBillingHistoryEntry, OrganizationBillingManagementUrl, OrganizationBillingView, OrganizationContainerGrant, OrganizationContainerGrants, OrganizationDataUsage, OrganizationDirectory, OrganizationDirectoryAndGroups, OrganizationDirectoryUser, OrganizationGrantRef, OrganizationGroupContainer, OrganizationGroupContainers, OrganizationGroupDetails, OrganizationGroupMember, OrganizationGroupMembers, OrganizationGroupMutationReceipt, OrganizationGroupPolicyHistory, OrganizationGroupSummary, OrganizationMembership, OrganizationMemberships, OrganizationPolicyGrantChange, OrganizationPolicyGroupChange, OrganizationPolicyHistory, OrganizationPolicyHistoryEntry, OrganizationProfile, OrganizationSyncPauseResult, Organizations, OrganizationUserDetail, RemoveOrganizationGroupUserInput, } from "./organizations/index.js";
|
|
21
|
+
export type { AbandonOrganizationPolicyMutationInput, AddOrganizationGroupUserInput, DiscardUnreadableOrganizationPolicyMutationInput, ImportedOrganizationUser, LocalOrganizationSummary, OrganizationBilling, OrganizationBillingHistory, OrganizationBillingHistoryEntry, OrganizationBillingManagementUrl, OrganizationBillingView, OrganizationContainerGrant, OrganizationContainerGrants, OrganizationDataUsage, OrganizationDirectory, OrganizationDirectoryAndGroups, OrganizationDirectoryUser, OrganizationGrantRef, OrganizationGroupContainer, OrganizationGroupContainers, OrganizationGroupDetails, OrganizationGroupMember, OrganizationGroupMembers, OrganizationGroupMutationReceipt, OrganizationGroupPolicyHistory, OrganizationGroupSummary, OrganizationLeaveRequestResult, OrganizationMembership, OrganizationMemberships, OrganizationPolicyGrantChange, OrganizationPolicyGroupChange, OrganizationPolicyHistory, OrganizationPolicyHistoryEntry, OrganizationProfile, OrganizationSyncPauseResult, Organizations, OrganizationUserDetail, RemoveOrganizationGroupUserInput, } from "./organizations/index.js";
|
|
22
22
|
export { Database, type DatabaseListener, type DatabaseOptions, type DatabaseSnapshot, type DatabaseStatus, } from "./runtime/database.js";
|
|
23
23
|
export { Events, type EventsListener, type EventsSnapshot, } from "./runtime/events.js";
|
|
24
24
|
export { createBrowserNetworkStatusSource, Network, type NetworkListener, type NetworkMode, type NetworkStatusSource, } from "./runtime/network.js";
|
package/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EACL,8BAA8B,GAE/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,+BAA+B,EAK/B,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,EAE5B,yBAAyB,GAO1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAyB,KAAK,EAAE,MAAM,SAAS,CAAC;AAgDvD,OAAO,EAAE,sCAAsC,EAAE,MAAM,qBAAqB,CAAC;AAuB7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAUlD,OAAO,EACL,2BAA2B,GAE5B,MAAM,uBAAuB,CAAC;AA6B/B,OAAO,EACL,yBAAyB,EACzB,sCAAsC,EACtC,wCAAwC,EACxC,kCAAkC,EAClC,kBAAkB,EAClB,2CAA2C,EAC3C,qCAAqC,EACrC,+BAA+B,EAC/B,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EAChC,mCAAmC,GACpC,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EACL,8BAA8B,GAE/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,+BAA+B,EAK/B,8BAA8B,GAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,4BAA4B,EAE5B,yBAAyB,GAO1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAyB,KAAK,EAAE,MAAM,SAAS,CAAC;AAgDvD,OAAO,EAAE,sCAAsC,EAAE,MAAM,qBAAqB,CAAC;AAuB7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAUlD,OAAO,EACL,2BAA2B,GAE5B,MAAM,uBAAuB,CAAC;AA6B/B,OAAO,EACL,yBAAyB,EACzB,sCAAsC,EACtC,wCAAwC,EACxC,kCAAkC,EAClC,kBAAkB,EAClB,2CAA2C,EAC3C,qCAAqC,EACrC,+BAA+B,EAC/B,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC3B,6BAA6B,EAC7B,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EACL,gCAAgC,EAChC,gCAAgC,EAChC,mCAAmC,GACpC,MAAM,oCAAoC,CAAC;AAwC5C,OAAO,EACL,QAAQ,GAKT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,MAAM,GAGP,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,gCAAgC,EAChC,OAAO,GAIR,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EACL,eAAe,GAEhB,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EAAE,8CAA8C,EAAE,MAAM,iCAAiC,CAAC","sourcesContent":["export {\n createDomainScope,\n type DomainScope,\n} from \"../data/shared/domainScope\";\nexport type {\n LocalProjectionReconciledDelta,\n LocalProjectionSnapshot,\n} from \"../stores/local-projection\";\nexport {\n enqueueReconciliationForEvents,\n type ReconciliationService,\n} from \"../sync/reconciliation\";\nexport {\n createUnavailableDirectCheckout,\n type DirectCheckoutAppearance,\n type DirectCheckoutCapability,\n type DirectCheckoutConfirmation,\n type DirectCheckoutSession,\n DirectCheckoutUnavailableError,\n} from \"./billing/directCheckout\";\nexport {\n createRevenueCatPurchases,\n createUnavailablePurchases,\n PurchaseAbortedError,\n PurchaseAlreadyOwnedError,\n PurchaseCancelledError,\n PurchaseIdentityPendingError,\n PurchaseProviderStalledError,\n type PurchasesCapability,\n PurchasesUnavailableError,\n type RevenueCatBackend,\n type RevenueCatCustomerInfo,\n type RevenueCatPackage,\n type RevenueCatPurchasesConfig,\n type SyncPurchaseResult,\n type SyncSubscriptionOption,\n} from \"./billing/purchases\";\nexport { type BlobStoreFactory, Blobs } from \"./blobs\";\nexport type {\n BlobInfo,\n BlobInfoAttachmentKind,\n BlobInfoDocumentReference,\n BlobInfoInput,\n BlobInfoList,\n BlobInfoSort,\n BlobInfoSortDirection,\n BlobInfoSortKey,\n ContainerContents,\n ContainerContentsContextValue,\n ContainerContentsStore,\n ContainerContentsStoreOptions,\n ContainerDocumentLinkInput,\n ContainerDocumentLinks,\n ContainerDocumentObjectSyncState,\n ContainerDocumentObjectSyncStatus,\n ContainerDocumentQueries,\n ContainerDocumentSidebarRow,\n ContainerInfo,\n ContainerInfoInput,\n ContainerItemRow,\n ContainerItemSort,\n ContainerItemSortDirection,\n ContainerItemSortKey,\n ContainerNode,\n ContainerShareAccessLevel,\n DocumentAttributionRangesInput,\n DocumentAttributionRangesPage,\n DocumentInfo,\n DocumentInfoInput,\n LinkDocumentToContainerInput,\n MergeDocumentSummary,\n MoveDocumentToContainerInput,\n OpenContainerDocumentInput,\n PendingWriteQueueItem,\n PendingWriteQueueItemStatus,\n PendingWriteQueueObjectKind,\n PendingWriteQueueOperation,\n PendingWriteQueueOperationKind,\n PendingWriteQueueOperationStatus,\n PurgeDocumentInput,\n PurgeDocumentResult,\n SetActiveDocumentContainerInput,\n SetLinkedContainerIdsForDocument,\n UnlinkDocumentFromContainerInput,\n} from \"./containerContents\";\nexport { createContainerDocumentObjectSyncState } from \"./containerContents\";\nexport type {\n DeviceFirst,\n DeviceFirstContainerContents,\n LocalProjectionView,\n} from \"./deviceFirst\";\nexport type {\n DocumentAttachmentStatus,\n DocumentAttachmentUpload,\n DocumentContextValue,\n DocumentList,\n DocumentSort,\n DocumentSortDirection,\n DocumentSortKey,\n DocumentStore,\n DocumentSubscriptionOptions,\n Documents,\n DocumentsRuntime,\n ListDocumentsInput,\n OpenDocumentInput,\n OpenDocumentOptions,\n PersistedDocumentListener,\n} from \"./documents\";\nexport { DEFAULT_DOCUMENT_ID } from \"./documents\";\nexport type { FileSaver, SaveFileRequest } from \"./host/fileSaver\";\nexport type { Logger } from \"./host/logger\";\nexport type {\n Identity,\n IdentityGenerationResult,\n IdentityListener,\n IdentityOptions,\n IdentitySnapshot,\n} from \"./identity\";\nexport {\n IDENTITY_KEY_PACKAGE_FORMAT,\n type IdentityKeyPackage,\n} from \"./identity/keyPackage\";\nexport type {\n ResolvedUserIdentity,\n UserIdentities,\n} from \"./identity/userIdentities\";\nexport type {\n BrowserLocalKeyringOptions,\n IndexedDbLocalKeyringManifestStoreOptions,\n IndexedDbWrappingKeyKeystoreOptions,\n LocalKeyPurpose,\n LocalKeyring,\n LocalKeyringManifest,\n LocalKeyringManifestFormat,\n LocalKeyringManifestStorage,\n LocalKeyringManifestStore,\n LocalKeyringOptions,\n LocalKeyringScope,\n LocalKeyringSession,\n LocalSecretContext,\n LocalStorageLocalKeyringManifestStoreOptions,\n NormalizedLocalKeyringScope,\n UnwrapLocalSecretInput,\n WrapLocalSecretInput,\n WrappedLocalSecretEnvelope,\n WrappedLocalSecretFormat,\n WrappingKeyHandle,\n WrappingKeyKeystore,\n WrappingKeyMaterialStorage,\n} from \"./localKeyring\";\nexport {\n createBrowserLocalKeyring,\n createBrowserLocalKeyringManifestStore,\n createIndexedDbLocalKeyringManifestStore,\n createIndexedDbWrappingKeyKeystore,\n createLocalKeyring,\n createLocalStorageLocalKeyringManifestStore,\n createMemoryLocalKeyringManifestStore,\n createMemoryWrappingKeyKeystore,\n createWebViewLocalKeyring,\n decodeLocalKeyringSqliteKey,\n encodeLocalKeyringSqliteKey,\n LOCAL_KEYRING_MANIFEST_FORMAT,\n localKeyringScopeKey,\n normalizeLocalKeyringScope,\n parseLocalKeyringManifest,\n serializeLocalKeyringManifest,\n WRAPPED_LOCAL_SECRET_FORMAT,\n} from \"./localKeyring\";\nexport type {\n LocalKeyringPinCode,\n PinCodeBrowserLocalKeyringOptions,\n PinCodeWrappingKeyKeystoreOptions,\n} from \"./localKeyring/localKeyringPinCode\";\nexport {\n createPinCodeBrowserLocalKeyring,\n createPinCodeWrappingKeyKeystore,\n isPinCodeWrappedLocalSecretEnvelope,\n} from \"./localKeyring/localKeyringPinCode\";\nexport type {\n AbandonOrganizationPolicyMutationInput,\n AddOrganizationGroupUserInput,\n DiscardUnreadableOrganizationPolicyMutationInput,\n ImportedOrganizationUser,\n LocalOrganizationSummary,\n OrganizationBilling,\n OrganizationBillingHistory,\n OrganizationBillingHistoryEntry,\n OrganizationBillingManagementUrl,\n OrganizationBillingView,\n OrganizationContainerGrant,\n OrganizationContainerGrants,\n OrganizationDataUsage,\n OrganizationDirectory,\n OrganizationDirectoryAndGroups,\n OrganizationDirectoryUser,\n OrganizationGrantRef,\n OrganizationGroupContainer,\n OrganizationGroupContainers,\n OrganizationGroupDetails,\n OrganizationGroupMember,\n OrganizationGroupMembers,\n OrganizationGroupMutationReceipt,\n OrganizationGroupPolicyHistory,\n OrganizationGroupSummary,\n OrganizationLeaveRequestResult,\n OrganizationMembership,\n OrganizationMemberships,\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n OrganizationPolicyHistory,\n OrganizationPolicyHistoryEntry,\n OrganizationProfile,\n OrganizationSyncPauseResult,\n Organizations,\n OrganizationUserDetail,\n RemoveOrganizationGroupUserInput,\n} from \"./organizations\";\nexport {\n Database,\n type DatabaseListener,\n type DatabaseOptions,\n type DatabaseSnapshot,\n type DatabaseStatus,\n} from \"./runtime/database\";\nexport {\n Events,\n type EventsListener,\n type EventsSnapshot,\n} from \"./runtime/events\";\nexport {\n createBrowserNetworkStatusSource,\n Network,\n type NetworkListener,\n type NetworkMode,\n type NetworkStatusSource,\n} from \"./runtime/network\";\nexport type {\n PrincipalHistoryKeyProvider,\n PrincipalHistoryKeyScope,\n} from \"./runtime/principalHistoryProtection\";\nexport {\n SyncBillingGate,\n type SyncBillingGateListener,\n} from \"./runtime/syncBillingGate\";\nexport type {\n SecurityIncident,\n SecurityIncidentListener,\n SecurityIncidentObjectKind,\n SecurityIncidents,\n} from \"./securityIncidents\";\nexport { PurgedOrganizationRecoveryBillingRequiredError } from \"./session/sessionRecoveryErrors\";\nexport type {\n CreateOrganizationOptions,\n Session,\n SessionContext,\n SessionCreateOrganizationResult,\n SessionListener,\n SessionRecoverOrganizationResult,\n SessionRegistrationRefusal,\n SessionRegistrationResult,\n SessionSnapshot,\n UserSession,\n} from \"./session/sessionTypes\";\n"]}
|
|
@@ -2,7 +2,7 @@ import type { ContainerContents } from "../containerContents/index.js";
|
|
|
2
2
|
import type { InternalRuntime } from "../runtime/workflowRuntime.js";
|
|
3
3
|
import { type OrganizationContentReconciler } from "./organizationMemberships.js";
|
|
4
4
|
import type { Organizations } from "./organizationsTypes.js";
|
|
5
|
-
export type { ImportedOrganizationUser, LocalOrganizationSummary, OrganizationBilling, OrganizationBillingHistory, OrganizationBillingHistoryEntry, OrganizationBillingManagementUrl, OrganizationBillingView, OrganizationContainerGrant, OrganizationContainerGrants, OrganizationDataUsage, OrganizationDirectory, OrganizationDirectoryAndGroups, OrganizationDirectoryUser, OrganizationGroupContainer, OrganizationGroupContainers, OrganizationGroupDetails, OrganizationGroupMember, OrganizationGroupMembers, OrganizationGroupPolicyHistory, OrganizationGroupSummary, OrganizationMembership, OrganizationPolicyGrantChange, OrganizationPolicyGroupChange, OrganizationPolicyHistory, OrganizationPolicyHistoryEntry, OrganizationProfile, OrganizationSyncPauseResult, OrganizationUserDetail, } from "../../workflows/organizations/index.js";
|
|
5
|
+
export type { ImportedOrganizationUser, LocalOrganizationSummary, OrganizationBilling, OrganizationBillingHistory, OrganizationBillingHistoryEntry, OrganizationBillingManagementUrl, OrganizationBillingView, OrganizationContainerGrant, OrganizationContainerGrants, OrganizationDataUsage, OrganizationDirectory, OrganizationDirectoryAndGroups, OrganizationDirectoryUser, OrganizationGroupContainer, OrganizationGroupContainers, OrganizationGroupDetails, OrganizationGroupMember, OrganizationGroupMembers, OrganizationGroupPolicyHistory, OrganizationGroupSummary, OrganizationLeaveRequestResult, OrganizationMembership, OrganizationPolicyGrantChange, OrganizationPolicyGroupChange, OrganizationPolicyHistory, OrganizationPolicyHistoryEntry, OrganizationProfile, OrganizationSyncPauseResult, OrganizationUserDetail, } from "../../workflows/organizations/index.js";
|
|
6
6
|
export type { OrganizationContentReconciler, OrganizationMemberships, } from "./organizationMemberships.js";
|
|
7
7
|
export type { OrganizationGroupMutationReceipt, Organizations, } from "./organizationsTypes.js";
|
|
8
8
|
export type { AbandonOrganizationPolicyMutationInput, DiscardUnreadableOrganizationPolicyMutationInput, } from "./principalMutationRecovery.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { runWithSecurityIncidentReporting } from "../../data/keyingProjectionVerification/error.js";
|
|
2
|
-
import { cancelStripeSubscription, checkNativePurchaseEligibility, claimNativeOrganizationSubscription, createStripeCheckout, createStripeCheckoutSession, importOrganizationUser, listLocalOrganizations, loadOrganizationBilling, loadOrganizationBillingHistory, loadOrganizationBillingManagementUrl, loadStripeCheckoutOptions, startOrganizationTrial, updateOrganizationProfile, updateOrganizationRosterEntry, } from "../../workflows/organizations/index.js";
|
|
2
|
+
import { cancelStripeSubscription, checkNativePurchaseEligibility, claimNativeOrganizationSubscription, createStripeCheckout, createStripeCheckoutSession, importOrganizationUser, listLocalOrganizations, loadOrganizationBilling, loadOrganizationBillingHistory, loadOrganizationBillingManagementUrl, loadStripeCheckoutOptions, startOrganizationTrial, updateOrganizationProfile, updateOrganizationRosterEntry, withVerifiedDirectoryUser, } from "../../workflows/organizations/index.js";
|
|
3
3
|
import { createOrganizationDataUsageCoordinator, } from "./organizationDataUsage.js";
|
|
4
4
|
import { loadOrganizationGroupPresentationDetails } from "./organizationGroupPresentation.js";
|
|
5
5
|
import { createOrganizationMemberships, } from "./organizationMemberships.js";
|
|
6
|
-
import { createOrganizationReadModelCoordinator, } from "./organizationReadModels.js";
|
|
6
|
+
import { createOrganizationReadModelCoordinator, leaveRequestSignerResolver, } from "./organizationReadModels.js";
|
|
7
7
|
import { authenticatedOrganizationId, runForOrganization, } from "./organizationWorkflowRuntime.js";
|
|
8
8
|
import { abandonPendingOrganizationPolicyMutation, discardUnreadableOrganizationPolicyMutation, readPendingOrganizationPolicyMutation, retryPendingOrganizationPolicyMutation, } from "./principalMutationRecovery.js";
|
|
9
9
|
import { currentOrganizationMutation } from "./principalMutationScope.js";
|
|
@@ -170,18 +170,22 @@ class OrganizationsService {
|
|
|
170
170
|
loadUserDetail(userId) {
|
|
171
171
|
return this.readModelCoordinator.loadLocalUserDetail(userId);
|
|
172
172
|
}
|
|
173
|
-
updateRosterEntry(userId, profileDocumentId) {
|
|
173
|
+
async updateRosterEntry(userId, profileDocumentId) {
|
|
174
174
|
const runtime = this.runtimeService.workflowInput();
|
|
175
175
|
const organizationId = authenticatedOrganizationId(runtime);
|
|
176
176
|
if (!organizationId || userId.length === 0) {
|
|
177
|
-
return
|
|
177
|
+
return null;
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
const user = await updateOrganizationRosterEntry({
|
|
180
180
|
apiClient: runtime.apiClient,
|
|
181
181
|
organizationId,
|
|
182
182
|
profileDocumentId,
|
|
183
183
|
userId,
|
|
184
184
|
});
|
|
185
|
+
// Callers store this response as directory state, so its leave request
|
|
186
|
+
// passes the same check as one read from the read model.
|
|
187
|
+
return (user &&
|
|
188
|
+
withVerifiedDirectoryUser(organizationId, user, leaveRequestSignerResolver(this.runtimeService, runtime)));
|
|
185
189
|
}
|
|
186
190
|
updateProfile(profileDocumentId) {
|
|
187
191
|
const runtime = this.runtimeService.workflowInput();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gCAAgC,EAAE,MAAM,+CAA+C,CAAC;AACjG,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,EACvB,8BAA8B,EAC9B,oCAAoC,EACpC,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,sCAAsC,GAEvC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,wCAAwC,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EACL,6BAA6B,GAG9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,sCAAsC,GAEvC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,wCAAwC,EAExC,2CAA2C,EAC3C,qCAAqC,EACrC,sCAAsC,GACvC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAEL,0BAA0B,EAC1B,0BAA0B,EAC1B,0BAA0B,EAG1B,+BAA+B,EAC/B,uBAAuB,GACxB,MAAM,sBAAsB,CAAC;AAkD9B,MAAM,UAAU,mBAAmB,CACjC,OAAwB,EACxB,iBAAoC,EACpC,cAAmD;IAEnD,OAAO,IAAI,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,oBAAoB;IAML;IACA;IANV,WAAW,CAA0B;IAC7B,oBAAoB,CAAmC;IACvD,oBAAoB,CAAmC;IAExE,YACmB,cAA+B,EAC/B,iBAAoC,EACrD,cAAmD;QAFlC,mBAAc,GAAd,cAAc,CAAiB;QAC/B,sBAAiB,GAAjB,iBAAiB,CAAmB;QAGrD,IAAI,CAAC,oBAAoB,GAAG,sCAAsC,CAChE,IAAI,CAAC,cAAc,CACpB,CAAC;QACF,IAAI,CAAC,oBAAoB,GAAG,sCAAsC,CAChE,IAAI,CAAC,cAAc,CACpB,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,6BAA6B,CAC9C,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,iBAAiB,EACtB,cAAc,CACf,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAoC;QACvD,OAAO,0BAA0B,CAAC;YAChC,GAAG,KAAK;YACR,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,GAAG,2BAA2B,CAAC,IAAI,CAAC,cAAc,CAAC;SACpD,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB,CAAC,cAAsB;QAC9C,OAAO,qCAAqC,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;IACJ,CAAC;IAED,+BAA+B,CAC7B,KAAuD;QAEvD,OAAO,2CAA2C,CAChD,IAAI,CAAC,cAAc,EACnB,KAAK,CACN,CAAC;IACJ,CAAC;IAED,0BAA0B,CAAC,cAAsB;QAC/C,OAAO,sCAAsC,CAC3C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;IACJ,CAAC;IAED,4BAA4B,CAAC,KAA6C;QACxE,OAAO,wCAAwC,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,OAAO,0BAA0B,CAAC;YAChC,IAAI;YACJ,GAAG,2BAA2B,CAAC,IAAI,CAAC,cAAc,CAAC;SACpD,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,OAAO,0BAA0B,CAAC;YAChC,OAAO;YACP,GAAG,2BAA2B,CAAC,IAAI,CAAC,cAAc,CAAC;SACpD,CAAC,CAAC;IACL,CAAC;IAED,cAAc,CAAC,MAAc;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,OAAO,sBAAsB,CAAC;YAC5B,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;YAC9D,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,WAAW;QACT,OAAO,kBAAkB,CAAC,IAAI,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAC;IAC1E,CAAC;IAED,0BAA0B,CAAC,cAAsB;QAC/C,wEAAwE;QACxE,yEAAyE;QACzE,mCAAmC;QACnC,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,uBAAuB,EACvB,cAAc,CACf,CAAC;IACJ,CAAC;IAED,kBAAkB;QAChB,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,8BAA8B,CAC/B,CAAC;IACJ,CAAC;IAED,wBAAwB;QACtB,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,oCAAoC,CACrC,CAAC;IACJ,CAAC;IAED,yBAAyB,CAAC,cAAuB;QAC/C,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,yBAAyB,EACzB,cAAc,CACf,CAAC;IACJ,CAAC;IAED,oBAAoB,CAAC,cAAuB;QAC1C,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,oBAAoB,EACpB,cAAc,CACf,CAAC;IACJ,CAAC;IAED,2BAA2B,CAAC,SAAiB,EAAE,cAAuB;QACpE,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,CAAC,KAAK,EAAE,EAAE,CAAC,2BAA2B,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC,EAC/D,cAAc,CACf,CAAC;IACJ,CAAC;IAED,wBAAwB;QACtB,OAAO,kBAAkB,CAAC,IAAI,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC;IAC3E,CAAC;IAED,uBAAuB,CACrB,cAAsB,EACtB,KAA8B;QAE9B,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,CAAC,KAAK,EAAE,EAAE,CAAC,mCAAmC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,EACnE,cAAc,CACf,CAAC;IACJ,CAAC;IAED,8BAA8B,CAC5B,cAAsB,EACtB,KAA8B;QAE9B,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,CAAC,KAAK,EAAE,EAAE,CAAC,8BAA8B,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,CAAC,EAC9D,cAAc,CACf,CAAC;IACJ,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,sBAAsB;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,OAAO,gCAAgC,CACrC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EACnC;YACE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;YACrC,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,mCAAmC;YAC9C,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;SAC5C,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,CAC5C,CAAC;IACJ,CAAC;IAED,mCAAmC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,OAAO,gCAAgC,CACrC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EACnC;YACE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;YACrC,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,kDAAkD;YAC7D,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;SAC5C,EACD,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,sBAAsB,EAAE,CACzD,CAAC;IACJ,CAAC;IAED,2BAA2B;QACzB,OAAO,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,gBAAgB,CAAC,OAAe;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,MAAM,cAAc,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,OAAO,CAAC,SAAS,CAAC,4BAA4B,CACnD,cAAc,EACd,OAAO,CACR,CAAC;IACJ,CAAC;IAED,4BAA4B,CAAC,OAAe,EAAE,aAAsB;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,OAAO,gCAAgC,CACrC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EACnC;YACE,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,yBAAyB;YACpC,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;SAC5C,EACD,GAAG,EAAE,CACH,wCAAwC,CAAC;YACvC,OAAO;YACP,aAAa;YACb,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,OAAO;SACR,CAAC,CACL,CAAC;IACJ,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,oBAAoB,CAAC,eAAe,EAAE,CAAC;IACrD,CAAC;IAED,mBAAmB,CAAC,OAAe;QACjC,OAAO,IAAI,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,sBAAsB;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACvC,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,sBAAsB,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,iBAAiB,CAAC,aAAsB;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,OAAO,gCAAgC,CACrC,OAAO,CAAC,IAAI,CAAC,sBAAsB,EACnC;YACE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;YACrC,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,kCAAkC;YAC7C,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc;SAC5C,EACD,GAAG,EAAE,CACH,IAAI,CAAC,oBAAoB,CAAC,6BAA6B,CACrD,SAAS,EACT,aAAa,CACd,CACJ,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,MAAc;QAC3B,OAAO,IAAI,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED,iBAAiB,CAAC,MAAc,EAAE,iBAAgC;QAChE,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,MAAM,cAAc,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,6BAA6B,CAAC;YACnC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,cAAc;YACd,iBAAiB;YACjB,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,aAAa,CAAC,iBAAgC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QACpD,MAAM,cAAc,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,OAAO,yBAAyB,CAAC;YAC/B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,cAAc;YACd,iBAAiB;SAClB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,KAAuC;QAC/D,OAAO,+BAA+B,CAAC;YACrC,GAAG,KAAK;YACR,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,GAAG,2BAA2B,CAAC,IAAI,CAAC,cAAc,CAAC;SACpD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAA2B;QAC3C,OAAO,uBAAuB,CAAC;YAC7B,GAAG,KAAK;YACR,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,GAAG,2BAA2B,CAAC,IAAI,CAAC,cAAc,CAAC;SACpD,CAAC,CAAC;IACL,CAAC;IAED,UAAU,CAAC,cAAuB;QAChC,OAAO,kBAAkB,CACvB,IAAI,CAAC,cAAc,EACnB,sBAAsB,EACtB,cAAc,CACf,CAAC;IACJ,CAAC;CACF","sourcesContent":["import type { NativeSubscriptionStore } from \"@tearleads/validators/billing\";\nimport { runWithSecurityIncidentReporting } from \"../../data/keyingProjectionVerification/error\";\nimport {\n cancelStripeSubscription,\n checkNativePurchaseEligibility,\n claimNativeOrganizationSubscription,\n createStripeCheckout,\n createStripeCheckoutSession,\n importOrganizationUser,\n listLocalOrganizations,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n loadStripeCheckoutOptions,\n startOrganizationTrial,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n} from \"../../workflows/organizations\";\nimport type { ContainerContents } from \"../containerContents\";\nimport type { InternalRuntime } from \"../runtime/workflowRuntime\";\nimport {\n createOrganizationDataUsageCoordinator,\n type OrganizationDataUsageCoordinator,\n} from \"./organizationDataUsage\";\nimport { loadOrganizationGroupPresentationDetails } from \"./organizationGroupPresentation\";\nimport {\n createOrganizationMemberships,\n type OrganizationContentReconciler,\n type OrganizationMemberships,\n} from \"./organizationMemberships\";\nimport {\n createOrganizationReadModelCoordinator,\n type OrganizationReadModelCoordinator,\n} from \"./organizationReadModels\";\nimport type { Organizations } from \"./organizationsTypes\";\nimport {\n authenticatedOrganizationId,\n runForOrganization,\n} from \"./organizationWorkflowRuntime\";\nimport {\n type AbandonOrganizationPolicyMutationInput,\n abandonPendingOrganizationPolicyMutation,\n type DiscardUnreadableOrganizationPolicyMutationInput,\n discardUnreadableOrganizationPolicyMutation,\n readPendingOrganizationPolicyMutation,\n retryPendingOrganizationPolicyMutation,\n} from \"./principalMutationRecovery\";\nimport { currentOrganizationMutation } from \"./principalMutationScope\";\nimport {\n type AddOrganizationGroupUserInput,\n addUserToOrganizationGroup,\n createGroupForOrganization,\n deleteGroupForOrganization,\n type OrganizationGrantRef,\n type RemoveOrganizationGroupUserInput,\n removeUserFromOrganizationGroup,\n revokeOrganizationGrant,\n} from \"./principalMutations\";\n\nexport type {\n ImportedOrganizationUser,\n LocalOrganizationSummary,\n OrganizationBilling,\n OrganizationBillingHistory,\n OrganizationBillingHistoryEntry,\n OrganizationBillingManagementUrl,\n OrganizationBillingView,\n OrganizationContainerGrant,\n OrganizationContainerGrants,\n OrganizationDataUsage,\n OrganizationDirectory,\n OrganizationDirectoryAndGroups,\n OrganizationDirectoryUser,\n OrganizationGroupContainer,\n OrganizationGroupContainers,\n OrganizationGroupDetails,\n OrganizationGroupMember,\n OrganizationGroupMembers,\n OrganizationGroupPolicyHistory,\n OrganizationGroupSummary,\n OrganizationMembership,\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n OrganizationPolicyHistory,\n OrganizationPolicyHistoryEntry,\n OrganizationProfile,\n OrganizationSyncPauseResult,\n OrganizationUserDetail,\n} from \"../../workflows/organizations\";\nexport type {\n OrganizationContentReconciler,\n OrganizationMemberships,\n} from \"./organizationMemberships\";\nexport type {\n OrganizationGroupMutationReceipt,\n Organizations,\n} from \"./organizationsTypes\";\nexport type {\n AbandonOrganizationPolicyMutationInput,\n DiscardUnreadableOrganizationPolicyMutationInput,\n} from \"./principalMutationRecovery\";\nexport type {\n AddOrganizationGroupUserInput,\n OrganizationGrantRef,\n RemoveOrganizationGroupUserInput,\n} from \"./principalMutations\";\n\nexport function createOrganizations(\n runtime: InternalRuntime,\n containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n): Organizations {\n return new OrganizationsService(runtime, containerContents, openReconciler);\n}\n\nclass OrganizationsService implements Organizations {\n readonly memberships: OrganizationMemberships;\n private readonly dataUsageCoordinator: OrganizationDataUsageCoordinator;\n private readonly readModelCoordinator: OrganizationReadModelCoordinator;\n\n constructor(\n private readonly runtimeService: InternalRuntime,\n private readonly containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n ) {\n this.dataUsageCoordinator = createOrganizationDataUsageCoordinator(\n this.runtimeService,\n );\n this.readModelCoordinator = createOrganizationReadModelCoordinator(\n this.runtimeService,\n );\n this.memberships = createOrganizationMemberships(\n this.runtimeService,\n this.containerContents,\n openReconciler,\n );\n }\n\n async addUserToGroup(input: AddOrganizationGroupUserInput) {\n return addUserToOrganizationGroup({\n ...input,\n containerContents: this.containerContents,\n readModelCoordinator: this.readModelCoordinator,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n readPendingPolicyMutation(organizationId: string) {\n return readPendingOrganizationPolicyMutation(\n this.runtimeService,\n organizationId,\n );\n }\n\n discardUnreadablePolicyMutation(\n input: DiscardUnreadableOrganizationPolicyMutationInput,\n ) {\n return discardUnreadableOrganizationPolicyMutation(\n this.runtimeService,\n input,\n );\n }\n\n retryPendingPolicyMutation(organizationId: string) {\n return retryPendingOrganizationPolicyMutation(\n this.runtimeService,\n organizationId,\n );\n }\n\n abandonPendingPolicyMutation(input: AbandonOrganizationPolicyMutationInput) {\n return abandonPendingOrganizationPolicyMutation(this.runtimeService, input);\n }\n\n createGroup(name: string) {\n return createGroupForOrganization({\n name,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n deleteGroup(groupId: string) {\n return deleteGroupForOrganization({\n groupId,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n importUserById(userId: string) {\n const runtime = this.runtimeService.workflowInput();\n return importOrganizationUser({\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n userId,\n });\n }\n\n loadBilling() {\n return runForOrganization(this.runtimeService, loadOrganizationBilling);\n }\n\n loadBillingForOrganization(organizationId: string) {\n // Gated on an authenticated session rather than on the target being the\n // active org. The server still enforces membership, so an org the caller\n // cannot reach resolves to `null`.\n return runForOrganization(\n this.runtimeService,\n loadOrganizationBilling,\n organizationId,\n );\n }\n\n loadBillingHistory() {\n return runForOrganization(\n this.runtimeService,\n loadOrganizationBillingHistory,\n );\n }\n\n loadBillingManagementUrl() {\n return runForOrganization(\n this.runtimeService,\n loadOrganizationBillingManagementUrl,\n );\n }\n\n loadStripeCheckoutOptions(organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n loadStripeCheckoutOptions,\n organizationId,\n );\n }\n\n createStripeCheckout(organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n createStripeCheckout,\n organizationId,\n );\n }\n\n createStripeCheckoutSession(returnUrl: string, organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n (input) => createStripeCheckoutSession({ ...input, returnUrl }),\n organizationId,\n );\n }\n\n cancelStripeSubscription() {\n return runForOrganization(this.runtimeService, cancelStripeSubscription);\n }\n\n claimNativeSubscription(\n organizationId: string,\n store: NativeSubscriptionStore,\n ) {\n return runForOrganization(\n this.runtimeService,\n (input) => claimNativeOrganizationSubscription({ ...input, store }),\n organizationId,\n );\n }\n\n checkNativePurchaseEligibility(\n organizationId: string,\n store: NativeSubscriptionStore,\n ) {\n return runForOrganization(\n this.runtimeService,\n (input) => checkNativePurchaseEligibility({ ...input, store }),\n organizationId,\n );\n }\n\n loadDataUsage() {\n return this.dataUsageCoordinator.reconcile();\n }\n\n loadLocalDataUsage() {\n return this.dataUsageCoordinator.loadLocal();\n }\n\n loadDirectoryAndGroups() {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: runtime.auth.organizationId,\n objectKind: \"principal\",\n operation: \"organization.read_model.reconcile\",\n organizationId: runtime.auth.organizationId,\n },\n () => this.readModelCoordinator.reconcile(),\n );\n }\n\n loadDirectoryAndGroupsAfterMutation() {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: runtime.auth.organizationId,\n objectKind: \"principal\",\n operation: \"organization.read_model.reconcile_after_mutation\",\n organizationId: runtime.auth.organizationId,\n },\n () => this.readModelCoordinator.reconcileAfterMutation(),\n );\n }\n\n loadLocalDirectoryAndGroups() {\n return this.readModelCoordinator.loadLocal();\n }\n\n loadGroupMembers(groupId: string) {\n const runtime = this.runtimeService.workflowInput();\n const organizationId = authenticatedOrganizationId(runtime);\n if (!organizationId || groupId.length === 0) {\n return Promise.resolve(null);\n }\n\n return runtime.apiClient.listOrganizationGroupMembers(\n organizationId,\n groupId,\n );\n }\n\n loadGroupPresentationDetails(groupId: string, beforeVersion?: number) {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: groupId,\n objectKind: \"principal\",\n operation: \"group.presentation.load\",\n organizationId: runtime.auth.organizationId,\n },\n () =>\n loadOrganizationGroupPresentationDetails({\n groupId,\n beforeVersion,\n readModelCoordinator: this.readModelCoordinator,\n runtime,\n }),\n );\n }\n\n loadGrants() {\n return this.readModelCoordinator.loadLocalGrants();\n }\n\n loadGroupContainers(groupId: string) {\n return this.readModelCoordinator.loadLocalGroupContainers(groupId);\n }\n\n listLocalOrganizations() {\n const runtime = this.runtimeService.workflowInput();\n if (runtime.infra.dbStatus !== \"ready\") {\n return Promise.resolve([]);\n }\n\n return listLocalOrganizations({ execSql: runtime.infra.execSql });\n }\n\n loadPolicyHistory(beforeVersion?: number) {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: runtime.auth.organizationId,\n objectKind: \"principal\",\n operation: \"organization.policy_history.load\",\n organizationId: runtime.auth.organizationId,\n },\n () =>\n this.readModelCoordinator.loadOrganizationPolicyHistory(\n undefined,\n beforeVersion,\n ),\n );\n }\n\n loadUserDetail(userId: string) {\n return this.readModelCoordinator.loadLocalUserDetail(userId);\n }\n\n updateRosterEntry(userId: string, profileDocumentId: string | null) {\n const runtime = this.runtimeService.workflowInput();\n const organizationId = authenticatedOrganizationId(runtime);\n if (!organizationId || userId.length === 0) {\n return Promise.resolve(null);\n }\n\n return updateOrganizationRosterEntry({\n apiClient: runtime.apiClient,\n organizationId,\n profileDocumentId,\n userId,\n });\n }\n\n updateProfile(profileDocumentId: string | null) {\n const runtime = this.runtimeService.workflowInput();\n const organizationId = authenticatedOrganizationId(runtime);\n if (!organizationId) {\n return Promise.resolve(null);\n }\n\n return updateOrganizationProfile({\n apiClient: runtime.apiClient,\n organizationId,\n profileDocumentId,\n });\n }\n\n async removeUserFromGroup(input: RemoveOrganizationGroupUserInput) {\n return removeUserFromOrganizationGroup({\n ...input,\n containerContents: this.containerContents,\n readModelCoordinator: this.readModelCoordinator,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n async revokeGrant(grant: OrganizationGrantRef) {\n return revokeOrganizationGrant({\n ...grant,\n containerContents: this.containerContents,\n readModelCoordinator: this.readModelCoordinator,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n startTrial(organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n startOrganizationTrial,\n organizationId,\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NativeSubscriptionStore } from \"@tearleads/validators/billing\";\nimport { runWithSecurityIncidentReporting } from \"../../data/keyingProjectionVerification/error\";\nimport {\n cancelStripeSubscription,\n checkNativePurchaseEligibility,\n claimNativeOrganizationSubscription,\n createStripeCheckout,\n createStripeCheckoutSession,\n importOrganizationUser,\n listLocalOrganizations,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n loadStripeCheckoutOptions,\n startOrganizationTrial,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n withVerifiedDirectoryUser,\n} from \"../../workflows/organizations\";\nimport type { ContainerContents } from \"../containerContents\";\nimport type { InternalRuntime } from \"../runtime/workflowRuntime\";\nimport {\n createOrganizationDataUsageCoordinator,\n type OrganizationDataUsageCoordinator,\n} from \"./organizationDataUsage\";\nimport { loadOrganizationGroupPresentationDetails } from \"./organizationGroupPresentation\";\nimport {\n createOrganizationMemberships,\n type OrganizationContentReconciler,\n type OrganizationMemberships,\n} from \"./organizationMemberships\";\nimport {\n createOrganizationReadModelCoordinator,\n leaveRequestSignerResolver,\n type OrganizationReadModelCoordinator,\n} from \"./organizationReadModels\";\nimport type { Organizations } from \"./organizationsTypes\";\nimport {\n authenticatedOrganizationId,\n runForOrganization,\n} from \"./organizationWorkflowRuntime\";\nimport {\n type AbandonOrganizationPolicyMutationInput,\n abandonPendingOrganizationPolicyMutation,\n type DiscardUnreadableOrganizationPolicyMutationInput,\n discardUnreadableOrganizationPolicyMutation,\n readPendingOrganizationPolicyMutation,\n retryPendingOrganizationPolicyMutation,\n} from \"./principalMutationRecovery\";\nimport { currentOrganizationMutation } from \"./principalMutationScope\";\nimport {\n type AddOrganizationGroupUserInput,\n addUserToOrganizationGroup,\n createGroupForOrganization,\n deleteGroupForOrganization,\n type OrganizationGrantRef,\n type RemoveOrganizationGroupUserInput,\n removeUserFromOrganizationGroup,\n revokeOrganizationGrant,\n} from \"./principalMutations\";\n\nexport type {\n ImportedOrganizationUser,\n LocalOrganizationSummary,\n OrganizationBilling,\n OrganizationBillingHistory,\n OrganizationBillingHistoryEntry,\n OrganizationBillingManagementUrl,\n OrganizationBillingView,\n OrganizationContainerGrant,\n OrganizationContainerGrants,\n OrganizationDataUsage,\n OrganizationDirectory,\n OrganizationDirectoryAndGroups,\n OrganizationDirectoryUser,\n OrganizationGroupContainer,\n OrganizationGroupContainers,\n OrganizationGroupDetails,\n OrganizationGroupMember,\n OrganizationGroupMembers,\n OrganizationGroupPolicyHistory,\n OrganizationGroupSummary,\n OrganizationLeaveRequestResult,\n OrganizationMembership,\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n OrganizationPolicyHistory,\n OrganizationPolicyHistoryEntry,\n OrganizationProfile,\n OrganizationSyncPauseResult,\n OrganizationUserDetail,\n} from \"../../workflows/organizations\";\nexport type {\n OrganizationContentReconciler,\n OrganizationMemberships,\n} from \"./organizationMemberships\";\nexport type {\n OrganizationGroupMutationReceipt,\n Organizations,\n} from \"./organizationsTypes\";\nexport type {\n AbandonOrganizationPolicyMutationInput,\n DiscardUnreadableOrganizationPolicyMutationInput,\n} from \"./principalMutationRecovery\";\nexport type {\n AddOrganizationGroupUserInput,\n OrganizationGrantRef,\n RemoveOrganizationGroupUserInput,\n} from \"./principalMutations\";\n\nexport function createOrganizations(\n runtime: InternalRuntime,\n containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n): Organizations {\n return new OrganizationsService(runtime, containerContents, openReconciler);\n}\n\nclass OrganizationsService implements Organizations {\n readonly memberships: OrganizationMemberships;\n private readonly dataUsageCoordinator: OrganizationDataUsageCoordinator;\n private readonly readModelCoordinator: OrganizationReadModelCoordinator;\n\n constructor(\n private readonly runtimeService: InternalRuntime,\n private readonly containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n ) {\n this.dataUsageCoordinator = createOrganizationDataUsageCoordinator(\n this.runtimeService,\n );\n this.readModelCoordinator = createOrganizationReadModelCoordinator(\n this.runtimeService,\n );\n this.memberships = createOrganizationMemberships(\n this.runtimeService,\n this.containerContents,\n openReconciler,\n );\n }\n\n async addUserToGroup(input: AddOrganizationGroupUserInput) {\n return addUserToOrganizationGroup({\n ...input,\n containerContents: this.containerContents,\n readModelCoordinator: this.readModelCoordinator,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n readPendingPolicyMutation(organizationId: string) {\n return readPendingOrganizationPolicyMutation(\n this.runtimeService,\n organizationId,\n );\n }\n\n discardUnreadablePolicyMutation(\n input: DiscardUnreadableOrganizationPolicyMutationInput,\n ) {\n return discardUnreadableOrganizationPolicyMutation(\n this.runtimeService,\n input,\n );\n }\n\n retryPendingPolicyMutation(organizationId: string) {\n return retryPendingOrganizationPolicyMutation(\n this.runtimeService,\n organizationId,\n );\n }\n\n abandonPendingPolicyMutation(input: AbandonOrganizationPolicyMutationInput) {\n return abandonPendingOrganizationPolicyMutation(this.runtimeService, input);\n }\n\n createGroup(name: string) {\n return createGroupForOrganization({\n name,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n deleteGroup(groupId: string) {\n return deleteGroupForOrganization({\n groupId,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n importUserById(userId: string) {\n const runtime = this.runtimeService.workflowInput();\n return importOrganizationUser({\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n userId,\n });\n }\n\n loadBilling() {\n return runForOrganization(this.runtimeService, loadOrganizationBilling);\n }\n\n loadBillingForOrganization(organizationId: string) {\n // Gated on an authenticated session rather than on the target being the\n // active org. The server still enforces membership, so an org the caller\n // cannot reach resolves to `null`.\n return runForOrganization(\n this.runtimeService,\n loadOrganizationBilling,\n organizationId,\n );\n }\n\n loadBillingHistory() {\n return runForOrganization(\n this.runtimeService,\n loadOrganizationBillingHistory,\n );\n }\n\n loadBillingManagementUrl() {\n return runForOrganization(\n this.runtimeService,\n loadOrganizationBillingManagementUrl,\n );\n }\n\n loadStripeCheckoutOptions(organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n loadStripeCheckoutOptions,\n organizationId,\n );\n }\n\n createStripeCheckout(organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n createStripeCheckout,\n organizationId,\n );\n }\n\n createStripeCheckoutSession(returnUrl: string, organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n (input) => createStripeCheckoutSession({ ...input, returnUrl }),\n organizationId,\n );\n }\n\n cancelStripeSubscription() {\n return runForOrganization(this.runtimeService, cancelStripeSubscription);\n }\n\n claimNativeSubscription(\n organizationId: string,\n store: NativeSubscriptionStore,\n ) {\n return runForOrganization(\n this.runtimeService,\n (input) => claimNativeOrganizationSubscription({ ...input, store }),\n organizationId,\n );\n }\n\n checkNativePurchaseEligibility(\n organizationId: string,\n store: NativeSubscriptionStore,\n ) {\n return runForOrganization(\n this.runtimeService,\n (input) => checkNativePurchaseEligibility({ ...input, store }),\n organizationId,\n );\n }\n\n loadDataUsage() {\n return this.dataUsageCoordinator.reconcile();\n }\n\n loadLocalDataUsage() {\n return this.dataUsageCoordinator.loadLocal();\n }\n\n loadDirectoryAndGroups() {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: runtime.auth.organizationId,\n objectKind: \"principal\",\n operation: \"organization.read_model.reconcile\",\n organizationId: runtime.auth.organizationId,\n },\n () => this.readModelCoordinator.reconcile(),\n );\n }\n\n loadDirectoryAndGroupsAfterMutation() {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: runtime.auth.organizationId,\n objectKind: \"principal\",\n operation: \"organization.read_model.reconcile_after_mutation\",\n organizationId: runtime.auth.organizationId,\n },\n () => this.readModelCoordinator.reconcileAfterMutation(),\n );\n }\n\n loadLocalDirectoryAndGroups() {\n return this.readModelCoordinator.loadLocal();\n }\n\n loadGroupMembers(groupId: string) {\n const runtime = this.runtimeService.workflowInput();\n const organizationId = authenticatedOrganizationId(runtime);\n if (!organizationId || groupId.length === 0) {\n return Promise.resolve(null);\n }\n\n return runtime.apiClient.listOrganizationGroupMembers(\n organizationId,\n groupId,\n );\n }\n\n loadGroupPresentationDetails(groupId: string, beforeVersion?: number) {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: groupId,\n objectKind: \"principal\",\n operation: \"group.presentation.load\",\n organizationId: runtime.auth.organizationId,\n },\n () =>\n loadOrganizationGroupPresentationDetails({\n groupId,\n beforeVersion,\n readModelCoordinator: this.readModelCoordinator,\n runtime,\n }),\n );\n }\n\n loadGrants() {\n return this.readModelCoordinator.loadLocalGrants();\n }\n\n loadGroupContainers(groupId: string) {\n return this.readModelCoordinator.loadLocalGroupContainers(groupId);\n }\n\n listLocalOrganizations() {\n const runtime = this.runtimeService.workflowInput();\n if (runtime.infra.dbStatus !== \"ready\") {\n return Promise.resolve([]);\n }\n\n return listLocalOrganizations({ execSql: runtime.infra.execSql });\n }\n\n loadPolicyHistory(beforeVersion?: number) {\n const runtime = this.runtimeService.workflowInput();\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: runtime.auth.organizationId,\n objectKind: \"principal\",\n operation: \"organization.policy_history.load\",\n organizationId: runtime.auth.organizationId,\n },\n () =>\n this.readModelCoordinator.loadOrganizationPolicyHistory(\n undefined,\n beforeVersion,\n ),\n );\n }\n\n loadUserDetail(userId: string) {\n return this.readModelCoordinator.loadLocalUserDetail(userId);\n }\n\n async updateRosterEntry(userId: string, profileDocumentId: string | null) {\n const runtime = this.runtimeService.workflowInput();\n const organizationId = authenticatedOrganizationId(runtime);\n if (!organizationId || userId.length === 0) {\n return null;\n }\n\n const user = await updateOrganizationRosterEntry({\n apiClient: runtime.apiClient,\n organizationId,\n profileDocumentId,\n userId,\n });\n // Callers store this response as directory state, so its leave request\n // passes the same check as one read from the read model.\n return (\n user &&\n withVerifiedDirectoryUser(\n organizationId,\n user,\n leaveRequestSignerResolver(this.runtimeService, runtime),\n )\n );\n }\n\n updateProfile(profileDocumentId: string | null) {\n const runtime = this.runtimeService.workflowInput();\n const organizationId = authenticatedOrganizationId(runtime);\n if (!organizationId) {\n return Promise.resolve(null);\n }\n\n return updateOrganizationProfile({\n apiClient: runtime.apiClient,\n organizationId,\n profileDocumentId,\n });\n }\n\n async removeUserFromGroup(input: RemoveOrganizationGroupUserInput) {\n return removeUserFromOrganizationGroup({\n ...input,\n containerContents: this.containerContents,\n readModelCoordinator: this.readModelCoordinator,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n async revokeGrant(grant: OrganizationGrantRef) {\n return revokeOrganizationGrant({\n ...grant,\n containerContents: this.containerContents,\n readModelCoordinator: this.readModelCoordinator,\n ...currentOrganizationMutation(this.runtimeService),\n });\n }\n\n startTrial(organizationId?: string) {\n return runForOrganization(\n this.runtimeService,\n startOrganizationTrial,\n organizationId,\n );\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type OrganizationMembership, type OrganizationSyncPauseResult } from "../../workflows/organizations/index.js";
|
|
1
|
+
import { type OrganizationLeaveRequestResult, type OrganizationMembership, type OrganizationSyncPauseResult } from "../../workflows/organizations/index.js";
|
|
2
2
|
import { type DomainScope } from "../../workflows/sync/index.js";
|
|
3
3
|
import { type ContainerContents } from "../containerContents/index.js";
|
|
4
4
|
import type { InternalRuntime } from "../runtime/workflowRuntime.js";
|
|
@@ -11,10 +11,21 @@ export interface OrganizationMemberships {
|
|
|
11
11
|
refresh(): Promise<OrganizationMembership[] | null>;
|
|
12
12
|
/** Pauses or resumes one organization for all of the user's devices. */
|
|
13
13
|
setSyncPaused(organizationId: string, paused: boolean): Promise<OrganizationSyncPauseResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Asks the organization's administrators to remove the user, or withdraws
|
|
16
|
+
* that request. Signed with the user's identity key; an administrator still
|
|
17
|
+
* has to approve it.
|
|
18
|
+
*/
|
|
19
|
+
setLeaveRequested(organizationId: string, requested: boolean): Promise<OrganizationLeaveRequestResult>;
|
|
14
20
|
/** The organizations paused on this device, read from local storage. */
|
|
15
21
|
loadPausedOrganizationIds(): Promise<ReadonlySet<string>>;
|
|
16
22
|
/** Notifies when the paused set for the current scope changes. */
|
|
17
23
|
subscribeToSyncPauses(listener: () => void): () => void;
|
|
24
|
+
/**
|
|
25
|
+
* Hands each membership list a refresh reads for the current scope, so a
|
|
26
|
+
* choice made on another device reaches every view of it.
|
|
27
|
+
*/
|
|
28
|
+
subscribeToMemberships(listener: (memberships: readonly OrganizationMembership[]) => void): () => void;
|
|
18
29
|
}
|
|
19
30
|
/**
|
|
20
31
|
* The scope's document reconciler. Containers it reconciled before a pause
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { refreshOrganizationMemberships, setOrganizationSyncPaused, } from "../../workflows/organizations/index.js";
|
|
1
|
+
import { refreshOrganizationMemberships, setOrganizationLeaveRequested, setOrganizationSyncPaused, } from "../../workflows/organizations/index.js";
|
|
2
2
|
import { getOrCreateOrganizationSyncPauses, hasDomainSyncCoordinatorPendingWork, requestAllDomainSyncLanes, subscribeToDomainSyncCoordinator, waitForDomainSyncCoordinatorToSettle, } from "../../workflows/sync/index.js";
|
|
3
3
|
import { carriesLocalWrites, } from "../containerContents/index.js";
|
|
4
4
|
// Long enough for a typical upload burst, short enough to answer a tap.
|
|
5
5
|
const PAUSE_FLUSH_TIMEOUT_MS = 10_000;
|
|
6
|
+
const membershipListenersByScope = new WeakMap();
|
|
6
7
|
const settleRetriesByScope = new WeakMap();
|
|
7
8
|
// One retry per scope: it runs whenever the scope's sync lanes go idle and
|
|
8
9
|
// stops once it reports the work done.
|
|
@@ -99,7 +100,13 @@ export function createOrganizationMemberships(runtimeService, containerContents,
|
|
|
99
100
|
const runtime = runtimeService.workflowInput();
|
|
100
101
|
if (!canReachServer(runtime))
|
|
101
102
|
return null;
|
|
102
|
-
|
|
103
|
+
const memberships = await refreshOrganizationMemberships(membershipInput(runtime));
|
|
104
|
+
const listeners = membershipListenersByScope.get(runtime.state.domainScope);
|
|
105
|
+
if (memberships && listeners) {
|
|
106
|
+
for (const listener of [...listeners])
|
|
107
|
+
listener(memberships);
|
|
108
|
+
}
|
|
109
|
+
return memberships;
|
|
103
110
|
},
|
|
104
111
|
async setSyncPaused(organizationId, paused) {
|
|
105
112
|
const runtime = runtimeService.workflowInput();
|
|
@@ -116,6 +123,24 @@ export function createOrganizationMemberships(runtimeService, containerContents,
|
|
|
116
123
|
paused,
|
|
117
124
|
});
|
|
118
125
|
},
|
|
126
|
+
async setLeaveRequested(organizationId, requested) {
|
|
127
|
+
const runtime = runtimeService.workflowInput();
|
|
128
|
+
const { userId } = runtime.auth;
|
|
129
|
+
const { signingKeyPair } = runtime.crypto;
|
|
130
|
+
if (!canReachServer(runtime) || !userId || !signingKeyPair) {
|
|
131
|
+
return {
|
|
132
|
+
httpStatus: null,
|
|
133
|
+
message: "Connect to ask to leave an organization.",
|
|
134
|
+
status: "failed",
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return setOrganizationLeaveRequested({
|
|
138
|
+
apiClient: runtime.apiClient,
|
|
139
|
+
organizationId,
|
|
140
|
+
requested,
|
|
141
|
+
signer: { signingKeyPair, userId },
|
|
142
|
+
});
|
|
143
|
+
},
|
|
119
144
|
async loadPausedOrganizationIds() {
|
|
120
145
|
const runtime = runtimeService.workflowInput();
|
|
121
146
|
if (runtime.infra.dbStatus !== "ready")
|
|
@@ -127,6 +152,15 @@ export function createOrganizationMemberships(runtimeService, containerContents,
|
|
|
127
152
|
subscribeToSyncPauses(listener) {
|
|
128
153
|
return getOrCreateOrganizationSyncPauses(runtimeService.workflowInput().state.domainScope).subscribe(listener);
|
|
129
154
|
},
|
|
155
|
+
subscribeToMemberships(listener) {
|
|
156
|
+
const { domainScope } = runtimeService.workflowInput().state;
|
|
157
|
+
const listeners = membershipListenersByScope.get(domainScope) ?? new Set();
|
|
158
|
+
membershipListenersByScope.set(domainScope, listeners);
|
|
159
|
+
listeners.add(listener);
|
|
160
|
+
return () => {
|
|
161
|
+
listeners.delete(listener);
|
|
162
|
+
};
|
|
163
|
+
},
|
|
130
164
|
};
|
|
131
165
|
}
|
|
132
166
|
//# sourceMappingURL=organizationMemberships.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationMemberships.js","sourceRoot":"","sources":["organizationMemberships.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type OrganizationContentHost,\n type OrganizationMembership,\n type OrganizationSyncPauseResult,\n refreshOrganizationMemberships,\n setOrganizationSyncPaused,\n} from \"../../workflows/organizations\";\nimport {\n type DomainScope,\n getOrCreateOrganizationSyncPauses,\n hasDomainSyncCoordinatorPendingWork,\n requestAllDomainSyncLanes,\n subscribeToDomainSyncCoordinator,\n waitForDomainSyncCoordinatorToSettle,\n} from \"../../workflows/sync\";\nimport {\n type ContainerContents,\n carriesLocalWrites,\n} from \"../containerContents\";\nimport type {\n InternalRuntime,\n InternalWorkflowRuntimeInput,\n} from \"../runtime/workflowRuntime\";\n\n// Long enough for a typical upload burst, short enough to answer a tap.\nconst PAUSE_FLUSH_TIMEOUT_MS = 10_000;\n\n/** The user's own conduit to the organizations they belong to. */\nexport interface OrganizationMemberships {\n /**\n * Reads the user's memberships and applies their pause choices on this\n * device. Null when offline or the list could not be read.\n */\n refresh(): Promise<OrganizationMembership[] | null>;\n /** Pauses or resumes one organization for all of the user's devices. */\n setSyncPaused(\n organizationId: string,\n paused: boolean,\n ): Promise<OrganizationSyncPauseResult>;\n /** The organizations paused on this device, read from local storage. */\n loadPausedOrganizationIds(): Promise<ReadonlySet<string>>;\n /** Notifies when the paused set for the current scope changes. */\n subscribeToSyncPauses(listener: () => void): () => void;\n}\n\n/**\n * The scope's document reconciler. Containers it reconciled before a pause\n * stay marked as listed, so a resume has to forget that before reconciling.\n */\nexport interface OrganizationContentReconciler {\n resetDiscovered(): void;\n reconcileNow(options: { readonly freshListing: true }): Promise<void>;\n}\n\ninterface SettleRetry {\n retry: () => Promise<boolean>;\n running: boolean;\n unsubscribe: () => void;\n}\n\nconst settleRetriesByScope = new WeakMap<DomainScope, SettleRetry>();\n\n// One retry per scope: it runs whenever the scope's sync lanes go idle and\n// stops once it reports the work done.\nexport function retryWhenWritesSettle(\n domainScope: DomainScope,\n retry: () => Promise<boolean>,\n): void {\n const existing = settleRetriesByScope.get(domainScope);\n if (existing) {\n existing.retry = retry;\n return;\n }\n const entry: SettleRetry = { retry, running: false, unsubscribe: () => {} };\n settleRetriesByScope.set(domainScope, entry);\n const attempt = () => {\n if (entry.running || hasDomainSyncCoordinatorPendingWork(domainScope)) {\n return;\n }\n entry.running = true;\n void entry\n .retry()\n .then(\n (done) => {\n if (!done) return;\n entry.unsubscribe();\n settleRetriesByScope.delete(domainScope);\n },\n () => undefined,\n )\n .finally(() => {\n entry.running = false;\n });\n };\n entry.unsubscribe = subscribeToDomainSyncCoordinator(domainScope, attempt);\n // The lanes may already have gone idle before the subscription existed.\n attempt();\n}\n\n// Bound to the scope the operation started in: the tree is opened once, and\n// every action re-checks the scope so stale work never reaches another\n// identity's device state.\nfunction createOrganizationContentHost(\n runtime: InternalWorkflowRuntimeInput,\n containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n isCurrent: () => boolean,\n): OrganizationContentHost {\n const { domainScope } = runtime.state;\n const tree = containerContents.openTree();\n return {\n async forgetOrganizationContent(organizationId) {\n // A scope that ended has nothing left to retry.\n if (!isCurrent()) return true;\n return tree.forgetOrganizationContent(organizationId);\n },\n async hasUnsyncedOrganizationWrites(organizationId) {\n if (!isCurrent()) return true;\n const pending = await containerContents\n .documentQueries()\n .listPendingWrites();\n return pending.some(\n (item) =>\n item.organizationId === organizationId && carriesLocalWrites(item),\n );\n },\n async flushWrites() {\n requestAllDomainSyncLanes(domainScope);\n await waitForDomainSyncCoordinatorToSettle(domainScope, {\n timeoutMs: PAUSE_FLUSH_TIMEOUT_MS,\n });\n },\n async refetchContent() {\n if (!isCurrent()) return;\n // Re-lists the whole tree and every container's documents. The resumed\n // organization's folders were listed before the pause, and a hydration\n // may already have restored them, so they must be forgotten explicitly.\n // A sweep that started listing while paused would miss them, so this\n // one queues behind it rather than joining it.\n const reconciler = openReconciler();\n reconciler.resetDiscovered();\n await reconciler.reconcileNow({ freshListing: true });\n },\n retryWhenWritesSettle: (retry) => retryWhenWritesSettle(domainScope, retry),\n };\n}\n\nfunction canReachServer(runtime: InternalWorkflowRuntimeInput): boolean {\n return (\n runtime.infra.dbStatus === \"ready\" &&\n runtime.auth.isAuthenticated &&\n runtime.state.online\n );\n}\n\nexport function createOrganizationMemberships(\n runtimeService: InternalRuntime,\n containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n): OrganizationMemberships {\n const membershipInput = (runtime: InternalWorkflowRuntimeInput) => {\n const { domainScope } = runtime.state;\n const isCurrent = () =>\n runtimeService.workflowInput().state.domainScope === domainScope;\n return {\n apiClient: runtime.apiClient,\n domainScope,\n execSql: runtime.infra.execSql,\n host: createOrganizationContentHost(\n runtime,\n containerContents,\n openReconciler,\n isCurrent,\n ),\n isCurrent,\n };\n };\n return {\n async refresh() {\n const runtime = runtimeService.workflowInput();\n if (!canReachServer(runtime)) return null;\n return refreshOrganizationMemberships(membershipInput(runtime));\n },\n async setSyncPaused(organizationId, paused) {\n const runtime = runtimeService.workflowInput();\n if (!canReachServer(runtime)) {\n return {\n httpStatus: null,\n message: \"Connect to change sync for an organization.\",\n status: \"failed\",\n };\n }\n return setOrganizationSyncPaused({\n ...membershipInput(runtime),\n organizationId,\n paused,\n });\n },\n async loadPausedOrganizationIds() {\n const runtime = runtimeService.workflowInput();\n if (runtime.infra.dbStatus !== \"ready\") return new Set<string>();\n const pauses = getOrCreateOrganizationSyncPauses(\n runtime.state.domainScope,\n );\n await pauses.load(runtime.infra.execSql);\n return pauses.pausedOrganizationIds();\n },\n subscribeToSyncPauses(listener) {\n return getOrCreateOrganizationSyncPauses(\n runtimeService.workflowInput().state.domainScope,\n ).subscribe(listener);\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"organizationMemberships.js","sourceRoot":"","sources":["organizationMemberships.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type OrganizationContentHost,\n type OrganizationLeaveRequestResult,\n type OrganizationMembership,\n type OrganizationSyncPauseResult,\n refreshOrganizationMemberships,\n setOrganizationLeaveRequested,\n setOrganizationSyncPaused,\n} from \"../../workflows/organizations\";\nimport {\n type DomainScope,\n getOrCreateOrganizationSyncPauses,\n hasDomainSyncCoordinatorPendingWork,\n requestAllDomainSyncLanes,\n subscribeToDomainSyncCoordinator,\n waitForDomainSyncCoordinatorToSettle,\n} from \"../../workflows/sync\";\nimport {\n type ContainerContents,\n carriesLocalWrites,\n} from \"../containerContents\";\nimport type {\n InternalRuntime,\n InternalWorkflowRuntimeInput,\n} from \"../runtime/workflowRuntime\";\n\n// Long enough for a typical upload burst, short enough to answer a tap.\nconst PAUSE_FLUSH_TIMEOUT_MS = 10_000;\n\n/** The user's own conduit to the organizations they belong to. */\nexport interface OrganizationMemberships {\n /**\n * Reads the user's memberships and applies their pause choices on this\n * device. Null when offline or the list could not be read.\n */\n refresh(): Promise<OrganizationMembership[] | null>;\n /** Pauses or resumes one organization for all of the user's devices. */\n setSyncPaused(\n organizationId: string,\n paused: boolean,\n ): Promise<OrganizationSyncPauseResult>;\n /**\n * Asks the organization's administrators to remove the user, or withdraws\n * that request. Signed with the user's identity key; an administrator still\n * has to approve it.\n */\n setLeaveRequested(\n organizationId: string,\n requested: boolean,\n ): Promise<OrganizationLeaveRequestResult>;\n /** The organizations paused on this device, read from local storage. */\n loadPausedOrganizationIds(): Promise<ReadonlySet<string>>;\n /** Notifies when the paused set for the current scope changes. */\n subscribeToSyncPauses(listener: () => void): () => void;\n /**\n * Hands each membership list a refresh reads for the current scope, so a\n * choice made on another device reaches every view of it.\n */\n subscribeToMemberships(\n listener: (memberships: readonly OrganizationMembership[]) => void,\n ): () => void;\n}\n\ntype MembershipsListener = (\n memberships: readonly OrganizationMembership[],\n) => void;\n\nconst membershipListenersByScope = new WeakMap<\n DomainScope,\n Set<MembershipsListener>\n>();\n\n/**\n * The scope's document reconciler. Containers it reconciled before a pause\n * stay marked as listed, so a resume has to forget that before reconciling.\n */\nexport interface OrganizationContentReconciler {\n resetDiscovered(): void;\n reconcileNow(options: { readonly freshListing: true }): Promise<void>;\n}\n\ninterface SettleRetry {\n retry: () => Promise<boolean>;\n running: boolean;\n unsubscribe: () => void;\n}\n\nconst settleRetriesByScope = new WeakMap<DomainScope, SettleRetry>();\n\n// One retry per scope: it runs whenever the scope's sync lanes go idle and\n// stops once it reports the work done.\nexport function retryWhenWritesSettle(\n domainScope: DomainScope,\n retry: () => Promise<boolean>,\n): void {\n const existing = settleRetriesByScope.get(domainScope);\n if (existing) {\n existing.retry = retry;\n return;\n }\n const entry: SettleRetry = { retry, running: false, unsubscribe: () => {} };\n settleRetriesByScope.set(domainScope, entry);\n const attempt = () => {\n if (entry.running || hasDomainSyncCoordinatorPendingWork(domainScope)) {\n return;\n }\n entry.running = true;\n void entry\n .retry()\n .then(\n (done) => {\n if (!done) return;\n entry.unsubscribe();\n settleRetriesByScope.delete(domainScope);\n },\n () => undefined,\n )\n .finally(() => {\n entry.running = false;\n });\n };\n entry.unsubscribe = subscribeToDomainSyncCoordinator(domainScope, attempt);\n // The lanes may already have gone idle before the subscription existed.\n attempt();\n}\n\n// Bound to the scope the operation started in: the tree is opened once, and\n// every action re-checks the scope so stale work never reaches another\n// identity's device state.\nfunction createOrganizationContentHost(\n runtime: InternalWorkflowRuntimeInput,\n containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n isCurrent: () => boolean,\n): OrganizationContentHost {\n const { domainScope } = runtime.state;\n const tree = containerContents.openTree();\n return {\n async forgetOrganizationContent(organizationId) {\n // A scope that ended has nothing left to retry.\n if (!isCurrent()) return true;\n return tree.forgetOrganizationContent(organizationId);\n },\n async hasUnsyncedOrganizationWrites(organizationId) {\n if (!isCurrent()) return true;\n const pending = await containerContents\n .documentQueries()\n .listPendingWrites();\n return pending.some(\n (item) =>\n item.organizationId === organizationId && carriesLocalWrites(item),\n );\n },\n async flushWrites() {\n requestAllDomainSyncLanes(domainScope);\n await waitForDomainSyncCoordinatorToSettle(domainScope, {\n timeoutMs: PAUSE_FLUSH_TIMEOUT_MS,\n });\n },\n async refetchContent() {\n if (!isCurrent()) return;\n // Re-lists the whole tree and every container's documents. The resumed\n // organization's folders were listed before the pause, and a hydration\n // may already have restored them, so they must be forgotten explicitly.\n // A sweep that started listing while paused would miss them, so this\n // one queues behind it rather than joining it.\n const reconciler = openReconciler();\n reconciler.resetDiscovered();\n await reconciler.reconcileNow({ freshListing: true });\n },\n retryWhenWritesSettle: (retry) => retryWhenWritesSettle(domainScope, retry),\n };\n}\n\nfunction canReachServer(runtime: InternalWorkflowRuntimeInput): boolean {\n return (\n runtime.infra.dbStatus === \"ready\" &&\n runtime.auth.isAuthenticated &&\n runtime.state.online\n );\n}\n\nexport function createOrganizationMemberships(\n runtimeService: InternalRuntime,\n containerContents: ContainerContents,\n openReconciler: () => OrganizationContentReconciler,\n): OrganizationMemberships {\n const membershipInput = (runtime: InternalWorkflowRuntimeInput) => {\n const { domainScope } = runtime.state;\n const isCurrent = () =>\n runtimeService.workflowInput().state.domainScope === domainScope;\n return {\n apiClient: runtime.apiClient,\n domainScope,\n execSql: runtime.infra.execSql,\n host: createOrganizationContentHost(\n runtime,\n containerContents,\n openReconciler,\n isCurrent,\n ),\n isCurrent,\n };\n };\n return {\n async refresh() {\n const runtime = runtimeService.workflowInput();\n if (!canReachServer(runtime)) return null;\n const memberships = await refreshOrganizationMemberships(\n membershipInput(runtime),\n );\n const listeners = membershipListenersByScope.get(\n runtime.state.domainScope,\n );\n if (memberships && listeners) {\n for (const listener of [...listeners]) listener(memberships);\n }\n return memberships;\n },\n async setSyncPaused(organizationId, paused) {\n const runtime = runtimeService.workflowInput();\n if (!canReachServer(runtime)) {\n return {\n httpStatus: null,\n message: \"Connect to change sync for an organization.\",\n status: \"failed\",\n };\n }\n return setOrganizationSyncPaused({\n ...membershipInput(runtime),\n organizationId,\n paused,\n });\n },\n async setLeaveRequested(organizationId, requested) {\n const runtime = runtimeService.workflowInput();\n const { userId } = runtime.auth;\n const { signingKeyPair } = runtime.crypto;\n if (!canReachServer(runtime) || !userId || !signingKeyPair) {\n return {\n httpStatus: null,\n message: \"Connect to ask to leave an organization.\",\n status: \"failed\",\n };\n }\n return setOrganizationLeaveRequested({\n apiClient: runtime.apiClient,\n organizationId,\n requested,\n signer: { signingKeyPair, userId },\n });\n },\n async loadPausedOrganizationIds() {\n const runtime = runtimeService.workflowInput();\n if (runtime.infra.dbStatus !== \"ready\") return new Set<string>();\n const pauses = getOrCreateOrganizationSyncPauses(\n runtime.state.domainScope,\n );\n await pauses.load(runtime.infra.execSql);\n return pauses.pausedOrganizationIds();\n },\n subscribeToSyncPauses(listener) {\n return getOrCreateOrganizationSyncPauses(\n runtimeService.workflowInput().state.domainScope,\n ).subscribe(listener);\n },\n subscribeToMemberships(listener) {\n const { domainScope } = runtimeService.workflowInput().state;\n const listeners =\n membershipListenersByScope.get(domainScope) ?? new Set();\n membershipListenersByScope.set(domainScope, listeners);\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n"]}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { type OrganizationContainerGrants, type OrganizationDirectoryAndGroups, type OrganizationGroupContainers, type OrganizationGroupMembers, type OrganizationGroupPolicyHistory, type OrganizationPolicyHistory, type OrganizationUserDetail } from "../../workflows/organizations/index.js";
|
|
2
|
-
import type { InternalRuntime } from "../runtime/workflowRuntime.js";
|
|
2
|
+
import type { InternalRuntime, InternalWorkflowRuntimeInput } from "../runtime/workflowRuntime.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the identity a leave request is checked against: the device's
|
|
5
|
+
* durable pin first, so a request already stored still verifies offline,
|
|
6
|
+
* then a trusted remote resolution for a member not pinned yet.
|
|
7
|
+
*/
|
|
8
|
+
export declare function leaveRequestSignerResolver(runtimeService: InternalRuntime, runtime: InternalWorkflowRuntimeInput): InternalWorkflowRuntimeInput["resolveTrustedUserIdentity"];
|
|
3
9
|
export interface OrganizationReadModelCoordinator {
|
|
4
10
|
loadLocal(organizationId?: string | undefined): Promise<OrganizationDirectoryAndGroups | null>;
|
|
5
11
|
loadLocalGroupMembers(groupId: string, organizationId?: string | undefined): Promise<OrganizationGroupMembers | null>;
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { recoverOrganizationAccess } from "../../workflows/container-contents/recovery/accessRestoration.js";
|
|
2
|
-
import { loadLocalOrganizationContainerGrants, loadLocalOrganizationDirectoryAndGroups, loadLocalOrganizationGroupContainers, loadLocalOrganizationGroupMembers, loadLocalOrganizationUserDetail, reconcileOrganizationDirectoryAndGroups, } from "../../workflows/organizations/index.js";
|
|
2
|
+
import { loadLocalOrganizationContainerGrants, loadLocalOrganizationDirectoryAndGroups, loadLocalOrganizationGroupContainers, loadLocalOrganizationGroupMembers, loadLocalOrganizationUserDetail, reconcileOrganizationDirectoryAndGroups, withVerifiedLeaveRequests, withVerifiedUserLeaveRequest, } from "../../workflows/organizations/index.js";
|
|
3
3
|
import { organizationAccessScopeKey, wasOrganizationPresentationAccessDeniedByServer, } from "../../workflows/organizations/readModel/organizationPresentationAccessState.js";
|
|
4
4
|
import { loadBoundedOrganizationGroupHistory } from "./organizationGroupHistory.js";
|
|
5
5
|
import { hydrateOrganizationGroupNamesForRuntime } from "./organizationGroupNameHydration.js";
|
|
6
6
|
import { loadBoundedOrganizationHistory } from "./organizationHistory.js";
|
|
7
7
|
import { activeOrganizationDataRuntime, isOrganizationDataRuntimeCurrent, } from "./organizationWorkflowRuntime.js";
|
|
8
8
|
const coordinatorsByRuntime = new WeakMap();
|
|
9
|
+
/**
|
|
10
|
+
* Resolves the identity a leave request is checked against: the device's
|
|
11
|
+
* durable pin first, so a request already stored still verifies offline,
|
|
12
|
+
* then a trusted remote resolution for a member not pinned yet.
|
|
13
|
+
*/
|
|
14
|
+
export function leaveRequestSignerResolver(runtimeService, runtime) {
|
|
15
|
+
return async (userId) => (await runtimeService.identityLinks.resolvePinned(userId)) ??
|
|
16
|
+
runtime.resolveTrustedUserIdentity(userId);
|
|
17
|
+
}
|
|
9
18
|
class OrganizationReadModelCoordinatorImpl {
|
|
10
19
|
runtimeService;
|
|
11
20
|
reconciliationsByScope = new WeakMap();
|
|
@@ -26,11 +35,11 @@ class OrganizationReadModelCoordinatorImpl {
|
|
|
26
35
|
if (!active) {
|
|
27
36
|
return null;
|
|
28
37
|
}
|
|
29
|
-
return loadLocalOrganizationDirectoryAndGroups({
|
|
38
|
+
return withVerifiedLeaveRequests(await loadLocalOrganizationDirectoryAndGroups({
|
|
30
39
|
currentUserId: active.userId,
|
|
31
40
|
execSql: active.runtime.infra.execSql,
|
|
32
41
|
organizationId: active.organizationId,
|
|
33
|
-
});
|
|
42
|
+
}), leaveRequestSignerResolver(this.runtimeService, active.runtime));
|
|
34
43
|
}
|
|
35
44
|
async loadLocalGrants(organizationId) {
|
|
36
45
|
const active = activeOrganizationDataRuntime(this.runtimeService, organizationId);
|
|
@@ -96,12 +105,12 @@ class OrganizationReadModelCoordinatorImpl {
|
|
|
96
105
|
if (!active || userId.length === 0) {
|
|
97
106
|
return null;
|
|
98
107
|
}
|
|
99
|
-
return loadLocalOrganizationUserDetail({
|
|
108
|
+
return withVerifiedUserLeaveRequest(await loadLocalOrganizationUserDetail({
|
|
100
109
|
currentUserId: active.userId,
|
|
101
110
|
execSql: active.runtime.infra.execSql,
|
|
102
111
|
organizationId: active.organizationId,
|
|
103
112
|
userId,
|
|
104
|
-
});
|
|
113
|
+
}), active.organizationId, leaveRequestSignerResolver(this.runtimeService, active.runtime));
|
|
105
114
|
}
|
|
106
115
|
reconcile(organizationId) {
|
|
107
116
|
const active = activeOrganizationDataRuntime(this.runtimeService, organizationId);
|
|
@@ -153,7 +162,7 @@ class OrganizationReadModelCoordinatorImpl {
|
|
|
153
162
|
});
|
|
154
163
|
if (!stillCurrent())
|
|
155
164
|
return null;
|
|
156
|
-
return hydrateOrganizationGroupNamesForRuntime(this.runtimeService, active, domainScope, directoryAndGroups);
|
|
165
|
+
return withVerifiedLeaveRequests(await hydrateOrganizationGroupNamesForRuntime(this.runtimeService, active, domainScope, directoryAndGroups), leaveRequestSignerResolver(this.runtimeService, active.runtime));
|
|
157
166
|
})
|
|
158
167
|
.finally(() => {
|
|
159
168
|
if (byKey.get(key) === reconciliation) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationReadModels.js","sourceRoot":"","sources":["organizationReadModels.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport { recoverOrganizationAccess } from \"../../workflows/container-contents/recovery/accessRestoration\";\nimport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupMembers,\n loadLocalOrganizationUserDetail,\n type OrganizationContainerGrants,\n type OrganizationDirectoryAndGroups,\n type OrganizationGroupContainers,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationPolicyHistory,\n type OrganizationUserDetail,\n reconcileOrganizationDirectoryAndGroups,\n} from \"../../workflows/organizations\";\nimport {\n organizationAccessScopeKey,\n wasOrganizationPresentationAccessDeniedByServer,\n} from \"../../workflows/organizations/readModel/organizationPresentationAccessState\";\nimport type { InternalRuntime } from \"../runtime/workflowRuntime\";\nimport { loadBoundedOrganizationGroupHistory } from \"./organizationGroupHistory\";\nimport { hydrateOrganizationGroupNamesForRuntime } from \"./organizationGroupNameHydration\";\nimport { loadBoundedOrganizationHistory } from \"./organizationHistory\";\nimport {\n type ActiveOrganizationDataRuntime,\n activeOrganizationDataRuntime,\n isOrganizationDataRuntimeCurrent,\n} from \"./organizationWorkflowRuntime\";\n\nconst coordinatorsByRuntime = new WeakMap<\n InternalRuntime,\n OrganizationReadModelCoordinator\n>();\n\nexport interface OrganizationReadModelCoordinator {\n loadLocal(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null>;\n loadLocalGroupMembers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupMembers | null>;\n loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationGroupPolicyHistory | null>;\n loadOrganizationPolicyHistory(\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationPolicyHistory | null>;\n loadLocalGrants(\n organizationId?: string | undefined,\n ): Promise<OrganizationContainerGrants | null>;\n loadLocalGroupContainers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupContainers | null>;\n loadLocalUserDetail(\n userId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationUserDetail | null>;\n /**\n * Resolves `undefined` when the runtime declines without I/O (offline,\n * database not ready, organization mismatch) or when the feed failed with\n * no locally retained projection — passes that must not count as caught\n * up; `null` when the reconcile completed but produced nothing presentable\n * — including an authoritative denial that purged the projection, which\n * consumers must repaint.\n */\n reconcile(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n reconcileAfterMutation(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n}\n\nclass OrganizationReadModelCoordinatorImpl\n implements OrganizationReadModelCoordinator\n{\n private readonly reconciliationsByScope = new WeakMap<\n DomainScope,\n Map<string, Promise<OrganizationDirectoryAndGroups | null | undefined>>\n >();\n constructor(private readonly runtimeService: InternalRuntime) {}\n\n private reconciliationMap(active: ActiveOrganizationDataRuntime) {\n const scope = active.runtime.state.domainScope;\n let byKey = this.reconciliationsByScope.get(scope);\n if (!byKey) {\n byKey = new Map();\n this.reconciliationsByScope.set(scope, byKey);\n }\n return byKey;\n }\n\n async loadLocal(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationDirectoryAndGroups({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGrants(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationContainerGrants({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupContainers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupContainers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupMembers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupMembers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationGroupHistory({\n active,\n groupId,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadOrganizationPolicyHistory(\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) return null;\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationHistory({\n active,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadLocalUserDetail(userId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || userId.length === 0) {\n return null;\n }\n return loadLocalOrganizationUserDetail({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n userId,\n });\n }\n\n reconcile(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return Promise.resolve(undefined);\n }\n\n const byKey = this.reconciliationMap(active);\n const key = organizationAccessScopeKey(\n active.organizationId,\n active.userId,\n );\n const existing = byKey.get(key);\n if (existing) {\n return existing;\n }\n\n // Snapshot the server-denied flag before reconciling. A reconcile that\n // flips it back to readable means org access was just restored (e.g. the\n // user was re-added to a group), and any write lanes idled by\n // permission-denied submissions have no self re-arm — regaining access is\n // their retry signal, mirroring how billing recovery re-requests all\n // lanes. Only a genuine server denial counts: a local session reset also\n // marks scopes denied, and re-arming on its first reconcile would race the\n // startup sync passes (e.g. pending-create adoption between panes).\n const accessWasDenied = wasOrganizationPresentationAccessDeniedByServer(\n {\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n requesterUserId: active.userId,\n },\n \"readModel\",\n );\n const domainScope = active.runtime.state.domainScope;\n const stillCurrent = () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n );\n\n const reconciliation = reconcileOrganizationDirectoryAndGroups({\n apiClient: active.runtime.apiClient,\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n logError: active.runtime.util.logError,\n organizationId: active.organizationId,\n })\n .then(async (directoryAndGroups) => {\n if (!stillCurrent()) return null;\n // Feed success restores retry eligibility even if name decryption fails.\n const accessWasRestored =\n accessWasDenied &&\n directoryAndGroups !== null &&\n directoryAndGroups !== undefined;\n if (accessWasRestored)\n await recoverOrganizationAccess({\n domainScope,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n stillCurrent,\n userId: active.userId,\n });\n if (!stillCurrent()) return null;\n return hydrateOrganizationGroupNamesForRuntime(\n this.runtimeService,\n active,\n domainScope,\n directoryAndGroups,\n );\n })\n .finally(() => {\n if (byKey.get(key) === reconciliation) {\n byKey.delete(key);\n }\n });\n byKey.set(key, reconciliation);\n return reconciliation;\n }\n\n async reconcileAfterMutation(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return undefined;\n }\n const existing = this.reconciliationMap(active).get(\n organizationAccessScopeKey(active.organizationId, active.userId),\n );\n if (existing) {\n await existing.catch(() => null);\n }\n return this.reconcile(active.organizationId);\n }\n}\n\nexport function createOrganizationReadModelCoordinator(\n runtimeService: InternalRuntime,\n): OrganizationReadModelCoordinator {\n const existing = coordinatorsByRuntime.get(runtimeService);\n if (existing) {\n return existing;\n }\n\n const coordinator = new OrganizationReadModelCoordinatorImpl(runtimeService);\n coordinatorsByRuntime.set(runtimeService, coordinator);\n return coordinator;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"organizationReadModels.js","sourceRoot":"","sources":["organizationReadModels.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport { recoverOrganizationAccess } from \"../../workflows/container-contents/recovery/accessRestoration\";\nimport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupMembers,\n loadLocalOrganizationUserDetail,\n type OrganizationContainerGrants,\n type OrganizationDirectoryAndGroups,\n type OrganizationGroupContainers,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationPolicyHistory,\n type OrganizationUserDetail,\n reconcileOrganizationDirectoryAndGroups,\n withVerifiedLeaveRequests,\n withVerifiedUserLeaveRequest,\n} from \"../../workflows/organizations\";\nimport {\n organizationAccessScopeKey,\n wasOrganizationPresentationAccessDeniedByServer,\n} from \"../../workflows/organizations/readModel/organizationPresentationAccessState\";\nimport type {\n InternalRuntime,\n InternalWorkflowRuntimeInput,\n} from \"../runtime/workflowRuntime\";\nimport { loadBoundedOrganizationGroupHistory } from \"./organizationGroupHistory\";\nimport { hydrateOrganizationGroupNamesForRuntime } from \"./organizationGroupNameHydration\";\nimport { loadBoundedOrganizationHistory } from \"./organizationHistory\";\nimport {\n type ActiveOrganizationDataRuntime,\n activeOrganizationDataRuntime,\n isOrganizationDataRuntimeCurrent,\n} from \"./organizationWorkflowRuntime\";\n\nconst coordinatorsByRuntime = new WeakMap<\n InternalRuntime,\n OrganizationReadModelCoordinator\n>();\n\n/**\n * Resolves the identity a leave request is checked against: the device's\n * durable pin first, so a request already stored still verifies offline,\n * then a trusted remote resolution for a member not pinned yet.\n */\nexport function leaveRequestSignerResolver(\n runtimeService: InternalRuntime,\n runtime: InternalWorkflowRuntimeInput,\n): InternalWorkflowRuntimeInput[\"resolveTrustedUserIdentity\"] {\n return async (userId) =>\n (await runtimeService.identityLinks.resolvePinned(userId)) ??\n runtime.resolveTrustedUserIdentity(userId);\n}\n\nexport interface OrganizationReadModelCoordinator {\n loadLocal(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null>;\n loadLocalGroupMembers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupMembers | null>;\n loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationGroupPolicyHistory | null>;\n loadOrganizationPolicyHistory(\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationPolicyHistory | null>;\n loadLocalGrants(\n organizationId?: string | undefined,\n ): Promise<OrganizationContainerGrants | null>;\n loadLocalGroupContainers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupContainers | null>;\n loadLocalUserDetail(\n userId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationUserDetail | null>;\n /**\n * Resolves `undefined` when the runtime declines without I/O (offline,\n * database not ready, organization mismatch) or when the feed failed with\n * no locally retained projection — passes that must not count as caught\n * up; `null` when the reconcile completed but produced nothing presentable\n * — including an authoritative denial that purged the projection, which\n * consumers must repaint.\n */\n reconcile(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n reconcileAfterMutation(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n}\n\nclass OrganizationReadModelCoordinatorImpl\n implements OrganizationReadModelCoordinator\n{\n private readonly reconciliationsByScope = new WeakMap<\n DomainScope,\n Map<string, Promise<OrganizationDirectoryAndGroups | null | undefined>>\n >();\n constructor(private readonly runtimeService: InternalRuntime) {}\n\n private reconciliationMap(active: ActiveOrganizationDataRuntime) {\n const scope = active.runtime.state.domainScope;\n let byKey = this.reconciliationsByScope.get(scope);\n if (!byKey) {\n byKey = new Map();\n this.reconciliationsByScope.set(scope, byKey);\n }\n return byKey;\n }\n\n async loadLocal(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return withVerifiedLeaveRequests(\n await loadLocalOrganizationDirectoryAndGroups({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n }),\n leaveRequestSignerResolver(this.runtimeService, active.runtime),\n );\n }\n\n async loadLocalGrants(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationContainerGrants({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupContainers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupContainers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupMembers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupMembers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationGroupHistory({\n active,\n groupId,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadOrganizationPolicyHistory(\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) return null;\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationHistory({\n active,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadLocalUserDetail(userId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || userId.length === 0) {\n return null;\n }\n return withVerifiedUserLeaveRequest(\n await loadLocalOrganizationUserDetail({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n userId,\n }),\n active.organizationId,\n leaveRequestSignerResolver(this.runtimeService, active.runtime),\n );\n }\n\n reconcile(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return Promise.resolve(undefined);\n }\n\n const byKey = this.reconciliationMap(active);\n const key = organizationAccessScopeKey(\n active.organizationId,\n active.userId,\n );\n const existing = byKey.get(key);\n if (existing) {\n return existing;\n }\n\n // Snapshot the server-denied flag before reconciling. A reconcile that\n // flips it back to readable means org access was just restored (e.g. the\n // user was re-added to a group), and any write lanes idled by\n // permission-denied submissions have no self re-arm — regaining access is\n // their retry signal, mirroring how billing recovery re-requests all\n // lanes. Only a genuine server denial counts: a local session reset also\n // marks scopes denied, and re-arming on its first reconcile would race the\n // startup sync passes (e.g. pending-create adoption between panes).\n const accessWasDenied = wasOrganizationPresentationAccessDeniedByServer(\n {\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n requesterUserId: active.userId,\n },\n \"readModel\",\n );\n const domainScope = active.runtime.state.domainScope;\n const stillCurrent = () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n );\n\n const reconciliation = reconcileOrganizationDirectoryAndGroups({\n apiClient: active.runtime.apiClient,\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n logError: active.runtime.util.logError,\n organizationId: active.organizationId,\n })\n .then(async (directoryAndGroups) => {\n if (!stillCurrent()) return null;\n // Feed success restores retry eligibility even if name decryption fails.\n const accessWasRestored =\n accessWasDenied &&\n directoryAndGroups !== null &&\n directoryAndGroups !== undefined;\n if (accessWasRestored)\n await recoverOrganizationAccess({\n domainScope,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n stillCurrent,\n userId: active.userId,\n });\n if (!stillCurrent()) return null;\n return withVerifiedLeaveRequests(\n await hydrateOrganizationGroupNamesForRuntime(\n this.runtimeService,\n active,\n domainScope,\n directoryAndGroups,\n ),\n leaveRequestSignerResolver(this.runtimeService, active.runtime),\n );\n })\n .finally(() => {\n if (byKey.get(key) === reconciliation) {\n byKey.delete(key);\n }\n });\n byKey.set(key, reconciliation);\n return reconciliation;\n }\n\n async reconcileAfterMutation(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return undefined;\n }\n const existing = this.reconciliationMap(active).get(\n organizationAccessScopeKey(active.organizationId, active.userId),\n );\n if (existing) {\n await existing.catch(() => null);\n }\n return this.reconcile(active.organizationId);\n }\n}\n\nexport function createOrganizationReadModelCoordinator(\n runtimeService: InternalRuntime,\n): OrganizationReadModelCoordinator {\n const existing = coordinatorsByRuntime.get(runtimeService);\n if (existing) {\n return existing;\n }\n\n const coordinator = new OrganizationReadModelCoordinatorImpl(runtimeService);\n coordinatorsByRuntime.set(runtimeService, coordinator);\n return coordinator;\n}\n"]}
|
|
@@ -14,6 +14,19 @@ import { loadWithOrganizationReadModelIntegrityPurge, pruneInactiveOrganizationR
|
|
|
14
14
|
import { assertOrganizationReadModelResponse } from "./organizationReadModelResponseAssertions.js";
|
|
15
15
|
const DIRECTORY_INSERT_BATCH_SIZE = sqliteInsertBatchSize(organizationReadModelDirectoryUsers);
|
|
16
16
|
const GROUP_INSERT_BATCH_SIZE = sqliteInsertBatchSize(organizationReadModelGroups);
|
|
17
|
+
/**
|
|
18
|
+
* The member's leave request as stored JSON, kept only when it names this
|
|
19
|
+
* organization and member. Its signature is checked when read, against the
|
|
20
|
+
* member's trusted identity rather than the key served beside it.
|
|
21
|
+
*/
|
|
22
|
+
function storedLeaveRequestJson(organizationId, user) {
|
|
23
|
+
const request = user.leaveRequest;
|
|
24
|
+
return request &&
|
|
25
|
+
request.organizationId === organizationId &&
|
|
26
|
+
request.userId === user.userId
|
|
27
|
+
? JSON.stringify(request)
|
|
28
|
+
: null;
|
|
29
|
+
}
|
|
17
30
|
async function replaceDirectoryLane(input) {
|
|
18
31
|
await input.tx
|
|
19
32
|
.delete(organizationReadModelDirectoryUsers)
|
|
@@ -35,6 +48,7 @@ async function replaceDirectoryLane(input) {
|
|
|
35
48
|
updatedAt: user.updatedAt,
|
|
36
49
|
disabledAt: user.disabledAt,
|
|
37
50
|
disabledByUserId: user.disabledByUserId,
|
|
51
|
+
leaveRequest: storedLeaveRequestJson(input.organizationId, user),
|
|
38
52
|
}));
|
|
39
53
|
for (let index = 0; index < rows.length; index += DIRECTORY_INSERT_BATCH_SIZE) {
|
|
40
54
|
await input.tx
|