@codemem/server 0.47.1 → 0.47.3
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/dist/account/link-registry.d.ts +1 -1
- package/dist/account/link-registry.d.ts.map +1 -1
- package/dist/account/status.d.ts.map +1 -1
- package/dist/index.js +197 -82
- package/dist/index.js.map +1 -1
- package/dist/routes/account-operations.d.ts.map +1 -1
- package/dist/routes/team-setup-view.d.ts +1 -0
- package/dist/routes/team-setup-view.d.ts.map +1 -1
- package/dist/routes/team-setup.d.ts.map +1 -1
- package/package.json +2 -2
- package/static/app.js +28 -28
- package/static/app.js.br +0 -0
- package/static/app.js.gz +0 -0
- package/static/index.html +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { closeSync, existsSync, fstatSync, fsyncSync, linkSync, lstatSync, mkdirSync, openSync, readFileSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, isAbsolute, join, posix, resolve, win32 } from "node:path";
|
|
3
|
-
import { ACCESS_CLEANUP_OP_TYPE, CodememConfigMutationError, CoordinatorAccountLinkError, CoordinatorReciprocalApprovalRequestChangedError, DEFAULT_TIME_WINDOW_S, FILE_CONTEXT_TRANSPORT_MAX_BYTES, LEGACY_SHARED_REVIEW_SCOPE_ID, LOCAL_DEFAULT_SCOPE_ID, LOCAL_SYNC_CAPABILITY, LOCAL_SYNC_FEATURES, LegacyTeamSetupAdditiveConvergenceError, LegacyTeamSetupRosterCapacityError, MEMORY_FILTER_FIELD_TYPES, MEMORY_FILTER_NAMES, MEMORY_KIND_DESCRIPTIONS, MemoryStore, ObserverClient, PROMPT_TRANSPORT_PROTOCOL_RANGE, REMEMBER_MEMORY_KINDS, RICH_TIER_ANTHROPIC_DEFAULTS, RICH_TIER_DEFAULTS, RawEventIngestValidationError, RecipientPolicyEdgeRequestError, RecipientPolicyTeamRenameError, RemoteCoordinatorRequestError, SCOPE_MEMBERSHIP_REVOCATION_LIMITATION, SIMPLE_TIER_ANTHROPIC_DEFAULTS, SIMPLE_TIER_DEFAULTS, SYNC_AUTHORIZATION_REFRESH_HEADER, SYNC_CAPABILITY_HEADER, SYNC_FEATURES_HEADER, SYNC_SCOPE_QUERY_PARAM, VERSION, VERSION as VERSION$1, VIEWER_IDENTITY_TARGET_KEYS, VIEWER_SERVICE_DISCRIMINATOR, addSyncScopeToBoundary, analyzeProjectScopeMappingChangeGuardrails, analyzeProjectScopeMappingChangesGuardrails, analyzeProjectScopeMappingDeletionGuardrails, applyLegacyTeamSetupCompletionManifest, applyLegacyTeamSetupCompletionManifestAndReturnActivation, applyLocalIdentitySwitch, applyReplicationOps, areLegacyTeamSetupCompletionPolicyFactsAdditivelyCompatible, assertNoLocalIdentityOverride, automaticRecallHealth, buildAuthHeaders, buildBaseUrl, buildDirectPeerAuthHeaders, buildDistillReport, buildFilterBranchesWithContext, buildFilterClausesWithContext, buildPiFlushSignalFromEvent, buildRawEventEnvelopeFromCodexHook, buildRawEventEnvelopeFromHook, buildRawEventEnvelopeFromPiEvent, buildViewerIdentityTarget, canonicalCoordinatorLegacyTeamCompletionManifestJson, canonicalMemoryKind, canonicalRepositoryProjectIdentity, canonicalWorkspaceIdentity, captureAccountOwnerProfilePins, changeCoordinatorAccount, claimRecipientPolicyActorMutations, claimRecipientPolicyPublicationMutation, classifyRecordedSyncFailure, cleanupNonces, clearLegacyTeamSetupDeviceDecision, clonePromptPackAttempt, coerceObserverCommand, commitDeviceIdentityBindings, commitRecipientPolicyEdges, completeLocalIdentitySwitch, containLegacyTeamSetupCompletionConflict, coordinatorArchiveGroupAction, coordinatorAuthControllerReviewAction, coordinatorCreateAddDeviceInviteAction, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorCreateLegacyTeamCompletionAction, coordinatorCreateScopeAction, coordinatorDisableDeviceAction, coordinatorEnableDeviceAction, coordinatorGetLegacyTeamCompletionAction, coordinatorGrantScopeMembershipAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListConsumedTeamInvitesAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorListLegacyTeamCompletionsAction, coordinatorListReviewedRecipientInviteEvidenceAction, coordinatorListScopeMembershipsAction, coordinatorListScopesAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorRenameGroupAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, coordinatorRevokeScopeMembershipAction, coordinatorStatusSnapshot, coordinatorUnarchiveGroupAction, coordinatorUpdateScopeAction, countShareableProjectMemories, createCoordinatorReciprocalApproval, decodeInvitePayload, dedupeOrderedIds, defaultSpaceScopeIdForGroup, deleteProjectScopeSettingsMapping, deriveLegacyTeamSetupCompletionManifest, detectInstallKind, deterministicPolicyTeamId, diagnoseStalePeerReceivedRows, discoverLegacyTeamCandidates, dispatchFileContextTransport, ensureDeviceIdentity, executeShareProvisioning, extractInvitePayload, extractReplicationOps, filterReplicationOpsForSyncWithStatus, fingerprintPublicKey, formatHostPort, friendlyDeviceName, fromJson, generateWithOpenCodeV2, getCodememConfigPath, getCodememEnvOverrideValues, getCodememEnvOverrides, getCoordinatorEnrollmentReconciliationIssueSummary, getCoordinatorGroupPreference, getEffectiveCachedScopeAuthorization, getLegacyTeamSetupDraft, getRecipientPolicyAuthorityState, getSemanticIndexDiagnostics, getSyncResetState, getUpdateStatus, ingestRawEvents, inspectFreshLegacyTeamSetupActivation, inspectLegacyTeamSetupActivation, inviteTokenDigest, isAutomaticRecallMeasurement, isLegacyTeamCandidateSelectable, isLegacyTeamSetupProjectMappingIdentity, isPeerTrustBindingCompatible, isProjectSyncEnablementError, isScopedSyncCapability, judgeDistillReport, legacyDecisionCountsAsOwner, legacyTeamCandidateId, legacyTeamCandidateProjectInventory, legacyTeamCanonicalProjectRef, legacyTeamDeviceRef, legacyTeamResolvedProjectRef, legacyTeamSetupApiErrorCode, linkCoordinatorAccount, listAuthorizedScopesForPeer, listCoordinatorJoinRequests, listDeviceIdentityInventory, listInboundScopeRejections, listLegacyRecipientPolicyProjections, listMaintenanceJobs, listObserverProviderOptions, listOpenCodeV2Models, listPerPeerScopeSyncState, listProjectScopeCandidates, listProjectScopeInventory, listProjectScopeSettingsMappings, listRecipientPolicyIntent, listRecipientPolicyReview, listSharingDomainSettingsScopes, loadMemorySnapshotPageForPeer, loadPublicKey, loadReplicationOpsForPeer, loadRuntimeSigningPublicKey, lookupCoordinatorPeers, markLocalIdentitySwitchBound, markLocalIdentitySwitchNotCommitted, memoryFilterValueMatchesType, mergeAddresses, migrateRecipientPolicyIntent, mutateCodememConfigFile, negotiateSyncCapability, normalizeAddress, normalizeCoordinatorAccountLinkOrigin, normalizeCoordinatorLegacyTeamCompletionManifest, normalizeHumanPresentationName, normalizeSyncCapability, normalizeSyncFeatures, normalizeTeammateName, parseAcceptedProjectIntent, parseBootstrapExpiry, parseFileContextTransportRequest, parsePositiveMemoryId, parseReassignScopePayload, parseRecipientPolicyEdgeCommitRequest, parseStrictInteger, parseSyncScopeRequest, persistShareOperation, personalScopeGrantStatusForPeer, planShareOperation, previewDeviceIdentityBindings, previewLegacyTeamSetupActivation, previewRecipientPolicyEdges, previewRecipientPolicyOnboarding, previewRecipientPolicyOnboardingFromReviewedIntent, probeAvailableCredentials, projectMatchesFilter, projectShareLifecycle, promptPackArtifactFingerprint, readAccountLinkDevice, readAccountOwnerAssociation, readAccountOwnerAssociationRetainedAtMs, readCodememConfigFile, readCompletedLocalIdentitySwitches, readCoordinatorAccountChangeCapabilities, readCoordinatorAccountLinkStatus, readCoordinatorResolvedAccountOwnerReceiptStatus, readCoordinatorResolvedAccountOwnerStatus, readCoordinatorSyncConfig, readOpenLocalIdentitySwitch, reassignProjectScopeInventoryProject, recipientInviteAuthoritativeIdentityId, recipientPolicyDigest, recipientReviewedIntentDigest, reconcileCoordinatorEnrollmentSnapshot, reconcileRecipientPolicyProject, reconcileShareOperationAcceptance, reconstructLegacyTeamSetupCompletionManifest, recordAutomaticRecall, recordHighestObservedDirectSignatureVersion, recordLocalIdentitySwitch, recordNonce, recordPromptPackArtifacts, recordPromptPackTerminal, refreshAuthorizedCoordinatorPeerTrust, refreshConfiguredScopeMembershipCache, refreshLegacyTeamCandidate, rejectInboundScopeFailures, renameRecipientPolicyTeam, replayLegacyTeamSetupActivation, repositoryIdentitiesByWorkspace, repositoryIdentityForWorkspace, requestJson, requireLegacyTeamSetupAccessDeltaWithinLimit, resolveCodememConfigPath, resolveDbPath, resolveObserverDefaultModel, resolveObserverRuntime, resolveProject, resolveProjectRoot, resolveRecipientPolicyReview, resolveRecipientPolicyReviewBulk, resolveVisibleScopeIds, resumeDeviceRebind, runDeviceRebind, runSyncPass, schema, scopeAuthorizationFailureReason, searchPiSessions, serializeRecipientPolicyCoordinatorGroupMutation, serializeRecipientPolicyPublicationMutation, serializeRecipientPolicyTeamMutation, setLegacyTeamSetupDeviceAssignment, setLegacyTeamSetupDeviceDecision, setLegacyTeamSetupProjectMapping, summarizeInboundScopeRejections, summaryLikeSqlPredicate, supportsSyncFeature, syncScopeResetRequiredPayload, toJson, tryUpdateRetrievalDelivery, updatePeerAddresses, upsertCoordinatorGroupPreference, upsertProjectScopeSettingsMappings, validateLegacyTeamSetupCompletionManifest, validateLegacyTeamSetupCompletionManifestBinding, validateRawEvents, verifyDirectPeerSignature, verifyRecipientReviewedIntent, verifySignature, wakeRecipientPoliciesForIdentities, wakeRecipientPoliciesForProjectIdentities } from "@codemem/core";
|
|
3
|
+
import { ACCESS_CLEANUP_OP_TYPE, CodememConfigMutationError, CoordinatorAccountLinkError, CoordinatorReciprocalApprovalRequestChangedError, DEFAULT_TIME_WINDOW_S, FILE_CONTEXT_TRANSPORT_MAX_BYTES, LEGACY_SHARED_REVIEW_SCOPE_ID, LOCAL_DEFAULT_SCOPE_ID, LOCAL_SYNC_CAPABILITY, LOCAL_SYNC_FEATURES, LegacyTeamSetupAdditiveConvergenceError, LegacyTeamSetupRosterCapacityError, MEMORY_FILTER_FIELD_TYPES, MEMORY_FILTER_NAMES, MEMORY_KIND_DESCRIPTIONS, MemoryStore, ObserverClient, PROMPT_TRANSPORT_PROTOCOL_RANGE, REMEMBER_MEMORY_KINDS, RICH_TIER_ANTHROPIC_DEFAULTS, RICH_TIER_DEFAULTS, RawEventIngestValidationError, RecipientPolicyEdgeRequestError, RecipientPolicyTeamRenameError, RemoteCoordinatorRequestError, SCOPE_MEMBERSHIP_REVOCATION_LIMITATION, SIMPLE_TIER_ANTHROPIC_DEFAULTS, SIMPLE_TIER_DEFAULTS, SYNC_AUTHORIZATION_REFRESH_HEADER, SYNC_CAPABILITY_HEADER, SYNC_FEATURES_HEADER, SYNC_SCOPE_QUERY_PARAM, VERSION, VERSION as VERSION$1, VIEWER_IDENTITY_TARGET_KEYS, VIEWER_SERVICE_DISCRIMINATOR, addSyncScopeToBoundary, analyzeProjectScopeMappingChangeGuardrails, analyzeProjectScopeMappingChangesGuardrails, analyzeProjectScopeMappingDeletionGuardrails, applyLegacyTeamSetupCompletionManifest, applyLegacyTeamSetupCompletionManifestAndReturnActivation, applyLocalIdentitySwitch, applyReplicationOps, areLegacyTeamSetupCompletionPolicyFactsAdditivelyCompatible, assertNoLocalIdentityOverride, automaticRecallHealth, buildAuthHeaders, buildBaseUrl, buildDirectPeerAuthHeaders, buildDistillReport, buildFilterBranchesWithContext, buildFilterClausesWithContext, buildPiFlushSignalFromEvent, buildRawEventEnvelopeFromCodexHook, buildRawEventEnvelopeFromHook, buildRawEventEnvelopeFromPiEvent, buildViewerIdentityTarget, canonicalCoordinatorLegacyTeamCompletionManifestJson, canonicalMemoryKind, canonicalRepositoryProjectIdentity, canonicalWorkspaceIdentity, captureAccountOwnerProfilePins, changeCoordinatorAccount, claimRecipientPolicyActorMutations, claimRecipientPolicyPublicationMutation, classifyRecordedSyncFailure, cleanupNonces, clearLegacyTeamSetupDeviceDecision, clonePromptPackAttempt, coerceObserverCommand, commitDeviceIdentityBindings, commitRecipientPolicyEdges, completeLocalIdentitySwitch, containLegacyTeamSetupCompletionConflict, coordinatorArchiveGroupAction, coordinatorAuthControllerReviewAction, coordinatorCreateAddDeviceInviteAction, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorCreateLegacyTeamCompletionAction, coordinatorCreateScopeAction, coordinatorDisableDeviceAction, coordinatorEnableDeviceAction, coordinatorGetLegacyTeamCompletionAction, coordinatorGrantScopeMembershipAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListConsumedTeamInvitesAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorListLegacyTeamCompletionsAction, coordinatorListReviewedRecipientInviteEvidenceAction, coordinatorListScopeMembershipsAction, coordinatorListScopesAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorRenameGroupAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, coordinatorRevokeScopeMembershipAction, coordinatorStatusSnapshot, coordinatorUnarchiveGroupAction, coordinatorUpdateScopeAction, countShareableProjectMemories, createCoordinatorReciprocalApproval, decodeInvitePayload, dedupeOrderedIds, defaultSpaceScopeIdForGroup, deleteProjectScopeSettingsMapping, deriveLegacyTeamSetupCompletionManifest, detectInstallKind, deterministicPolicyTeamId, diagnoseStalePeerReceivedRows, discoverLegacyTeamCandidates, dispatchFileContextTransport, ensureDeviceIdentity, executeShareProvisioning, extractInvitePayload, extractReplicationOps, filterReplicationOpsForSyncWithStatus, fingerprintPublicKey, formatHostPort, friendlyDeviceName, fromJson, generateWithOpenCodeV2, getCodememConfigPath, getCodememEnvOverrideValues, getCodememEnvOverrides, getCoordinatorEnrollmentReconciliationIssueSummary, getCoordinatorGroupPreference, getEffectiveCachedScopeAuthorization, getLegacyTeamSetupDraft, getRecipientPolicyAuthorityState, getSemanticIndexDiagnostics, getSyncResetState, getUpdateStatus, ingestRawEvents, inspectFreshLegacyTeamSetupActivation, inspectLegacyTeamSetupActivation, inviteTokenDigest, isAutomaticRecallMeasurement, isLegacyTeamCandidateSelectable, isLegacyTeamSetupProjectMappingIdentity, isPeerTrustBindingCompatible, isProjectSyncEnablementError, isScopedSyncCapability, judgeDistillReport, legacyDecisionCountsAsOwner, legacyTeamCandidateId, legacyTeamCandidateProjectInventory, legacyTeamCanonicalProjectRef, legacyTeamDeviceRef, legacyTeamResolvedProjectRef, legacyTeamSetupApiErrorCode, legacyTeamSetupCompletionActorIds, legacyTeamSetupFailureCheck, linkCoordinatorAccount, listAuthorizedScopesForPeer, listCoordinatorJoinRequests, listDeviceIdentityInventory, listInboundScopeRejections, listLegacyRecipientPolicyProjections, listMaintenanceJobs, listObserverProviderOptions, listOpenCodeV2Models, listPerPeerScopeSyncState, listProjectScopeCandidates, listProjectScopeInventory, listProjectScopeSettingsMappings, listRecipientPolicyIntent, listRecipientPolicyReview, listSharingDomainSettingsScopes, loadMemorySnapshotPageForPeer, loadPublicKey, loadReplicationOpsForPeer, loadRuntimeSigningPublicKey, lookupCoordinatorPeers, markLocalIdentitySwitchBound, markLocalIdentitySwitchNotCommitted, memoryFilterValueMatchesType, mergeAddresses, migrateRecipientPolicyIntent, mutateCodememConfigFile, negotiateSyncCapability, normalizeAddress, normalizeCoordinatorAccountLinkOrigin, normalizeCoordinatorLegacyTeamCompletionManifest, normalizeHumanPresentationName, normalizeSyncCapability, normalizeSyncFeatures, normalizeTeammateName, parseAcceptedProjectIntent, parseBootstrapExpiry, parseFileContextTransportRequest, parsePositiveMemoryId, parseReassignScopePayload, parseRecipientPolicyEdgeCommitRequest, parseStrictInteger, parseSyncScopeRequest, persistShareOperation, personalScopeGrantStatusForPeer, planShareOperation, previewDeviceIdentityBindings, previewLegacyTeamSetupActivation, previewRecipientPolicyEdges, previewRecipientPolicyOnboarding, previewRecipientPolicyOnboardingFromReviewedIntent, probeAvailableCredentials, projectMatchesFilter, projectShareLifecycle, promptPackArtifactFingerprint, readAccountLinkDevice, readAccountOwnerAssociation, readAccountOwnerAssociationRetainedAtMs, readCodememConfigFile, readCompletedLocalIdentitySwitches, readCoordinatorAccountChangeCapabilities, readCoordinatorAccountLinkStatus, readCoordinatorResolvedAccountOwnerReceiptStatus, readCoordinatorResolvedAccountOwnerStatus, readCoordinatorSyncConfig, readOpenLocalIdentitySwitch, reassignProjectScopeInventoryProject, recipientInviteAuthoritativeIdentityId, recipientPolicyDigest, recipientReviewedIntentDigest, reconcileCoordinatorEnrollmentSnapshot, reconcileRecipientPolicyProject, reconcileShareOperationAcceptance, reconstructLegacyTeamSetupCompletionManifest, recordAutomaticRecall, recordHighestObservedDirectSignatureVersion, recordLocalIdentitySwitch, recordNonce, recordPromptPackArtifacts, recordPromptPackTerminal, refreshAuthorizedCoordinatorPeerTrust, refreshConfiguredScopeMembershipCache, refreshLegacyTeamCandidate, rejectInboundScopeFailures, renameRecipientPolicyTeam, replayLegacyTeamSetupActivation, repositoryIdentitiesByWorkspace, repositoryIdentityForWorkspace, requestJson, requireLegacyTeamSetupAccessDeltaWithinLimit, resolveCodememConfigPath, resolveDbPath, resolveObserverDefaultModel, resolveObserverRuntime, resolveProject, resolveProjectRoot, resolveRecipientPolicyReview, resolveRecipientPolicyReviewBulk, resolveVisibleScopeIds, resumeDeviceRebind, runDeviceRebind, runSyncPass, schema, scopeAuthorizationFailureReason, searchPiSessions, serializeRecipientPolicyActorMutations, serializeRecipientPolicyCoordinatorGroupMutation, serializeRecipientPolicyPublicationMutation, serializeRecipientPolicyTeamMutation, setLegacyTeamSetupDeviceAssignment, setLegacyTeamSetupDeviceDecision, setLegacyTeamSetupProjectMapping, summarizeInboundScopeRejections, summaryLikeSqlPredicate, supportsSyncFeature, syncScopeResetRequiredPayload, toJson, tryUpdateRetrievalDelivery, updatePeerAddresses, upsertCoordinatorGroupPreference, upsertProjectScopeSettingsMappings, validateLegacyTeamSetupCompletionManifest, validateLegacyTeamSetupCompletionManifestBinding, validateRawEvents, verifyDirectPeerSignature, verifyRecipientReviewedIntent, verifySignature, wakeRecipientPoliciesForIdentities, wakeRecipientPoliciesForProjectIdentities } from "@codemem/core";
|
|
4
4
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
5
5
|
import { Hono } from "hono";
|
|
6
6
|
import { createCipheriv, createDecipheriv, createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -435,11 +435,13 @@ var InProcessAccountLinkRegistry = class {
|
|
|
435
435
|
};
|
|
436
436
|
const intent = job.operation.intent ?? "connect";
|
|
437
437
|
if (intent === "sign_in") return await this.#runSignIn(job, options.onBrowserStart);
|
|
438
|
-
if (intent === "connect")
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
438
|
+
if (intent === "connect") {
|
|
439
|
+
if (expectedAuthority === null) throw new CoordinatorAccountLinkError("invalid_options");
|
|
440
|
+
await (this.#options.link ?? linkCoordinatorAccount)({
|
|
441
|
+
...options,
|
|
442
|
+
expectedAuthority
|
|
443
|
+
});
|
|
444
|
+
} else {
|
|
443
445
|
const result = await (this.#options.change ?? changeCoordinatorAccount)({
|
|
444
446
|
...options,
|
|
445
447
|
intent,
|
|
@@ -481,6 +483,7 @@ var InProcessAccountLinkRegistry = class {
|
|
|
481
483
|
}
|
|
482
484
|
start({ intent = "connect", context, expectedCoordinatorId, expectedAuthority, expectedLifecycleToken, expectedLinkId }) {
|
|
483
485
|
if (this.#shuttingDown) return { error: "account_shutting_down" };
|
|
486
|
+
if (expectedAuthority !== "controller_attestation" && expectedAuthority !== "device_claim" && !(intent === "sign_in" && expectedAuthority === null)) return { error: "account_context_changed" };
|
|
484
487
|
const pending = this.#inProgress();
|
|
485
488
|
if (pending) return pending;
|
|
486
489
|
if (expectedLifecycleToken && expectedLifecycleToken !== this.lifecycleToken()) return { error: "account_context_changed" };
|
|
@@ -791,11 +794,11 @@ function associatedOwnerView(view, context, association, remote) {
|
|
|
791
794
|
//#region src/account/status.ts
|
|
792
795
|
/**
|
|
793
796
|
* The owner-only state offers sign-in when the owner's Google account is
|
|
794
|
-
* linked and this device
|
|
795
|
-
*
|
|
797
|
+
* linked and this device is unlinked or still needs enrollment review.
|
|
798
|
+
* Rebind verifies the Google account before switching the device's Identity.
|
|
796
799
|
*/
|
|
797
800
|
function withOwnerSignIn(owner, own, context, remote) {
|
|
798
|
-
if (owner.ownerProjection?.status.profileState !== "linked" || own.
|
|
801
|
+
if (owner.ownerProjection?.status.profileState !== "linked" || own.remote.kind !== "status" || own.remote.state !== "review_required" && !(own.canSignIn === true && own.remote.state === "unlinked")) return owner;
|
|
799
802
|
return {
|
|
800
803
|
...owner,
|
|
801
804
|
canSignIn: true,
|
|
@@ -1010,7 +1013,10 @@ async function finishAccountStatus(options, context, fresh, remote, read) {
|
|
|
1010
1013
|
const associated = await readAssociatedOwner(options, context, currentView, remote, signal);
|
|
1011
1014
|
if (associated) {
|
|
1012
1015
|
const owner = withOwnerSignIn(associated, currentView, context, remote);
|
|
1013
|
-
if (read.ownIdentityOnly && owner.signIn?.contextId === context.contextId) return attachOperation(
|
|
1016
|
+
if (read.ownIdentityOnly && owner.signIn?.contextId === context.contextId) return attachOperation({
|
|
1017
|
+
...currentView,
|
|
1018
|
+
canSignIn: true
|
|
1019
|
+
}, options.registry);
|
|
1014
1020
|
return attachOperation(owner, options.registry, context.contextId);
|
|
1015
1021
|
}
|
|
1016
1022
|
}
|
|
@@ -1147,7 +1153,7 @@ function isCurrent(options, operation) {
|
|
|
1147
1153
|
return !("error" in fresh) && fresh.setup === "ready" && fresh.context?.groupId === operation.groupId && fresh.context.contextId === operation.contextId;
|
|
1148
1154
|
}
|
|
1149
1155
|
function validStartBody(body) {
|
|
1150
|
-
return body !== null && validString(body.groupId) && validString(body.contextId) && validString(body.coordinatorId) && (body.intent !== "disconnect" || validString(body.expectedLinkId)) && (body.intent === void 0 || body.intent === "connect" || body.intent === "refresh" || body.intent === "disconnect" || body.intent === "sign_in") && (body.authority === "controller_attestation" || body.authority === "device_claim");
|
|
1156
|
+
return body !== null && validString(body.groupId) && validString(body.contextId) && validString(body.coordinatorId) && (body.intent !== "disconnect" || validString(body.expectedLinkId)) && (body.intent === void 0 || body.intent === "connect" || body.intent === "refresh" || body.intent === "disconnect" || body.intent === "sign_in") && (body.authority === "controller_attestation" || body.authority === "device_claim" || body.intent === "sign_in" && body.authority === null);
|
|
1151
1157
|
}
|
|
1152
1158
|
function unlinkTargetChanged(body, view) {
|
|
1153
1159
|
return body.intent === "disconnect" && body.expectedLinkId !== view.unlinkTarget;
|
|
@@ -6354,6 +6360,23 @@ var MAX_PROJECT_MAPPING_METADATA_ROWS = 1e4;
|
|
|
6354
6360
|
var MAX_MUTATION_BODY_BYTES = 8192;
|
|
6355
6361
|
var SUMMARY_SNAPSHOT_CACHE_TTL_MS = 3e4;
|
|
6356
6362
|
var COORDINATOR_ROSTER_READ_BUDGET_MS = 6e4;
|
|
6363
|
+
function serializeCanonicalManifestMutation(store, groupId, manifest, operation) {
|
|
6364
|
+
return serializeRecipientPolicyPublicationMutation(store.db, () => {
|
|
6365
|
+
const actorIds = legacyTeamSetupCompletionActorIds(store.db, manifest);
|
|
6366
|
+
return serializeRecipientPolicyActorMutations(store.db, actorIds, () => serializeRecipientPolicyTeamMutation(store.db, manifest.team_id, () => serializeRecipientPolicyCoordinatorGroupMutation(store.db, groupId, () => operation(actorIds))));
|
|
6367
|
+
});
|
|
6368
|
+
}
|
|
6369
|
+
function finishDraftActorIds(draft) {
|
|
6370
|
+
return draft.devices.flatMap((device) => [...device.decision === "included" && device.targetIdentityId ? [device.targetIdentityId] : [], ...device.existingIdentityId ? [device.existingIdentityId] : []]);
|
|
6371
|
+
}
|
|
6372
|
+
function completionRecipientPolicyLocksHeld(actorIds) {
|
|
6373
|
+
return {
|
|
6374
|
+
publication: true,
|
|
6375
|
+
actors: actorIds,
|
|
6376
|
+
team: true,
|
|
6377
|
+
coordinatorGroup: true
|
|
6378
|
+
};
|
|
6379
|
+
}
|
|
6357
6380
|
var TEAM_SETUP_ROUTE_PREFIX = "/api/sync/team-setup/v1";
|
|
6358
6381
|
var CANDIDATE_REF_PATTERN = /^legacy-team-candidate:[0-9a-f]{32}$/u;
|
|
6359
6382
|
var DEVICE_REF_PATTERN = /^legacy-team-device-ref-v1:[0-9a-f]{64}$/u;
|
|
@@ -6399,6 +6422,47 @@ async function runCandidateMutation(db, candidateRef, operation) {
|
|
|
6399
6422
|
release();
|
|
6400
6423
|
}
|
|
6401
6424
|
}
|
|
6425
|
+
function completionFailureHandlers(options) {
|
|
6426
|
+
const handledGroupIds = /* @__PURE__ */ new Set();
|
|
6427
|
+
const reportFailure = (group, error) => {
|
|
6428
|
+
handledGroupIds.add(group.groupId);
|
|
6429
|
+
options.onFailure?.(group, error);
|
|
6430
|
+
};
|
|
6431
|
+
const handleFailure = (group, error) => {
|
|
6432
|
+
if (!options.isolateApplyFailures) throw error;
|
|
6433
|
+
reportFailure(group, error);
|
|
6434
|
+
};
|
|
6435
|
+
return {
|
|
6436
|
+
handledGroupIds,
|
|
6437
|
+
handleFailure,
|
|
6438
|
+
reportFailure
|
|
6439
|
+
};
|
|
6440
|
+
}
|
|
6441
|
+
function completionConflictError(cause) {
|
|
6442
|
+
return new Error("team_setup_completion_conflict", { cause });
|
|
6443
|
+
}
|
|
6444
|
+
function addFreshCompletionGroups(index, groups, keyOf) {
|
|
6445
|
+
for (const group of groups) {
|
|
6446
|
+
if (!group) continue;
|
|
6447
|
+
const key = keyOf(group);
|
|
6448
|
+
if (index.has(key)) throw new Error("team_setup_completion_invalid");
|
|
6449
|
+
index.set(key, group);
|
|
6450
|
+
}
|
|
6451
|
+
}
|
|
6452
|
+
function groupCompletionFailureHandler(groups, handleFailure) {
|
|
6453
|
+
return (groupId, error) => {
|
|
6454
|
+
const group = groups.get(groupId);
|
|
6455
|
+
if (group) handleFailure(group, error);
|
|
6456
|
+
};
|
|
6457
|
+
}
|
|
6458
|
+
function summaryReconciliationOptions(blockingErrors) {
|
|
6459
|
+
return {
|
|
6460
|
+
isolateApplyFailures: true,
|
|
6461
|
+
onFailure: (group, error) => {
|
|
6462
|
+
blockingErrors.set(legacyTeamCandidateId(group.coordinatorId, group.groupId), apiErrorCode(new Error(completionApiError(error))));
|
|
6463
|
+
}
|
|
6464
|
+
};
|
|
6465
|
+
}
|
|
6402
6466
|
var defaultCompletionDependencies = {
|
|
6403
6467
|
create: coordinatorCreateLegacyTeamCompletionAction,
|
|
6404
6468
|
get: coordinatorGetLegacyTeamCompletionAction,
|
|
@@ -6490,13 +6554,17 @@ function isUnsupportedCompletionQuery(error) {
|
|
|
6490
6554
|
function isUnattributableCompletionBatchError(error) {
|
|
6491
6555
|
return error instanceof Error && (error.message === "coordinator_completion_response_malformed" || error.message === "coordinator_completion_group_mismatch");
|
|
6492
6556
|
}
|
|
6493
|
-
async function listCompletionRecordsPerGroup(groupIds, list) {
|
|
6494
|
-
if (groupIds.length
|
|
6557
|
+
async function listCompletionRecordsPerGroup(groupIds, list, onFailure, batchError) {
|
|
6558
|
+
if (groupIds.length === 1) {
|
|
6559
|
+
onFailure(groupIds[0], batchError);
|
|
6560
|
+
return [];
|
|
6561
|
+
}
|
|
6495
6562
|
const records = [];
|
|
6496
6563
|
for (const groupId of groupIds) try {
|
|
6497
6564
|
records.push(...await list([groupId]));
|
|
6498
6565
|
} catch (error) {
|
|
6499
6566
|
if (!isUnattributableCompletionBatchError(error)) throw error;
|
|
6567
|
+
onFailure(groupId, error);
|
|
6500
6568
|
}
|
|
6501
6569
|
return records;
|
|
6502
6570
|
}
|
|
@@ -6730,6 +6798,55 @@ function candidateFromDraft(draft) {
|
|
|
6730
6798
|
unresolvedProjectCount: draft.unresolvedProjectCount
|
|
6731
6799
|
};
|
|
6732
6800
|
}
|
|
6801
|
+
function blockedCandidateSummary(store, group, blockingError) {
|
|
6802
|
+
const candidateRef = legacyTeamCandidateId(group.coordinatorId, group.groupId);
|
|
6803
|
+
const draft = getLegacyTeamSetupDraft(store.db, candidateRef);
|
|
6804
|
+
if (draft) return {
|
|
6805
|
+
...candidateSummary(candidateFromDraft(draft)),
|
|
6806
|
+
status: "stale",
|
|
6807
|
+
blockingError
|
|
6808
|
+
};
|
|
6809
|
+
const forbiddenIds = [
|
|
6810
|
+
group.coordinatorId,
|
|
6811
|
+
group.groupId,
|
|
6812
|
+
candidateRef,
|
|
6813
|
+
...group.devices.flatMap((device) => [
|
|
6814
|
+
device.deviceId,
|
|
6815
|
+
device.fingerprint,
|
|
6816
|
+
...device.labelRedactionIds ?? []
|
|
6817
|
+
])
|
|
6818
|
+
];
|
|
6819
|
+
return {
|
|
6820
|
+
candidateRef,
|
|
6821
|
+
displayName: safeChoiceLabel(group.displayName, "Legacy Team", forbiddenIds),
|
|
6822
|
+
status: "stale",
|
|
6823
|
+
blockingError,
|
|
6824
|
+
deviceCount: group.devices.length,
|
|
6825
|
+
projectCount: 0,
|
|
6826
|
+
unresolvedDeviceCount: 0,
|
|
6827
|
+
unresolvedProjectCount: 0
|
|
6828
|
+
};
|
|
6829
|
+
}
|
|
6830
|
+
function pendingCandidateSummaries(store, groups, blockingErrors) {
|
|
6831
|
+
const pending = readPureCandidateViews(store, groups.filter((group) => !blockingErrors.has(legacyTeamCandidateId(group.coordinatorId, group.groupId)))).map(candidateSummary).filter((candidate) => candidate.status !== "ready");
|
|
6832
|
+
const blocked = groups.flatMap((group) => {
|
|
6833
|
+
const error = blockingErrors.get(legacyTeamCandidateId(group.coordinatorId, group.groupId));
|
|
6834
|
+
return error ? [blockedCandidateSummary(store, group, error)] : [];
|
|
6835
|
+
});
|
|
6836
|
+
return [...pending, ...blocked].toSorted((left, right) => {
|
|
6837
|
+
if (left.candidateRef < right.candidateRef) return -1;
|
|
6838
|
+
return left.candidateRef > right.candidateRef ? 1 : 0;
|
|
6839
|
+
});
|
|
6840
|
+
}
|
|
6841
|
+
async function reconcileSummaryCandidates(store, groups, reconcile) {
|
|
6842
|
+
readPureCandidateViews(store, groups);
|
|
6843
|
+
const blockingErrors = /* @__PURE__ */ new Map();
|
|
6844
|
+
await reconcile(store, groups, summaryReconciliationOptions(blockingErrors));
|
|
6845
|
+
return {
|
|
6846
|
+
version: TEAM_SETUP_VERSION,
|
|
6847
|
+
candidates: pendingCandidateSummaries(store, groups, blockingErrors)
|
|
6848
|
+
};
|
|
6849
|
+
}
|
|
6733
6850
|
function readPureCandidateViews(store, groups) {
|
|
6734
6851
|
const existing = [];
|
|
6735
6852
|
const discoverable = [];
|
|
@@ -7094,6 +7211,20 @@ function apiErrorCode(error) {
|
|
|
7094
7211
|
const code = legacyTeamSetupApiErrorCode(error);
|
|
7095
7212
|
return code === "team_setup_projection_changed" ? "team_setup_conflict" : code;
|
|
7096
7213
|
}
|
|
7214
|
+
/**
|
|
7215
|
+
* Maps a setup failure to its API code and logs the internal check that raised
|
|
7216
|
+
* it. Dozens of checks share each public code, so the log is the only place an
|
|
7217
|
+
* operator can see which one failed.
|
|
7218
|
+
*/
|
|
7219
|
+
function teamSetupFailure(error, route) {
|
|
7220
|
+
const code = apiErrorCode(error);
|
|
7221
|
+
const check = legacyTeamSetupFailureCheck(error);
|
|
7222
|
+
console.warn(`[team-setup] route=${route} apiCode=${code}${check ? ` check=${check}` : ""}`);
|
|
7223
|
+
return {
|
|
7224
|
+
code,
|
|
7225
|
+
status: errorStatus$1(code)
|
|
7226
|
+
};
|
|
7227
|
+
}
|
|
7097
7228
|
function completionApiError(error) {
|
|
7098
7229
|
const code = legacyTeamSetupApiErrorCode(error);
|
|
7099
7230
|
return code === "team_setup_failed" ? "team_setup_completion_unavailable" : code;
|
|
@@ -7432,29 +7563,26 @@ function teamSetupRoutes(options) {
|
|
|
7432
7563
|
*/
|
|
7433
7564
|
async function applyCanonicalManifestIfStillAuthorized(store, authorization, group, manifest, freshRoster) {
|
|
7434
7565
|
let outcome = "unauthorized";
|
|
7435
|
-
return await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () =>
|
|
7566
|
+
return await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () => serializeCanonicalManifestMutation(store, group.groupId, manifest, async (actorIds) => {
|
|
7436
7567
|
if (!stillAuthorizesGroup(authorization, group)) return;
|
|
7437
7568
|
await applyLegacyTeamSetupCompletionManifest(store.db, {
|
|
7438
7569
|
coordinatorId: group.coordinatorId,
|
|
7439
7570
|
groupId: group.groupId,
|
|
7440
7571
|
manifest,
|
|
7441
7572
|
freshRoster,
|
|
7442
|
-
recipientPolicyLocksHeld:
|
|
7443
|
-
publication: true,
|
|
7444
|
-
team: true,
|
|
7445
|
-
coordinatorGroup: true
|
|
7446
|
-
}
|
|
7573
|
+
recipientPolicyLocksHeld: completionRecipientPolicyLocksHeld(actorIds)
|
|
7447
7574
|
});
|
|
7448
7575
|
outcome = "applied";
|
|
7449
|
-
}))
|
|
7576
|
+
})) ? outcome : "claimed";
|
|
7450
7577
|
}
|
|
7451
7578
|
async function reconcileCompletions(store, groups, reconciliationOptions = {}) {
|
|
7579
|
+
const { handledGroupIds, handleFailure, reportFailure } = completionFailureHandlers(reconciliationOptions);
|
|
7452
7580
|
if (!completionDependencies || groups.length === 0) return;
|
|
7453
7581
|
let authorization;
|
|
7454
7582
|
try {
|
|
7455
7583
|
authorization = currentCompletionAuthorization();
|
|
7456
7584
|
} catch (error) {
|
|
7457
|
-
throw new Error(completionApiError(error));
|
|
7585
|
+
throw new Error(completionApiError(error), { cause: error });
|
|
7458
7586
|
}
|
|
7459
7587
|
if (!authorization) return;
|
|
7460
7588
|
const { config, remoteUrl } = authorization;
|
|
@@ -7476,30 +7604,25 @@ function teamSetupRoutes(options) {
|
|
|
7476
7604
|
records = await listCompletionRecords(scopedGroupIds);
|
|
7477
7605
|
} catch (error) {
|
|
7478
7606
|
if (isUnsupportedCompletionQuery(error)) records = [];
|
|
7479
|
-
else if (reconciliationOptions.isolateApplyFailures && isUnattributableCompletionBatchError(error)) records = await listCompletionRecordsPerGroup(scopedGroupIds, listCompletionRecords);
|
|
7607
|
+
else if (reconciliationOptions.isolateApplyFailures && isUnattributableCompletionBatchError(error)) records = await listCompletionRecordsPerGroup(scopedGroupIds, listCompletionRecords, groupCompletionFailureHandler(groupById, handleFailure), error);
|
|
7480
7608
|
else throw error;
|
|
7481
7609
|
}
|
|
7482
7610
|
const freshGroupByKey = /* @__PURE__ */ new Map();
|
|
7483
7611
|
if (records.length > 0) try {
|
|
7484
7612
|
const onlyGroup = scopedGroups.length === 1 ? scopedGroups[0] : void 0;
|
|
7485
|
-
|
|
7486
|
-
for (const freshGroup of freshGroups) {
|
|
7487
|
-
if (!freshGroup) continue;
|
|
7488
|
-
const key = freshGroupKey(freshGroup);
|
|
7489
|
-
if (freshGroupByKey.has(key)) throw new Error("team_setup_completion_invalid");
|
|
7490
|
-
freshGroupByKey.set(key, freshGroup);
|
|
7491
|
-
}
|
|
7613
|
+
addFreshCompletionGroups(freshGroupByKey, onlyGroup ? [await loadFreshGroupSnapshot(onlyGroup, remoteUrl, reconciliationDeadlineMs)] : await loadedSnapshots(void 0, reconciliationDeadlineMs), freshGroupKey);
|
|
7492
7614
|
} catch (error) {
|
|
7493
7615
|
for (const record of records) {
|
|
7494
7616
|
const group = groupById.get(record.group_id);
|
|
7495
7617
|
if (!group || !belongsToGroupCandidate(record, group)) continue;
|
|
7618
|
+
reportFailure(group, error);
|
|
7496
7619
|
try {
|
|
7497
7620
|
validateLegacyTeamSetupCompletionManifestBinding(record.manifest, {
|
|
7498
7621
|
coordinatorId: group.coordinatorId,
|
|
7499
7622
|
groupId: group.groupId
|
|
7500
7623
|
});
|
|
7501
7624
|
} catch (bindingError) {
|
|
7502
|
-
|
|
7625
|
+
handleFailure(group, bindingError);
|
|
7503
7626
|
continue;
|
|
7504
7627
|
}
|
|
7505
7628
|
let canonicalManifest;
|
|
@@ -7509,16 +7632,17 @@ function teamSetupRoutes(options) {
|
|
|
7509
7632
|
groupId: group.groupId
|
|
7510
7633
|
});
|
|
7511
7634
|
} catch (validationError) {
|
|
7635
|
+
reportFailure(group, validationError);
|
|
7512
7636
|
try {
|
|
7513
7637
|
if (!await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () => containLegacyTeamSetupCompletionConflict(store.db, {
|
|
7514
7638
|
coordinatorId: group.coordinatorId,
|
|
7515
7639
|
groupId: group.groupId
|
|
7516
7640
|
}))) {
|
|
7517
|
-
|
|
7641
|
+
handleFailure(group, validationError);
|
|
7518
7642
|
continue;
|
|
7519
7643
|
}
|
|
7520
7644
|
} catch (containmentError) {
|
|
7521
|
-
|
|
7645
|
+
handleFailure(group, containmentError);
|
|
7522
7646
|
}
|
|
7523
7647
|
if (!reconciliationOptions.isolateApplyFailures) throw validationError;
|
|
7524
7648
|
continue;
|
|
@@ -7534,13 +7658,12 @@ function teamSetupRoutes(options) {
|
|
|
7534
7658
|
groupId: group.groupId
|
|
7535
7659
|
}));
|
|
7536
7660
|
} catch (containmentError) {
|
|
7537
|
-
|
|
7661
|
+
handleFailure(group, containmentError);
|
|
7538
7662
|
}
|
|
7539
7663
|
}
|
|
7540
7664
|
if (!reconciliationOptions.isolateApplyFailures) throw error;
|
|
7541
7665
|
return;
|
|
7542
7666
|
}
|
|
7543
|
-
const coordinatorCompletionGroupIds = /* @__PURE__ */ new Set();
|
|
7544
7667
|
for (const record of records) {
|
|
7545
7668
|
const group = groupById.get(record.group_id);
|
|
7546
7669
|
if (!group) throw new Error("team_setup_completion_invalid");
|
|
@@ -7551,7 +7674,7 @@ function teamSetupRoutes(options) {
|
|
|
7551
7674
|
groupId: group.groupId
|
|
7552
7675
|
});
|
|
7553
7676
|
} catch (bindingError) {
|
|
7554
|
-
|
|
7677
|
+
handleFailure(group, bindingError);
|
|
7555
7678
|
continue;
|
|
7556
7679
|
}
|
|
7557
7680
|
let canonicalManifest;
|
|
@@ -7561,18 +7684,19 @@ function teamSetupRoutes(options) {
|
|
|
7561
7684
|
groupId: group.groupId
|
|
7562
7685
|
});
|
|
7563
7686
|
} catch (validationError) {
|
|
7687
|
+
reportFailure(group, validationError);
|
|
7564
7688
|
try {
|
|
7565
7689
|
await runCandidateMutation(store.db, legacyTeamCandidateId(group.coordinatorId, group.groupId), () => containLegacyTeamSetupCompletionConflict(store.db, {
|
|
7566
7690
|
coordinatorId: group.coordinatorId,
|
|
7567
7691
|
groupId: group.groupId
|
|
7568
7692
|
}));
|
|
7569
7693
|
} catch (containmentError) {
|
|
7570
|
-
|
|
7694
|
+
handleFailure(group, containmentError);
|
|
7571
7695
|
}
|
|
7572
7696
|
if (!reconciliationOptions.isolateApplyFailures) throw validationError;
|
|
7573
7697
|
continue;
|
|
7574
7698
|
}
|
|
7575
|
-
|
|
7699
|
+
handledGroupIds.add(record.group_id);
|
|
7576
7700
|
try {
|
|
7577
7701
|
let freshGroup = freshGroupByKey.get(freshGroupKey(group));
|
|
7578
7702
|
if (!freshGroup && scopedGroups.length > 1) {
|
|
@@ -7584,18 +7708,18 @@ function teamSetupRoutes(options) {
|
|
|
7584
7708
|
coordinatorId: group.coordinatorId,
|
|
7585
7709
|
groupId: group.groupId
|
|
7586
7710
|
}))) {
|
|
7587
|
-
|
|
7711
|
+
handleFailure(group, /* @__PURE__ */ new Error("team_setup_completion_invalid"));
|
|
7588
7712
|
continue;
|
|
7589
7713
|
}
|
|
7590
7714
|
throw new Error("team_setup_completion_invalid");
|
|
7591
7715
|
}
|
|
7592
7716
|
if (await applyCanonicalManifestIfStillAuthorized(store, authorization, group, canonicalManifest, freshGroup.devices) !== "applied") continue;
|
|
7593
7717
|
} catch (error) {
|
|
7594
|
-
|
|
7718
|
+
handleFailure(group, error);
|
|
7595
7719
|
}
|
|
7596
7720
|
}
|
|
7597
7721
|
for (const group of scopedGroups) {
|
|
7598
|
-
if (
|
|
7722
|
+
if (handledGroupIds.has(group.groupId)) continue;
|
|
7599
7723
|
const publicationTimeoutS = remainingCoordinatorTimeoutS(timeoutS, reconciliationDeadlineMs);
|
|
7600
7724
|
if (publicationTimeoutS == null) break;
|
|
7601
7725
|
if (!hasCompletedLegacyTeamSetup(store, legacyTeamCandidateId(group.coordinatorId, group.groupId))) continue;
|
|
@@ -7642,14 +7766,14 @@ function teamSetupRoutes(options) {
|
|
|
7642
7766
|
coordinatorId: group.coordinatorId,
|
|
7643
7767
|
groupId: group.groupId
|
|
7644
7768
|
}))) {
|
|
7645
|
-
|
|
7769
|
+
handleFailure(group, /* @__PURE__ */ new Error("team_setup_completion_conflict"));
|
|
7646
7770
|
continue;
|
|
7647
7771
|
}
|
|
7648
7772
|
} catch (containmentError) {
|
|
7649
|
-
|
|
7773
|
+
handleFailure(group, containmentError);
|
|
7650
7774
|
continue;
|
|
7651
7775
|
}
|
|
7652
|
-
|
|
7776
|
+
handleFailure(group, /* @__PURE__ */ new Error("team_setup_completion_conflict"));
|
|
7653
7777
|
continue;
|
|
7654
7778
|
}
|
|
7655
7779
|
try {
|
|
@@ -7658,7 +7782,7 @@ function teamSetupRoutes(options) {
|
|
|
7658
7782
|
if (await applyCanonicalManifestIfStillAuthorized(store, authorization, group, canonicalManifest, freshGroup.devices) !== "applied") continue;
|
|
7659
7783
|
} catch (applyError) {
|
|
7660
7784
|
if (applyError instanceof LegacyTeamSetupAdditiveConvergenceError) {
|
|
7661
|
-
|
|
7785
|
+
handleFailure(group, applyError);
|
|
7662
7786
|
continue;
|
|
7663
7787
|
}
|
|
7664
7788
|
try {
|
|
@@ -7666,19 +7790,19 @@ function teamSetupRoutes(options) {
|
|
|
7666
7790
|
coordinatorId: group.coordinatorId,
|
|
7667
7791
|
groupId: group.groupId
|
|
7668
7792
|
}))) {
|
|
7669
|
-
|
|
7793
|
+
handleFailure(group, completionConflictError(applyError));
|
|
7670
7794
|
continue;
|
|
7671
7795
|
}
|
|
7672
7796
|
} catch (containmentError) {
|
|
7673
|
-
|
|
7797
|
+
handleFailure(group, containmentError);
|
|
7674
7798
|
continue;
|
|
7675
7799
|
}
|
|
7676
|
-
|
|
7800
|
+
handleFailure(group, completionConflictError(applyError));
|
|
7677
7801
|
}
|
|
7678
7802
|
}
|
|
7679
7803
|
}
|
|
7680
7804
|
} catch (error) {
|
|
7681
|
-
throw new Error(completionApiError(error));
|
|
7805
|
+
throw new Error(completionApiError(error), { cause: error });
|
|
7682
7806
|
}
|
|
7683
7807
|
}
|
|
7684
7808
|
async function loadedCandidateSnapshots(candidateRef, loadOptions = {}) {
|
|
@@ -7712,21 +7836,15 @@ function teamSetupRoutes(options) {
|
|
|
7712
7836
|
try {
|
|
7713
7837
|
groups = await loadedSummarySnapshots();
|
|
7714
7838
|
} catch (error) {
|
|
7715
|
-
const
|
|
7716
|
-
return c.json({ error: code },
|
|
7839
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7840
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7717
7841
|
}
|
|
7718
7842
|
try {
|
|
7719
|
-
const
|
|
7720
|
-
readPureCandidateViews(store, groups);
|
|
7721
|
-
await reconcileCompletions(store, groups, { isolateApplyFailures: true });
|
|
7722
|
-
const response = {
|
|
7723
|
-
version: TEAM_SETUP_VERSION,
|
|
7724
|
-
candidates: readPureCandidateViews(store, groups).map(candidateSummary).filter((candidate) => candidate.status !== "ready")
|
|
7725
|
-
};
|
|
7843
|
+
const response = await reconcileSummaryCandidates(options.getStore(), groups, reconcileCompletions);
|
|
7726
7844
|
return c.json(response);
|
|
7727
7845
|
} catch (error) {
|
|
7728
|
-
const
|
|
7729
|
-
return c.json({ error: code },
|
|
7846
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7847
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7730
7848
|
}
|
|
7731
7849
|
});
|
|
7732
7850
|
app.get("/api/sync/team-setup/v1/:candidateRef", async (c) => {
|
|
@@ -7772,8 +7890,8 @@ function teamSetupRoutes(options) {
|
|
|
7772
7890
|
if (completionGroups) candidate = candidateFromDraft(draft);
|
|
7773
7891
|
return c.json(detailResponse(store, draft, candidate));
|
|
7774
7892
|
} catch (error) {
|
|
7775
|
-
const
|
|
7776
|
-
return c.json({ error: code },
|
|
7893
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7894
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7777
7895
|
}
|
|
7778
7896
|
});
|
|
7779
7897
|
app.put("/api/sync/team-setup/v1/:candidateRef/devices/:deviceRef/assignment", async (c) => {
|
|
@@ -7818,8 +7936,8 @@ function teamSetupRoutes(options) {
|
|
|
7818
7936
|
releaseMutation();
|
|
7819
7937
|
}
|
|
7820
7938
|
} catch (error) {
|
|
7821
|
-
const
|
|
7822
|
-
return c.json({ error: code },
|
|
7939
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7940
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7823
7941
|
}
|
|
7824
7942
|
});
|
|
7825
7943
|
app.put("/api/sync/team-setup/v1/:candidateRef/devices/:deviceRef/decision", async (c) => {
|
|
@@ -7860,8 +7978,8 @@ function teamSetupRoutes(options) {
|
|
|
7860
7978
|
releaseMutation();
|
|
7861
7979
|
}
|
|
7862
7980
|
} catch (error) {
|
|
7863
|
-
const
|
|
7864
|
-
return c.json({ error: code },
|
|
7981
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
7982
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7865
7983
|
}
|
|
7866
7984
|
});
|
|
7867
7985
|
app.delete("/api/sync/team-setup/v1/:candidateRef/devices/:deviceRef/decision", async (c) => {
|
|
@@ -7891,8 +8009,8 @@ function teamSetupRoutes(options) {
|
|
|
7891
8009
|
releaseMutation();
|
|
7892
8010
|
}
|
|
7893
8011
|
} catch (error) {
|
|
7894
|
-
const
|
|
7895
|
-
return c.json({ error: code },
|
|
8012
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8013
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7896
8014
|
}
|
|
7897
8015
|
});
|
|
7898
8016
|
app.put("/api/sync/team-setup/v1/:candidateRef/projects/:projectRef/mapping", async (c) => {
|
|
@@ -7927,8 +8045,8 @@ function teamSetupRoutes(options) {
|
|
|
7927
8045
|
releaseMutation();
|
|
7928
8046
|
}
|
|
7929
8047
|
} catch (error) {
|
|
7930
|
-
const
|
|
7931
|
-
return c.json({ error: code },
|
|
8048
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8049
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7932
8050
|
}
|
|
7933
8051
|
});
|
|
7934
8052
|
app.post("/api/sync/team-setup/v1/:candidateRef/refresh", async (c) => {
|
|
@@ -7941,15 +8059,15 @@ function teamSetupRoutes(options) {
|
|
|
7941
8059
|
store = options.getStore();
|
|
7942
8060
|
if (getLegacyTeamSetupDraft(store.db, candidateRef)?.state === "completed" || hasCompletedLegacyTeamSetup(store, candidateRef)) return c.json({ error: "team_setup_confirmation_stale" }, 409);
|
|
7943
8061
|
} catch (error) {
|
|
7944
|
-
const
|
|
7945
|
-
return c.json({ error: code },
|
|
8062
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8063
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7946
8064
|
}
|
|
7947
8065
|
let groups;
|
|
7948
8066
|
try {
|
|
7949
8067
|
groups = await loadMutableCandidateSnapshots(store, candidateRef, () => loadedCandidateSnapshots(candidateRef));
|
|
7950
8068
|
} catch (error) {
|
|
7951
|
-
const
|
|
7952
|
-
return c.json({ error: code },
|
|
8069
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8070
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7953
8071
|
}
|
|
7954
8072
|
if (groups.filter((group) => legacyTeamCandidateId(group.coordinatorId, group.groupId) === candidateRef).length === 0) return c.json({ error: "team_setup_confirmation_stale" }, 404);
|
|
7955
8073
|
try {
|
|
@@ -7967,8 +8085,8 @@ function teamSetupRoutes(options) {
|
|
|
7967
8085
|
releaseMutation();
|
|
7968
8086
|
}
|
|
7969
8087
|
} catch (error) {
|
|
7970
|
-
const
|
|
7971
|
-
return c.json({ error: code },
|
|
8088
|
+
const failure = teamSetupFailure(error, `${c.req.method} ${c.req.routePath}`);
|
|
8089
|
+
return c.json({ error: failure.code }, failure.status);
|
|
7972
8090
|
}
|
|
7973
8091
|
});
|
|
7974
8092
|
app.post("/api/sync/team-setup/v1/:candidateRef/finish", async (c) => {
|
|
@@ -8040,13 +8158,14 @@ function teamSetupRoutes(options) {
|
|
|
8040
8158
|
if (!claimedDraft || claimedDraft.attemptId !== attemptId) return c.json({ error: "team_setup_confirmation_stale" }, 409);
|
|
8041
8159
|
const publicationDeadlineMs = Date.now() + COORDINATOR_ROSTER_READ_BUDGET_MS;
|
|
8042
8160
|
releasePublicationMutation = await claimRecipientPolicyPublicationMutation(store.db);
|
|
8043
|
-
|
|
8161
|
+
const claimedActorIds = finishDraftActorIds(claimedDraft);
|
|
8162
|
+
releaseActorMutations = await claimRecipientPolicyActorMutations(store.db, claimedActorIds);
|
|
8044
8163
|
return await serializeRecipientPolicyTeamMutation(store.db, deterministicPolicyTeamId(candidateRef), () => serializeRecipientPolicyCoordinatorGroupMutation(store.db, group.groupId, async () => {
|
|
8045
8164
|
let authorization;
|
|
8046
8165
|
try {
|
|
8047
8166
|
authorization = currentCompletionAuthorization();
|
|
8048
8167
|
} catch (error) {
|
|
8049
|
-
throw new Error(completionApiError(error));
|
|
8168
|
+
throw new Error(completionApiError(error), { cause: error });
|
|
8050
8169
|
}
|
|
8051
8170
|
if (!completionDependencies || !authorization) throw new Error("team_setup_completion_unavailable");
|
|
8052
8171
|
if (!authorizesGroup(authorization, group)) throw new Error("team_setup_completion_invalid");
|
|
@@ -8137,11 +8256,7 @@ function teamSetupRoutes(options) {
|
|
|
8137
8256
|
freshRoster: postPublicationGroup.devices,
|
|
8138
8257
|
manifest: canonicalManifest,
|
|
8139
8258
|
expectedDraftManifest: proposedManifest,
|
|
8140
|
-
recipientPolicyLocksHeld:
|
|
8141
|
-
publication: true,
|
|
8142
|
-
team: true,
|
|
8143
|
-
coordinatorGroup: true
|
|
8144
|
-
}
|
|
8259
|
+
recipientPolicyLocksHeld: completionRecipientPolicyLocksHeld(claimedActorIds)
|
|
8145
8260
|
});
|
|
8146
8261
|
return c.json(finishResponse(candidateRef, result));
|
|
8147
8262
|
}));
|