@aglyn/tenant-data-admin 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +7 -0
- package/jest.integration.config.d.ts +39 -0
- package/jest.integration.setup.d.ts +17 -0
- package/package.json +51 -0
- package/src/index.d.ts +17 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/lib/render-cache.d.ts +184 -0
- package/src/lib/render-cache.js +198 -0
- package/src/lib/render-cache.js.map +1 -0
- package/src/lib/server/account-addresses.d.ts +160 -0
- package/src/lib/server/account-addresses.js +311 -0
- package/src/lib/server/account-addresses.js.map +1 -0
- package/src/lib/server/account-emails.d.ts +219 -0
- package/src/lib/server/account-emails.js +640 -0
- package/src/lib/server/account-emails.js.map +1 -0
- package/src/lib/server/admin-audit.d.ts +180 -0
- package/src/lib/server/admin-audit.js +233 -0
- package/src/lib/server/admin-audit.js.map +1 -0
- package/src/lib/server/analytics-retention.d.ts +63 -0
- package/src/lib/server/analytics-retention.js +66 -0
- package/src/lib/server/analytics-retention.js.map +1 -0
- package/src/lib/server/api-http.d.ts +159 -0
- package/src/lib/server/api-http.js +230 -0
- package/src/lib/server/api-http.js.map +1 -0
- package/src/lib/server/api-keys.d.ts +117 -0
- package/src/lib/server/api-keys.js +298 -0
- package/src/lib/server/api-keys.js.map +1 -0
- package/src/lib/server/auth-handoff.d.ts +165 -0
- package/src/lib/server/auth-handoff.js +482 -0
- package/src/lib/server/auth-handoff.js.map +1 -0
- package/src/lib/server/auth-pools.d.ts +246 -0
- package/src/lib/server/auth-pools.js +551 -0
- package/src/lib/server/auth-pools.js.map +1 -0
- package/src/lib/server/billing-addons.d.ts +171 -0
- package/src/lib/server/billing-addons.js +277 -0
- package/src/lib/server/billing-addons.js.map +1 -0
- package/src/lib/server/campaign-attribution-store.d.ts +55 -0
- package/src/lib/server/campaign-attribution-store.js +95 -0
- package/src/lib/server/campaign-attribution-store.js.map +1 -0
- package/src/lib/server/campaign-conversion-attribution.d.ts +205 -0
- package/src/lib/server/campaign-conversion-attribution.js +279 -0
- package/src/lib/server/campaign-conversion-attribution.js.map +1 -0
- package/src/lib/server/client-error-report.d.ts +301 -0
- package/src/lib/server/client-error-report.js +755 -0
- package/src/lib/server/client-error-report.js.map +1 -0
- package/src/lib/server/connect-account-status.d.ts +74 -0
- package/src/lib/server/connect-account-status.js +94 -0
- package/src/lib/server/connect-account-status.js.map +1 -0
- package/src/lib/server/connect-payout-failure.d.ts +103 -0
- package/src/lib/server/connect-payout-failure.js +127 -0
- package/src/lib/server/connect-payout-failure.js.map +1 -0
- package/src/lib/server/console-api-rate-limit.d.ts +81 -0
- package/src/lib/server/console-api-rate-limit.js +111 -0
- package/src/lib/server/console-api-rate-limit.js.map +1 -0
- package/src/lib/server/console-domains.d.ts +326 -0
- package/src/lib/server/console-domains.js +779 -0
- package/src/lib/server/console-domains.js.map +1 -0
- package/src/lib/server/consume-once.d.ts +91 -0
- package/src/lib/server/consume-once.js +96 -0
- package/src/lib/server/consume-once.js.map +1 -0
- package/src/lib/server/contact-company-link.d.ts +85 -0
- package/src/lib/server/contact-company-link.js +105 -0
- package/src/lib/server/contact-company-link.js.map +1 -0
- package/src/lib/server/contact-email-engagement.d.ts +32 -0
- package/src/lib/server/contact-email-engagement.js +145 -0
- package/src/lib/server/contact-email-engagement.js.map +1 -0
- package/src/lib/server/contact-email-index.d.ts +56 -0
- package/src/lib/server/contact-email-index.js +158 -0
- package/src/lib/server/contact-email-index.js.map +1 -0
- package/src/lib/server/contact-lifecycle-floor.d.ts +89 -0
- package/src/lib/server/contact-lifecycle-floor.js +88 -0
- package/src/lib/server/contact-lifecycle-floor.js.map +1 -0
- package/src/lib/server/contact-merge.d.ts +55 -0
- package/src/lib/server/contact-merge.js +279 -0
- package/src/lib/server/contact-merge.js.map +1 -0
- package/src/lib/server/contact-suppression.d.ts +153 -0
- package/src/lib/server/contact-suppression.js +259 -0
- package/src/lib/server/contact-suppression.js.map +1 -0
- package/src/lib/server/crm-booking-activity.d.ts +86 -0
- package/src/lib/server/crm-booking-activity.js +251 -0
- package/src/lib/server/crm-booking-activity.js.map +1 -0
- package/src/lib/server/crm-email-activity.d.ts +112 -0
- package/src/lib/server/crm-email-activity.js +143 -0
- package/src/lib/server/crm-email-activity.js.map +1 -0
- package/src/lib/server/crm-inbound-email.d.ts +145 -0
- package/src/lib/server/crm-inbound-email.js +287 -0
- package/src/lib/server/crm-inbound-email.js.map +1 -0
- package/src/lib/server/crm-next-activity.d.ts +74 -0
- package/src/lib/server/crm-next-activity.js +194 -0
- package/src/lib/server/crm-next-activity.js.map +1 -0
- package/src/lib/server/crm-records.d.ts +144 -0
- package/src/lib/server/crm-records.js +218 -0
- package/src/lib/server/crm-records.js.map +1 -0
- package/src/lib/server/csp-aggregate.d.ts +62 -0
- package/src/lib/server/csp-aggregate.js +276 -0
- package/src/lib/server/csp-aggregate.js.map +1 -0
- package/src/lib/server/data-storage-gate.d.ts +66 -0
- package/src/lib/server/data-storage-gate.js +48 -0
- package/src/lib/server/data-storage-gate.js.map +1 -0
- package/src/lib/server/dataset-live-pages.d.ts +179 -0
- package/src/lib/server/dataset-live-pages.js +421 -0
- package/src/lib/server/dataset-live-pages.js.map +1 -0
- package/src/lib/server/dns-probe.d.ts +53 -0
- package/src/lib/server/dns-probe.js +184 -0
- package/src/lib/server/dns-probe.js.map +1 -0
- package/src/lib/server/document-id.d.ts +29 -0
- package/src/lib/server/document-id.js +100 -0
- package/src/lib/server/document-id.js.map +1 -0
- package/src/lib/server/domain-provider-vercel.d.ts +33 -0
- package/src/lib/server/domain-provider-vercel.js +298 -0
- package/src/lib/server/domain-provider-vercel.js.map +1 -0
- package/src/lib/server/domain-provider-webhook.d.ts +73 -0
- package/src/lib/server/domain-provider-webhook.js +223 -0
- package/src/lib/server/domain-provider-webhook.js.map +1 -0
- package/src/lib/server/domain-provider-wildcard.d.ts +54 -0
- package/src/lib/server/domain-provider-wildcard.js +163 -0
- package/src/lib/server/domain-provider-wildcard.js.map +1 -0
- package/src/lib/server/domain-provider.d.ts +197 -0
- package/src/lib/server/domain-provider.js +221 -0
- package/src/lib/server/domain-provider.js.map +1 -0
- package/src/lib/server/duplicate-activity.d.ts +54 -0
- package/src/lib/server/duplicate-activity.js +67 -0
- package/src/lib/server/duplicate-activity.js.map +1 -0
- package/src/lib/server/duplicate-resource.d.ts +55 -0
- package/src/lib/server/duplicate-resource.js +474 -0
- package/src/lib/server/duplicate-resource.js.map +1 -0
- package/src/lib/server/dynamic-list-materialize.d.ts +153 -0
- package/src/lib/server/dynamic-list-materialize.js +581 -0
- package/src/lib/server/dynamic-list-materialize.js.map +1 -0
- package/src/lib/server/edit-access-authz.d.ts +56 -0
- package/src/lib/server/edit-access-authz.js +107 -0
- package/src/lib/server/edit-access-authz.js.map +1 -0
- package/src/lib/server/edit-access-token.d.ts +72 -0
- package/src/lib/server/edit-access-token.js +116 -0
- package/src/lib/server/edit-access-token.js.map +1 -0
- package/src/lib/server/edit-hint-token.d.ts +83 -0
- package/src/lib/server/edit-hint-token.js +119 -0
- package/src/lib/server/edit-hint-token.js.map +1 -0
- package/src/lib/server/email-delivery-log.d.ts +509 -0
- package/src/lib/server/email-delivery-log.js +1043 -0
- package/src/lib/server/email-delivery-log.js.map +1 -0
- package/src/lib/server/email-flow-gate.d.ts +80 -0
- package/src/lib/server/email-flow-gate.js +153 -0
- package/src/lib/server/email-flow-gate.js.map +1 -0
- package/src/lib/server/email-marketing-gate.d.ts +333 -0
- package/src/lib/server/email-marketing-gate.js +639 -0
- package/src/lib/server/email-marketing-gate.js.map +1 -0
- package/src/lib/server/email-metering.d.ts +293 -0
- package/src/lib/server/email-metering.js +359 -0
- package/src/lib/server/email-metering.js.map +1 -0
- package/src/lib/server/email-revenue-attribution.d.ts +185 -0
- package/src/lib/server/email-revenue-attribution.js +300 -0
- package/src/lib/server/email-revenue-attribution.js.map +1 -0
- package/src/lib/server/email-send-rate.d.ts +232 -0
- package/src/lib/server/email-send-rate.js +417 -0
- package/src/lib/server/email-send-rate.js.map +1 -0
- package/src/lib/server/email-sender-reputation.d.ts +317 -0
- package/src/lib/server/email-sender-reputation.js +464 -0
- package/src/lib/server/email-sender-reputation.js.map +1 -0
- package/src/lib/server/email-suppression.d.ts +490 -0
- package/src/lib/server/email-suppression.js +648 -0
- package/src/lib/server/email-suppression.js.map +1 -0
- package/src/lib/server/email-topic-confirmation.d.ts +150 -0
- package/src/lib/server/email-topic-confirmation.js +272 -0
- package/src/lib/server/email-topic-confirmation.js.map +1 -0
- package/src/lib/server/email-unsubscribe-link.d.ts +174 -0
- package/src/lib/server/email-unsubscribe-link.js +236 -0
- package/src/lib/server/email-unsubscribe-link.js.map +1 -0
- package/src/lib/server/erase-person.d.ts +116 -0
- package/src/lib/server/erase-person.js +272 -0
- package/src/lib/server/erase-person.js.map +1 -0
- package/src/lib/server/erase.d.ts +458 -0
- package/src/lib/server/erase.js +1506 -0
- package/src/lib/server/erase.js.map +1 -0
- package/src/lib/server/firebase-admin.d.ts +71 -0
- package/src/lib/server/firebase-admin.js +343 -0
- package/src/lib/server/firebase-admin.js.map +1 -0
- package/src/lib/server/form-dataset-binding-token.d.ts +35 -0
- package/src/lib/server/form-dataset-binding-token.js +107 -0
- package/src/lib/server/form-dataset-binding-token.js.map +1 -0
- package/src/lib/server/free-workspace-cap.d.ts +201 -0
- package/src/lib/server/free-workspace-cap.js +404 -0
- package/src/lib/server/free-workspace-cap.js.map +1 -0
- package/src/lib/server/ga4-measurement-protocol.d.ts +256 -0
- package/src/lib/server/ga4-measurement-protocol.js +558 -0
- package/src/lib/server/ga4-measurement-protocol.js.map +1 -0
- package/src/lib/server/host-email-tokens.d.ts +47 -0
- package/src/lib/server/host-email-tokens.js +72 -0
- package/src/lib/server/host-email-tokens.js.map +1 -0
- package/src/lib/server/host-memberships.d.ts +54 -0
- package/src/lib/server/host-memberships.js +194 -0
- package/src/lib/server/host-memberships.js.map +1 -0
- package/src/lib/server/host-sending-domain.d.ts +292 -0
- package/src/lib/server/host-sending-domain.js +451 -0
- package/src/lib/server/host-sending-domain.js.map +1 -0
- package/src/lib/server/host-visitor-records.d.ts +150 -0
- package/src/lib/server/host-visitor-records.js +262 -0
- package/src/lib/server/host-visitor-records.js.map +1 -0
- package/src/lib/server/id-token-refusal.d.ts +28 -0
- package/src/lib/server/id-token-refusal.js +111 -0
- package/src/lib/server/id-token-refusal.js.map +1 -0
- package/src/lib/server/legal-acceptance.d.ts +214 -0
- package/src/lib/server/legal-acceptance.js +305 -0
- package/src/lib/server/legal-acceptance.js.map +1 -0
- package/src/lib/server/list-members.d.ts +211 -0
- package/src/lib/server/list-members.js +176 -0
- package/src/lib/server/list-members.js.map +1 -0
- package/src/lib/server/live-page-usage.d.ts +202 -0
- package/src/lib/server/live-page-usage.js +300 -0
- package/src/lib/server/live-page-usage.js.map +1 -0
- package/src/lib/server/lockdown.d.ts +313 -0
- package/src/lib/server/lockdown.js +643 -0
- package/src/lib/server/lockdown.js.map +1 -0
- package/src/lib/server/media-cdn-rate-limit.d.ts +188 -0
- package/src/lib/server/media-cdn-rate-limit.js +204 -0
- package/src/lib/server/media-cdn-rate-limit.js.map +1 -0
- package/src/lib/server/media-delivery.d.ts +267 -0
- package/src/lib/server/media-delivery.js +485 -0
- package/src/lib/server/media-delivery.js.map +1 -0
- package/src/lib/server/media-download-tokens.d.ts +161 -0
- package/src/lib/server/media-download-tokens.js +386 -0
- package/src/lib/server/media-download-tokens.js.map +1 -0
- package/src/lib/server/media-quarantine.d.ts +127 -0
- package/src/lib/server/media-quarantine.js +170 -0
- package/src/lib/server/media-quarantine.js.map +1 -0
- package/src/lib/server/media-signing.d.ts +126 -0
- package/src/lib/server/media-signing.js +159 -0
- package/src/lib/server/media-signing.js.map +1 -0
- package/src/lib/server/media-storage-path.d.ts +96 -0
- package/src/lib/server/media-storage-path.js +111 -0
- package/src/lib/server/media-storage-path.js.map +1 -0
- package/src/lib/server/media-strong-digest.d.ts +85 -0
- package/src/lib/server/media-strong-digest.js +190 -0
- package/src/lib/server/media-strong-digest.js.map +1 -0
- package/src/lib/server/media-tombstone.d.ts +276 -0
- package/src/lib/server/media-tombstone.js +421 -0
- package/src/lib/server/media-tombstone.js.map +1 -0
- package/src/lib/server/media-variants.d.ts +309 -0
- package/src/lib/server/media-variants.js +428 -0
- package/src/lib/server/media-variants.js.map +1 -0
- package/src/lib/server/member-email-aliases.d.ts +180 -0
- package/src/lib/server/member-email-aliases.js +420 -0
- package/src/lib/server/member-email-aliases.js.map +1 -0
- package/src/lib/server/member-photo.d.ts +88 -0
- package/src/lib/server/member-photo.js +185 -0
- package/src/lib/server/member-photo.js.map +1 -0
- package/src/lib/server/membership-recover-throttle.d.ts +211 -0
- package/src/lib/server/membership-recover-throttle.js +231 -0
- package/src/lib/server/membership-recover-throttle.js.map +1 -0
- package/src/lib/server/notifications.d.ts +55 -0
- package/src/lib/server/notifications.js +134 -0
- package/src/lib/server/notifications.js.map +1 -0
- package/src/lib/server/org-billing.d.ts +97 -0
- package/src/lib/server/org-billing.js +236 -0
- package/src/lib/server/org-billing.js.map +1 -0
- package/src/lib/server/organizations.d.ts +837 -0
- package/src/lib/server/organizations.js +1814 -0
- package/src/lib/server/organizations.js.map +1 -0
- package/src/lib/server/password-reset-throttle.d.ts +84 -0
- package/src/lib/server/password-reset-throttle.js +102 -0
- package/src/lib/server/password-reset-throttle.js.map +1 -0
- package/src/lib/server/personal-data-export.d.ts +241 -0
- package/src/lib/server/personal-data-export.js +858 -0
- package/src/lib/server/personal-data-export.js.map +1 -0
- package/src/lib/server/platform-domain-names.d.ts +62 -0
- package/src/lib/server/platform-domain-names.js +197 -0
- package/src/lib/server/platform-domain-names.js.map +1 -0
- package/src/lib/server/platform-marketing-consent.d.ts +133 -0
- package/src/lib/server/platform-marketing-consent.js +209 -0
- package/src/lib/server/platform-marketing-consent.js.map +1 -0
- package/src/lib/server/rate-limit-store.d.ts +702 -0
- package/src/lib/server/rate-limit-store.js +1220 -0
- package/src/lib/server/rate-limit-store.js.map +1 -0
- package/src/lib/server/realm-plugins.d.ts +67 -0
- package/src/lib/server/realm-plugins.js +250 -0
- package/src/lib/server/realm-plugins.js.map +1 -0
- package/src/lib/server/recaptcha-allowlist.d.ts +90 -0
- package/src/lib/server/recaptcha-allowlist.js +409 -0
- package/src/lib/server/recaptcha-allowlist.js.map +1 -0
- package/src/lib/server/release-flags.d.ts +105 -0
- package/src/lib/server/release-flags.js +183 -0
- package/src/lib/server/release-flags.js.map +1 -0
- package/src/lib/server/replay-erasures.d.ts +126 -0
- package/src/lib/server/replay-erasures.js +217 -0
- package/src/lib/server/replay-erasures.js.map +1 -0
- package/src/lib/server/resolve-people.d.ts +66 -0
- package/src/lib/server/resolve-people.js +112 -0
- package/src/lib/server/resolve-people.js.map +1 -0
- package/src/lib/server/safe-equal.d.ts +45 -0
- package/src/lib/server/safe-equal.js +58 -0
- package/src/lib/server/safe-equal.js.map +1 -0
- package/src/lib/server/sending-domain-debt.d.ts +127 -0
- package/src/lib/server/sending-domain-debt.js +268 -0
- package/src/lib/server/sending-domain-debt.js.map +1 -0
- package/src/lib/server/sending-domain-recheck.d.ts +151 -0
- package/src/lib/server/sending-domain-recheck.js +253 -0
- package/src/lib/server/sending-domain-recheck.js.map +1 -0
- package/src/lib/server/sending-domains.d.ts +364 -0
- package/src/lib/server/sending-domains.js +683 -0
- package/src/lib/server/sending-domains.js.map +1 -0
- package/src/lib/server/serve-media-cdn.d.ts +433 -0
- package/src/lib/server/serve-media-cdn.js +1370 -0
- package/src/lib/server/serve-media-cdn.js.map +1 -0
- package/src/lib/server/serve-plugin-fetch.d.ts +61 -0
- package/src/lib/server/serve-plugin-fetch.js +294 -0
- package/src/lib/server/serve-plugin-fetch.js.map +1 -0
- package/src/lib/server/sms-keywords.d.ts +63 -0
- package/src/lib/server/sms-keywords.js +146 -0
- package/src/lib/server/sms-keywords.js.map +1 -0
- package/src/lib/server/sso-break-glass-owners.d.ts +91 -0
- package/src/lib/server/sso-break-glass-owners.js +227 -0
- package/src/lib/server/sso-break-glass-owners.js.map +1 -0
- package/src/lib/server/sso-domain-policy.d.ts +140 -0
- package/src/lib/server/sso-domain-policy.js +239 -0
- package/src/lib/server/sso-domain-policy.js.map +1 -0
- package/src/lib/server/sso-drift-logic.d.ts +106 -0
- package/src/lib/server/sso-drift-logic.js +95 -0
- package/src/lib/server/sso-drift-logic.js.map +1 -0
- package/src/lib/server/sso-enforcement.d.ts +204 -0
- package/src/lib/server/sso-enforcement.js +309 -0
- package/src/lib/server/sso-enforcement.js.map +1 -0
- package/src/lib/server/sso-provisioning.d.ts +320 -0
- package/src/lib/server/sso-provisioning.js +715 -0
- package/src/lib/server/sso-provisioning.js.map +1 -0
- package/src/lib/server/staff-alert-email.d.ts +41 -0
- package/src/lib/server/staff-alert-email.js +63 -0
- package/src/lib/server/staff-alert-email.js.map +1 -0
- package/src/lib/server/stripe-account-mode.d.ts +156 -0
- package/src/lib/server/stripe-account-mode.js +162 -0
- package/src/lib/server/stripe-account-mode.js.map +1 -0
- package/src/lib/server/tenant-write-lockdown.d.ts +131 -0
- package/src/lib/server/tenant-write-lockdown.js +176 -0
- package/src/lib/server/tenant-write-lockdown.js.map +1 -0
- package/src/lib/server/test-firestore.d.ts +45 -0
- package/src/lib/server/test-firestore.js +124 -0
- package/src/lib/server/test-firestore.js.map +1 -0
- package/src/lib/server/token-revocation.d.ts +140 -0
- package/src/lib/server/token-revocation.js +255 -0
- package/src/lib/server/token-revocation.js.map +1 -0
- package/src/lib/server/update-existing.d.ts +32 -0
- package/src/lib/server/update-existing.js +73 -0
- package/src/lib/server/update-existing.js.map +1 -0
- package/src/lib/server/upload-cors-reconcile.d.ts +118 -0
- package/src/lib/server/upload-cors-reconcile.js +234 -0
- package/src/lib/server/upload-cors-reconcile.js.map +1 -0
- package/src/lib/server/upsert-contact.d.ts +262 -0
- package/src/lib/server/upsert-contact.js +546 -0
- package/src/lib/server/upsert-contact.js.map +1 -0
- package/src/lib/server/usage-invoice.d.ts +203 -0
- package/src/lib/server/usage-invoice.js +397 -0
- package/src/lib/server/usage-invoice.js.map +1 -0
- package/src/lib/server/user-profiles.d.ts +151 -0
- package/src/lib/server/user-profiles.js +364 -0
- package/src/lib/server/user-profiles.js.map +1 -0
- package/src/lib/server/vercel-drain-signature.d.ts +30 -0
- package/src/lib/server/vercel-drain-signature.js +61 -0
- package/src/lib/server/vercel-drain-signature.js.map +1 -0
- package/src/lib/server/vercel-log-drain.d.ts +259 -0
- package/src/lib/server/vercel-log-drain.js +479 -0
- package/src/lib/server/vercel-log-drain.js.map +1 -0
- package/src/lib/server/verify-email-cooldown.d.ts +102 -0
- package/src/lib/server/verify-email-cooldown.js +114 -0
- package/src/lib/server/verify-email-cooldown.js.map +1 -0
- package/src/lib/server/visitor-write-rate-limit.d.ts +87 -0
- package/src/lib/server/visitor-write-rate-limit.js +117 -0
- package/src/lib/server/visitor-write-rate-limit.js.map +1 -0
- package/src/lib/server/workspace-domains.d.ts +156 -0
- package/src/lib/server/workspace-domains.js +271 -0
- package/src/lib/server/workspace-domains.js.map +1 -0
- package/src/tenancy.d.ts +115 -0
- package/src/tenancy.js +142 -0
- package/src/tenancy.js.map +1 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type AccountAddressSet, type AccountAddressSource } from './account-addresses';
|
|
18
|
+
import { type PluginUserErasureReport } from '@aglyn/aglyn/plugin-manager/plugin-user-erasure';
|
|
19
|
+
import { type PluginOrgErasureReport } from '@aglyn/aglyn/plugin-manager/plugin-org-erasure';
|
|
20
|
+
import { type SendingDomainDisposition, type TeardownSendingDomainDriver } from './sending-domain-debt';
|
|
21
|
+
/** The reversible hold before a requested erasure is executed (AGL-485). */
|
|
22
|
+
export declare const ERASURE_HOLD_MS: number;
|
|
23
|
+
/**
|
|
24
|
+
* Permanently erase a single site and everything it owns (AGL-488).
|
|
25
|
+
* Unlike deleting the host doc alone (which orphans data), this cleans up
|
|
26
|
+
* every trailing reference:
|
|
27
|
+
* - Storage objects under `hosts/{hostId}/` (media, CDN variants),
|
|
28
|
+
* - the `hostIndex/{hostId}` routing entry (subdomain/cname resolution),
|
|
29
|
+
* - the owning org's `hosts` routing-map entry, and
|
|
30
|
+
* - the host's Firestore tree (screens, layouts, versions, counters, …)
|
|
31
|
+
* via `recursiveDelete`.
|
|
32
|
+
*
|
|
33
|
+
* Shared by the self-serve delete-site route and the org-erasure pipeline
|
|
34
|
+
* (AGL-487). Fail-soft on Storage/index cleanup so a partial failure never
|
|
35
|
+
* blocks the Firestore delete; safe to re-run.
|
|
36
|
+
*/
|
|
37
|
+
export interface EraseHostOptions {
|
|
38
|
+
/**
|
|
39
|
+
* The console-side sending-domain teardown, injected because this library
|
|
40
|
+
* may not hold the credentials it needs — see `sending-domain-debt.ts`.
|
|
41
|
+
*
|
|
42
|
+
* Absent, the site's domain is not released inline: the debt is recorded on
|
|
43
|
+
* the surviving label claim and `/api/admin/reap-sending-domains` settles
|
|
44
|
+
* it. That is the only correct default here. A library the tenant runtime
|
|
45
|
+
* imports cannot reach a full-access mail credential, and an erasure must
|
|
46
|
+
* not fail or stall because a vendor is unreachable.
|
|
47
|
+
*/
|
|
48
|
+
tearDownSendingDomain?: TeardownSendingDomainDriver | null;
|
|
49
|
+
}
|
|
50
|
+
export interface EraseHostResult {
|
|
51
|
+
/** What became of the site's dedicated sending domain, if it had one. */
|
|
52
|
+
sendingDomain: SendingDomainDisposition;
|
|
53
|
+
}
|
|
54
|
+
export declare function eraseHost(hostId: string, options?: EraseHostOptions): Promise<EraseHostResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Delete a single resource document *and everything under it* (AGL-945).
|
|
57
|
+
*
|
|
58
|
+
* Firestore does not cascade: deleting `orgs/{o}/datasets/{d}` leaves every
|
|
59
|
+
* `records/{r}` beneath it alive but unreachable from the console — still
|
|
60
|
+
* billed, still matched by the rules (which match subcollection paths
|
|
61
|
+
* independently of the parent), and resurrected wholesale if the parent id
|
|
62
|
+
* is ever reused. Only the Admin SDK has `recursiveDelete`, so the console
|
|
63
|
+
* cards route their deletes through /api/resources/erase, which lands here.
|
|
64
|
+
*
|
|
65
|
+
* Authorization belongs to the caller — this only walks the tree.
|
|
66
|
+
*/
|
|
67
|
+
export declare function eraseSubtree(path: readonly [string, string, string, string]): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* What an erasure did with `publisherProfiles/{orgId}` (AGL-1970).
|
|
70
|
+
*
|
|
71
|
+
* Three outcomes rather than a boolean, because the third one is a decision
|
|
72
|
+
* the audit row has to be able to state: a listing the erased org published
|
|
73
|
+
* can outlive it, and a listing whose publisher document is simply gone is
|
|
74
|
+
* unattributable in a way nobody chose.
|
|
75
|
+
*/
|
|
76
|
+
export type PublisherProfileDisposition = 'absent' | 'deleted' | 'tombstoned';
|
|
77
|
+
/**
|
|
78
|
+
* The two things an OPERATOR needs that a served caller does not (AGL-1481).
|
|
79
|
+
*
|
|
80
|
+
* `tools/scripts/erase-tenant.mjs` is the manual path staff reach for when the
|
|
81
|
+
* cron is stuck. It used to be a second implementation of this function, and it
|
|
82
|
+
* drifted: by the time AGL-1481 was filed it was missing four sweeps added that
|
|
83
|
+
* week and still wrote a complete dump of the workspace to the operator's
|
|
84
|
+
* working directory. The fix is that it CALLS this function — which means the
|
|
85
|
+
* capabilities it had and this function lacked have to live here instead.
|
|
86
|
+
*
|
|
87
|
+
* Neither is a hold bypass, deliberately. The script refused to run before the
|
|
88
|
+
* 7-day hold elapsed and this function refuses too; an `ignoreHold` flag would
|
|
89
|
+
* have been the easy way to keep the two paths identical and is the one
|
|
90
|
+
* difference worth preserving as a refusal on both.
|
|
91
|
+
*/
|
|
92
|
+
export interface EraseOrgOptions {
|
|
93
|
+
/**
|
|
94
|
+
* Count what an erasure WOULD destroy and destroy nothing. Every sweep runs
|
|
95
|
+
* its query and skips its write, so the plan is produced by the same list of
|
|
96
|
+
* sweeps that the erasure is — a separate counting pass would be exactly the
|
|
97
|
+
* second enumeration this issue removed. Nothing external is touched (no
|
|
98
|
+
* Storage, no Stripe, no Vercel, no DNS) and no audit row is written.
|
|
99
|
+
*
|
|
100
|
+
* Returns `ok: false` with `skippedReason: 'dry-run'`: `ok` means the org was
|
|
101
|
+
* erased, and a plan did not erase it. A caller that treats a plan as an
|
|
102
|
+
* erasure is the one mistake this shape has to make impossible.
|
|
103
|
+
*/
|
|
104
|
+
dryRun?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Who is answerable for this erasure, for the audit row. Defaults to the
|
|
107
|
+
* cron. A staff member running the script by hand is not the scheduler, and
|
|
108
|
+
* an erasure trail that says otherwise names the wrong actor for the single
|
|
109
|
+
* most irreversible action the platform performs.
|
|
110
|
+
*/
|
|
111
|
+
actorUid?: string;
|
|
112
|
+
/**
|
|
113
|
+
* The console-side sending-domain teardown, passed through to every host
|
|
114
|
+
* this erasure destroys. See {@link EraseHostOptions.tearDownSendingDomain}.
|
|
115
|
+
*
|
|
116
|
+
* Never consulted on a dry run: a plan touches no vendor.
|
|
117
|
+
*/
|
|
118
|
+
tearDownSendingDomain?: TeardownSendingDomainDriver | null;
|
|
119
|
+
/**
|
|
120
|
+
* Erase a workspace that carries NO erasure request at all (AGL-2585).
|
|
121
|
+
*
|
|
122
|
+
* ⛔ EXACTLY ONE CALLER, and the option exists so that caller has to say so
|
|
123
|
+
* out loud. `/api/admin/reap-unverified-orgs` collects workspaces created by
|
|
124
|
+
* a signup whose address was never confirmed — there is nobody to ask for an
|
|
125
|
+
* erasure, because nobody has been shown to exist. Every other path reaches
|
|
126
|
+
* this function through `erasureRequestedAt`, which is a person's decision
|
|
127
|
+
* with a seven-day hold on it, and none of them passes this.
|
|
128
|
+
*
|
|
129
|
+
* What it turns off is narrow and named: the `no-request` refusal and the
|
|
130
|
+
* hold, and nothing else. Every sweep, every audit row and `dryRun` behave
|
|
131
|
+
* identically — the caller supplies the proof that this workspace is
|
|
132
|
+
* nobody's, and this records WHAT that proof was on the audit row.
|
|
133
|
+
*
|
|
134
|
+
* It does not skip the request when one exists. An org somebody has already
|
|
135
|
+
* asked to erase is still that person's decision, and the reaper refuses
|
|
136
|
+
* such an org before it ever gets here.
|
|
137
|
+
*/
|
|
138
|
+
withoutRequest?: {
|
|
139
|
+
reason: string;
|
|
140
|
+
} | null;
|
|
141
|
+
}
|
|
142
|
+
export interface EraseOrgResult {
|
|
143
|
+
ok: boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Set when the org was NOT erased (flag missing, hold not elapsed, gone) —
|
|
146
|
+
* and `'dry-run'` when nothing was erased because nothing was meant to be.
|
|
147
|
+
*/
|
|
148
|
+
skippedReason?: string;
|
|
149
|
+
hosts?: number;
|
|
150
|
+
/** Member back-references cleaned up — reported so a plan can show them. */
|
|
151
|
+
members?: number;
|
|
152
|
+
/** API credentials destroyed (AGL-1444) — outside the org path. */
|
|
153
|
+
apiKeys?: number;
|
|
154
|
+
/**
|
|
155
|
+
* What each plugin's workspace eraser did (AGL-2978), keyed by plugin id:
|
|
156
|
+
* counts and flags, such as grants revoked at a provider. The erasers run
|
|
157
|
+
* before anything below is deleted. **`null` means that plugin's eraser
|
|
158
|
+
* failed** and its share may not be done; it is not zero. A plan carries
|
|
159
|
+
* each eraser's count of what it would do.
|
|
160
|
+
*/
|
|
161
|
+
plugins?: Record<string, PluginOrgErasureReport | null>;
|
|
162
|
+
/** Outreach mailbox grants destroyed (AGL-2974) — outside the org path. */
|
|
163
|
+
outreachMailboxCredentials?: number;
|
|
164
|
+
/** Public SSO routing docs destroyed (AGL-1448) — outside the org path. */
|
|
165
|
+
ssoDomains?: number;
|
|
166
|
+
/** Custom console domains released (AGL-1448) — outside the org path. */
|
|
167
|
+
consoleDomains?: number;
|
|
168
|
+
/** REST API replay keys destroyed (AGL-1448) — no TTL reaps these. */
|
|
169
|
+
apiIdempotency?: number;
|
|
170
|
+
/** Local Stripe reverse-index rows destroyed (AGL-1448/AGL-1028). */
|
|
171
|
+
stripeIndex?: number;
|
|
172
|
+
/** Slugs released — the current one AND every tombstone (AGL-1448). */
|
|
173
|
+
slugs?: number;
|
|
174
|
+
/**
|
|
175
|
+
* ORPHANED `hostIndex` rows collected (AGL-1448) — ones with no surviving
|
|
176
|
+
* `hosts` document for the per-host loop to reach them through.
|
|
177
|
+
*/
|
|
178
|
+
hostIndex?: number;
|
|
179
|
+
/**
|
|
180
|
+
* `hostMemberships` projections collected (AGL-1448), including FORMER
|
|
181
|
+
* members' rows that no membership list names.
|
|
182
|
+
*
|
|
183
|
+
* `null` means the sweep could not RUN — almost always the missing
|
|
184
|
+
* `COLLECTION_GROUP` index on `hostMemberships.orgId`. Deliberately not
|
|
185
|
+
* `0`: an erasure that could not reach a collection must not report the
|
|
186
|
+
* same number as one that reached it and found nothing.
|
|
187
|
+
*/
|
|
188
|
+
hostMemberships?: number | null;
|
|
189
|
+
/** Marketplace handle reservations released (AGL-1970) — id-keyed, public. */
|
|
190
|
+
publisherHandles?: number;
|
|
191
|
+
/** What became of the org's public publisher profile (AGL-1970). */
|
|
192
|
+
publisherProfile?: PublisherProfileDisposition;
|
|
193
|
+
/**
|
|
194
|
+
* Marketplace listings that OUTLIVE this erasure and still name the org
|
|
195
|
+
* (AGL-1970/AGL-1448 Tier 3). Reported rather than deleted: an erasure that
|
|
196
|
+
* leaves something standing has to say so, and this is the number that makes
|
|
197
|
+
* the parked listing-survival decision cost something measurable.
|
|
198
|
+
*/
|
|
199
|
+
listingsRetained?: number;
|
|
200
|
+
/**
|
|
201
|
+
* Support threads destroyed, each with its `messages` subtree (AGL-1971) —
|
|
202
|
+
* the highest-PII-density collection outside the org path.
|
|
203
|
+
*/
|
|
204
|
+
supportTickets?: number;
|
|
205
|
+
/**
|
|
206
|
+
* What became of the erased sites' dedicated sending domains.
|
|
207
|
+
*
|
|
208
|
+
* `deferred` is the number an operator reads: those provider slots and zone
|
|
209
|
+
* records are still held, the debt is on each label claim, and
|
|
210
|
+
* `/api/admin/reap-sending-domains` is what settles them. The erasure itself
|
|
211
|
+
* is complete either way — a vendor outage may delay a slot's release and
|
|
212
|
+
* may not delay a deletion somebody has a legal right to.
|
|
213
|
+
*/
|
|
214
|
+
sendingDomains?: {
|
|
215
|
+
released: number;
|
|
216
|
+
deferred: number;
|
|
217
|
+
/** Shared pool members refused. Always 0; a non-zero is a real alarm. */
|
|
218
|
+
protected: number;
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Permanently erase an organization once its 7-day hold has elapsed
|
|
223
|
+
* (AGL-485/487). Runs from the automated cron and the manual staff path.
|
|
224
|
+
*
|
|
225
|
+
* **Both of those are literally this function (AGL-1481).** The manual path,
|
|
226
|
+
* `tools/scripts/erase-tenant.mjs`, used to be a second implementation, and a
|
|
227
|
+
* second implementation of a cascade delete is a divergence with a schedule:
|
|
228
|
+
* within a week of `eraseOrgApiKeys`, the SSO/console-domain release and the
|
|
229
|
+
* org-keyed index sweeps landing here, the script was missing all four and
|
|
230
|
+
* reporting success without them — leaving a live API credential, live domain
|
|
231
|
+
* reservations, `orgSlugs` tombstones and the `stripeCustomers` reverse index
|
|
232
|
+
* behind an erasure a human had been told was complete. The script now calls
|
|
233
|
+
* this, and `EraseOrgOptions` is where the two capabilities it had and this
|
|
234
|
+
* did not (a plan, and a named actor) live instead.
|
|
235
|
+
*
|
|
236
|
+
* Order matters and every step is defensive:
|
|
237
|
+
* 1. Re-read the org and re-verify erasureRequestedAt + hold — never
|
|
238
|
+
* delete on a stale/cancelled request.
|
|
239
|
+
* 2. Nothing is written. This step used to persist a final JSON export of
|
|
240
|
+
* the org and host trees to `erasures/{orgId}/…` and abort if it could
|
|
241
|
+
* not — see the note below for why it is gone (AGL-1443).
|
|
242
|
+
* 3. Revoke the org's API credentials (AGL-1444), its public routing — SSO
|
|
243
|
+
* domains and custom console domains (AGL-1448) — and its public
|
|
244
|
+
* marketplace identity: the publisher profile and every handle it
|
|
245
|
+
* reserved (AGL-1970); and destroy the OAuth grants behind its reps'
|
|
246
|
+
* Outreach mailboxes (AGL-2974). All of them are top-level collections
|
|
247
|
+
* keyed by something other than a path under the org, so the org-tree
|
|
248
|
+
* delete cannot reach them; doing them before the content delete also
|
|
249
|
+
* closes the mid-erasure window, in which a credential, a domain or a
|
|
250
|
+
* public publisher page still resolves to a half-deleted workspace.
|
|
251
|
+
* 4. Delete each host (eraseHost), org-level Storage, the Stripe customer
|
|
252
|
+
* AND its local reverse index, member back-references, then the org tree
|
|
253
|
+
* and every slug the org ever held — tombstones included (AGL-1448).
|
|
254
|
+
* 5. Audit.
|
|
255
|
+
*
|
|
256
|
+
* Every ending is audited, not just the successful one (AGL-1455). A throw
|
|
257
|
+
* from any step writes an `org.erase-failed` row before re-throwing, because
|
|
258
|
+
* `erasureRequestedAt` stays set on a failure: without a record the org is
|
|
259
|
+
* retried and fails identically on every subsequent run, forever, and nothing
|
|
260
|
+
* anywhere says so.
|
|
261
|
+
*
|
|
262
|
+
* **The erasure writes no copy of the workspace (AGL-1443).** It used to
|
|
263
|
+
* persist `erasures/{orgId}/{requestedMs}.json` — and "export" understated
|
|
264
|
+
* it: `exportDocTree` recursed `listCollections()` with no bound and copied
|
|
265
|
+
* `snapshot.data()` wholesale, so the object was a complete verbatim copy of
|
|
266
|
+
* the org tree and every host tree, carrying `webhooks.secret` (a plaintext
|
|
267
|
+
* HMAC key), `orders.paymentLinkUrl` (a live bearer URL that lets its holder
|
|
268
|
+
* pay), `screens.protection.passwordHash` and `ssoDomains.token`. It landed
|
|
269
|
+
* on a prefix this function's own storage sweep does not cover, in a bucket
|
|
270
|
+
* with no lifecycle rule, so the most sensitive object the platform can
|
|
271
|
+
* produce outlived the request that deleted everything else — indefinitely,
|
|
272
|
+
* unread, and belonging to a customer who had been told their workspace was
|
|
273
|
+
* gone. Four facts decided it, and none of them is about tidiness:
|
|
274
|
+
*
|
|
275
|
+
* - **Nothing read it.** One producer, zero consumers in the repo; the
|
|
276
|
+
* owner's confirmation email never mentioned it.
|
|
277
|
+
* - **A governed full copy already exists.** Firestore backups run weekly
|
|
278
|
+
* with 14-week retention (AGL-871), so the dump added no recoverability —
|
|
279
|
+
* only a second, ungoverned place the data lived.
|
|
280
|
+
* - **The minimum that proves an erasure was already being written.** The
|
|
281
|
+
* `adminAudit` row below is ids and counts, in a collection with a
|
|
282
|
+
* retention policy. The one thing the object's NAME carried that the row
|
|
283
|
+
* did not — which request this run fulfilled — is now `after.requestedAt`.
|
|
284
|
+
* - **The DPA commits to "a limited period, after which deleted or
|
|
285
|
+
* de-identified"**, which indefinite retention of a full dump sits
|
|
286
|
+
* outside of.
|
|
287
|
+
*
|
|
288
|
+
* Two consequences are deliberate, not side effects. The export-write abort
|
|
289
|
+
* is gone with the write: there is nothing left to fail before the first
|
|
290
|
+
* delete, so an erasure can no longer be blocked by Storage. And the export
|
|
291
|
+
* was the only unbounded work in this function — it built the whole workspace
|
|
292
|
+
* in memory inside a 60-second cron, so the larger the workspace the likelier
|
|
293
|
+
* its erasure silently never happened (AGL-1455 half 1). That defect is
|
|
294
|
+
* removed by deletion rather than by a streaming exporter.
|
|
295
|
+
*/
|
|
296
|
+
export declare function eraseOrg(orgId: string, options?: EraseOrgOptions): Promise<EraseOrgResult>;
|
|
297
|
+
/** An org that stops a person's account from being erased. */
|
|
298
|
+
export interface UserErasureBlocker {
|
|
299
|
+
orgId: string;
|
|
300
|
+
orgName: string;
|
|
301
|
+
/** Whether the org still bills — the reason a human must intervene. */
|
|
302
|
+
hasLiveSubscription: boolean;
|
|
303
|
+
/** Other people who would be stranded if this org lost its owner. */
|
|
304
|
+
otherMembers: number;
|
|
305
|
+
}
|
|
306
|
+
export interface UserErasureCandidateOrg {
|
|
307
|
+
orgId: string;
|
|
308
|
+
orgName: string;
|
|
309
|
+
ownerUid: string | null;
|
|
310
|
+
hasLiveSubscription: boolean;
|
|
311
|
+
memberCount: number;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Which orgs block erasing `uid` (AGL-1140).
|
|
315
|
+
*
|
|
316
|
+
* Pure so the policy can be tested without Firestore, because the policy is
|
|
317
|
+
* the part worth arguing about — the deletion itself is mechanical.
|
|
318
|
+
*
|
|
319
|
+
* **Owning an org blocks erasure, always.** Not only when it bills, and not
|
|
320
|
+
* only when other members would be stranded. The alternative — cascading
|
|
321
|
+
* into `eraseOrg` — deletes a workspace, its sites and its data as a side
|
|
322
|
+
* effect of someone closing a personal account, and no consent given to the
|
|
323
|
+
* second act was given to the first. Blocking is recoverable; a cascade is
|
|
324
|
+
* not.
|
|
325
|
+
*
|
|
326
|
+
* A live subscription and stranded members are reported rather than gating,
|
|
327
|
+
* so the message can say WHY this org needs attention instead of a bare
|
|
328
|
+
* refusal — "transfer ownership" is useless advice if you do not know which
|
|
329
|
+
* of eleven workspaces is the problem.
|
|
330
|
+
*/
|
|
331
|
+
export declare function userErasureBlockers(uid: string, orgs: readonly UserErasureCandidateOrg[]): UserErasureBlocker[];
|
|
332
|
+
/**
|
|
333
|
+
* An address this account holds that a SECOND account also holds, which stops
|
|
334
|
+
* the erasure until a human decides what it is.
|
|
335
|
+
*
|
|
336
|
+
* ⛔ Carries no address and no other uid. The whole question is about a second
|
|
337
|
+
* customer, and a refusal that names them — or hands back an address in the
|
|
338
|
+
* clear, which `emailDeliveries` is hashed precisely to avoid keeping —
|
|
339
|
+
* discloses the person the refusal exists to protect. The staff account page
|
|
340
|
+
* already lists this account's own addresses and marks the shared ones, so
|
|
341
|
+
* the operator has the specifics without this record carrying them.
|
|
342
|
+
*/
|
|
343
|
+
export interface SharedAddressBlocker {
|
|
344
|
+
/** `sha256(address)` — matches the delivery log's own key. Not readable. */
|
|
345
|
+
key: string;
|
|
346
|
+
/** Where this account got it: `primary`, `provider`, `stored`. */
|
|
347
|
+
sources: AccountAddressSource[];
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Which of an account's addresses a second account is also known to hold.
|
|
351
|
+
*
|
|
352
|
+
* Pure, and separate from the sweep, for the same reason `userErasureBlockers`
|
|
353
|
+
* is: the policy is the arguable part. The mechanical part is deleting rows.
|
|
354
|
+
*
|
|
355
|
+
* ⚠️ `shared` is evidence in ONE direction. True proves a second holder;
|
|
356
|
+
* false only means none was found, because no lookup exists for an account
|
|
357
|
+
* holding an address through a federated provider. So this finds every case
|
|
358
|
+
* we can SEE and cannot promise there is no other — which is exactly why the
|
|
359
|
+
* sweep still tombstones every address it erases.
|
|
360
|
+
*/
|
|
361
|
+
export declare function sharedAddressBlockers(set: Pick<AccountAddressSet, 'addresses'>): SharedAddressBlocker[];
|
|
362
|
+
export interface EraseUserResult {
|
|
363
|
+
ok: boolean;
|
|
364
|
+
/** Set when the account was NOT erased. */
|
|
365
|
+
skippedReason?: 'not-found' | 'owns-orgs' | 'shared-address';
|
|
366
|
+
/** Orgs that must be handed over or deleted first. */
|
|
367
|
+
blockers?: UserErasureBlocker[];
|
|
368
|
+
/**
|
|
369
|
+
* Addresses a second account also holds. Set with
|
|
370
|
+
* `skippedReason: 'shared-address'`, and NOTHING was erased.
|
|
371
|
+
*/
|
|
372
|
+
sharedAddresses?: SharedAddressBlocker[];
|
|
373
|
+
/** What was actually removed, for the audit row and the caller's message. */
|
|
374
|
+
deleted?: {
|
|
375
|
+
subcollections: string[];
|
|
376
|
+
authRecord: boolean;
|
|
377
|
+
photo: boolean;
|
|
378
|
+
/** `profiles/{uid}` — the world-readable public identity (AGL-1970). */
|
|
379
|
+
profile: boolean;
|
|
380
|
+
/**
|
|
381
|
+
* Support messages stripped of `authorId`/`authorEmail` (AGL-1971). The
|
|
382
|
+
* threads themselves belong to the org and survive. **`null` means the
|
|
383
|
+
* redaction could not run** — not that there was nothing to redact.
|
|
384
|
+
*/
|
|
385
|
+
supportMessagesRedacted: number | null;
|
|
386
|
+
/**
|
|
387
|
+
* What each plugin's eraser removed (AGL-2939), keyed by plugin id — the
|
|
388
|
+
* data a plugin keeps about the person where neither the recursive
|
|
389
|
+
* delete of the user document nor an org's cascade reaches, such as
|
|
390
|
+
* documents under each org keyed by the uid. **`null` means that
|
|
391
|
+
* plugin's eraser failed** and its data may remain; it is not zero.
|
|
392
|
+
*/
|
|
393
|
+
plugins: Record<string, PluginUserErasureReport | null>;
|
|
394
|
+
/**
|
|
395
|
+
* Messages removed from `emailDeliveries/{sha256(address)}/messages` —
|
|
396
|
+
* the per-recipient delivery log. Zero for an account with no address on
|
|
397
|
+
* file, or one we never mailed.
|
|
398
|
+
*
|
|
399
|
+
* Across EVERY address the account held, not just the current primary.
|
|
400
|
+
*/
|
|
401
|
+
emailDeliveries: number;
|
|
402
|
+
/**
|
|
403
|
+
* `emailIdentityIndex/{address}` rows released — the address-keyed
|
|
404
|
+
* uniqueness claims, which no `recursiveDelete` of the user can reach.
|
|
405
|
+
*/
|
|
406
|
+
emailIdentityIndex: number;
|
|
407
|
+
/**
|
|
408
|
+
* How wide the address sweep actually was.
|
|
409
|
+
*
|
|
410
|
+
* ⚠️ `incomplete` is the field a compliance answer turns on: true means a
|
|
411
|
+
* source could not be read and an address the account held may have been
|
|
412
|
+
* missed, so this was not a complete erasure and must not be reported as
|
|
413
|
+
* one. Counts only — never the addresses, which is the data being erased.
|
|
414
|
+
*/
|
|
415
|
+
addressSweep: {
|
|
416
|
+
/** Addresses found across the Auth record, its providers and the store. */
|
|
417
|
+
resolved: number;
|
|
418
|
+
/** Addresses the delivery sweep actually visited. */
|
|
419
|
+
erased: number;
|
|
420
|
+
/**
|
|
421
|
+
* Addresses left INTACT because a second account also holds them.
|
|
422
|
+
*
|
|
423
|
+
* Always 0 on a successful erasure: a contested address refuses the
|
|
424
|
+
* whole run before anything is destroyed. It is reported so the audit
|
|
425
|
+
* row states that rather than leaving a reader to infer it.
|
|
426
|
+
*/
|
|
427
|
+
contested: number;
|
|
428
|
+
incomplete: boolean;
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Permanently erase a person's account (AGL-1140).
|
|
434
|
+
*
|
|
435
|
+
* Nothing did this before: `eraseHost`, `eraseSubtree` and `eraseOrg` existed
|
|
436
|
+
* and no path anywhere deleted a `users/{uid}`. That was survivable while the
|
|
437
|
+
* doc held a name and a phone; AGL-1133 added a postal address, and "we have
|
|
438
|
+
* no mechanism to delete it" is a bad answer to an erasure request.
|
|
439
|
+
*
|
|
440
|
+
* `eraseOrg` is deliberately NOT the model here. An org is a workspace with
|
|
441
|
+
* one owner; a person belongs to many orgs, so erasing them must not take
|
|
442
|
+
* anything with it that outlives them.
|
|
443
|
+
*
|
|
444
|
+
* Order matters:
|
|
445
|
+
* 1. Refuse if they own an org — see `userErasureBlockers`.
|
|
446
|
+
* 1b. Refuse if a second account holds one of their addresses — see
|
|
447
|
+
* `sharedAddressBlockers`. Both refusals come before any delete, so a
|
|
448
|
+
* blocked erasure leaves the account exactly as it was.
|
|
449
|
+
* 2. Remove their membership from every org they belong to, so no roster
|
|
450
|
+
* keeps their email and no host projection keeps granting them access.
|
|
451
|
+
* This runs BEFORE the profile delete: a half-erased account that still
|
|
452
|
+
* appears on a roster is worse than one not yet started.
|
|
453
|
+
* 3. Delete the `users/{uid}` subtree, the avatar, the world-readable
|
|
454
|
+
* `profiles/{uid}` public identity (AGL-1970), redact their name and
|
|
455
|
+
* email off every support message they wrote (AGL-1971), then the auth
|
|
456
|
+
* record last — once that is gone there is no uid to retry with.
|
|
457
|
+
*/
|
|
458
|
+
export declare function eraseUser(uid: string): Promise<EraseUserResult>;
|