@aglyn/plugins-outreach 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 +93 -0
- package/package.json +52 -0
- package/src/index.d.ts +22 -0
- package/src/index.js +29 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/compliance-section.d.ts +20 -0
- package/src/lib/components/compliance-section.js +291 -0
- package/src/lib/components/compliance-section.js.map +1 -0
- package/src/lib/components/enroll-dialog.d.ts +36 -0
- package/src/lib/components/enroll-dialog.js +656 -0
- package/src/lib/components/enroll-dialog.js.map +1 -0
- package/src/lib/components/enrollments-table.d.ts +28 -0
- package/src/lib/components/enrollments-table.js +375 -0
- package/src/lib/components/enrollments-table.js.map +1 -0
- package/src/lib/components/mailbox-card.d.ts +46 -0
- package/src/lib/components/mailbox-card.js +517 -0
- package/src/lib/components/mailbox-card.js.map +1 -0
- package/src/lib/components/mailboxes-section.d.ts +24 -0
- package/src/lib/components/mailboxes-section.js +258 -0
- package/src/lib/components/mailboxes-section.js.map +1 -0
- package/src/lib/components/outreach-console-page.d.ts +17 -0
- package/src/lib/components/outreach-console-page.js +81 -0
- package/src/lib/components/outreach-console-page.js.map +1 -0
- package/src/lib/components/outreach-console-sections.d.ts +43 -0
- package/src/lib/components/outreach-console-sections.js +55 -0
- package/src/lib/components/outreach-console-sections.js.map +1 -0
- package/src/lib/components/outreach-ui.d.ts +51 -0
- package/src/lib/components/outreach-ui.js +171 -0
- package/src/lib/components/outreach-ui.js.map +1 -0
- package/src/lib/components/send-window-fields.d.ts +25 -0
- package/src/lib/components/send-window-fields.js +178 -0
- package/src/lib/components/send-window-fields.js.map +1 -0
- package/src/lib/components/sequence-detail.d.ts +54 -0
- package/src/lib/components/sequence-detail.js +435 -0
- package/src/lib/components/sequence-detail.js.map +1 -0
- package/src/lib/components/sequence-editor.d.ts +37 -0
- package/src/lib/components/sequence-editor.js +485 -0
- package/src/lib/components/sequence-editor.js.map +1 -0
- package/src/lib/components/sequence-mailbox-picker.d.ts +44 -0
- package/src/lib/components/sequence-mailbox-picker.js +137 -0
- package/src/lib/components/sequence-mailbox-picker.js.map +1 -0
- package/src/lib/components/sequence-preview.d.ts +27 -0
- package/src/lib/components/sequence-preview.js +146 -0
- package/src/lib/components/sequence-preview.js.map +1 -0
- package/src/lib/components/sequence-step-card.d.ts +31 -0
- package/src/lib/components/sequence-step-card.js +326 -0
- package/src/lib/components/sequence-step-card.js.map +1 -0
- package/src/lib/components/sequences-section.d.ts +40 -0
- package/src/lib/components/sequences-section.js +310 -0
- package/src/lib/components/sequences-section.js.map +1 -0
- package/src/lib/components/use-outreach-api.d.ts +38 -0
- package/src/lib/components/use-outreach-api.js +139 -0
- package/src/lib/components/use-outreach-api.js.map +1 -0
- package/src/lib/components/use-outreach-crm.d.ts +50 -0
- package/src/lib/components/use-outreach-crm.js +200 -0
- package/src/lib/components/use-outreach-crm.js.map +1 -0
- package/src/lib/components/use-outreach-data.d.ts +55 -0
- package/src/lib/components/use-outreach-data.js +199 -0
- package/src/lib/components/use-outreach-data.js.map +1 -0
- package/src/lib/components/use-outreach-mailbox-api.d.ts +30 -0
- package/src/lib/components/use-outreach-mailbox-api.js +101 -0
- package/src/lib/components/use-outreach-mailbox-api.js.map +1 -0
- package/src/lib/components/use-outreach-mailboxes.d.ts +22 -0
- package/src/lib/components/use-outreach-mailboxes.js +68 -0
- package/src/lib/components/use-outreach-mailboxes.js.map +1 -0
- package/src/lib/components/use-outreach-settings.d.ts +17 -0
- package/src/lib/components/use-outreach-settings.js +64 -0
- package/src/lib/components/use-outreach-settings.js.map +1 -0
- package/src/lib/constants/api-routes.d.ts +68 -0
- package/src/lib/constants/api-routes.js +57 -0
- package/src/lib/constants/api-routes.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +46 -0
- package/src/lib/constants/bundle-common.js +55 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/constants/runtime-jobs.d.ts +24 -0
- package/src/lib/constants/runtime-jobs.js +24 -0
- package/src/lib/constants/runtime-jobs.js.map +1 -0
- package/src/lib/declarations.console-server.d.ts +38 -0
- package/src/lib/declarations.console-server.js +99 -0
- package/src/lib/declarations.console-server.js.map +1 -0
- package/src/lib/engine/compose.d.ts +86 -0
- package/src/lib/engine/compose.js +212 -0
- package/src/lib/engine/compose.js.map +1 -0
- package/src/lib/engine/delivery-status.d.ts +53 -0
- package/src/lib/engine/delivery-status.js +184 -0
- package/src/lib/engine/delivery-status.js.map +1 -0
- package/src/lib/engine/do-not-contact.d.ts +18 -0
- package/src/lib/engine/do-not-contact.js +34 -0
- package/src/lib/engine/do-not-contact.js.map +1 -0
- package/src/lib/engine/enrollment-state.d.ts +156 -0
- package/src/lib/engine/enrollment-state.js +303 -0
- package/src/lib/engine/enrollment-state.js.map +1 -0
- package/src/lib/engine/gates.d.ts +125 -0
- package/src/lib/engine/gates.js +232 -0
- package/src/lib/engine/gates.js.map +1 -0
- package/src/lib/engine/index.d.ts +28 -0
- package/src/lib/engine/index.js +33 -0
- package/src/lib/engine/index.js.map +1 -0
- package/src/lib/engine/mailbox-health.d.ts +49 -0
- package/src/lib/engine/mailbox-health.js +83 -0
- package/src/lib/engine/mailbox-health.js.map +1 -0
- package/src/lib/engine/opt-out-intent.d.ts +41 -0
- package/src/lib/engine/opt-out-intent.js +220 -0
- package/src/lib/engine/opt-out-intent.js.map +1 -0
- package/src/lib/engine/recipient-country.d.ts +41 -0
- package/src/lib/engine/recipient-country.js +171 -0
- package/src/lib/engine/recipient-country.js.map +1 -0
- package/src/lib/engine/schedule.d.ts +70 -0
- package/src/lib/engine/schedule.js +115 -0
- package/src/lib/engine/schedule.js.map +1 -0
- package/src/lib/engine/sending-capacity.d.ts +96 -0
- package/src/lib/engine/sending-capacity.js +172 -0
- package/src/lib/engine/sending-capacity.js.map +1 -0
- package/src/lib/engine/sequence-validation.d.ts +90 -0
- package/src/lib/engine/sequence-validation.js +291 -0
- package/src/lib/engine/sequence-validation.js.map +1 -0
- package/src/lib/engine/thread-classification.d.ts +78 -0
- package/src/lib/engine/thread-classification.js +224 -0
- package/src/lib/engine/thread-classification.js.map +1 -0
- package/src/lib/engine/thread-message.d.ts +80 -0
- package/src/lib/engine/thread-message.js +143 -0
- package/src/lib/engine/thread-message.js.map +1 -0
- package/src/lib/enrollment/enroll-people.d.ts +81 -0
- package/src/lib/enrollment/enroll-people.js +250 -0
- package/src/lib/enrollment/enroll-people.js.map +1 -0
- package/src/lib/enrollment/gate-lookups.d.ts +32 -0
- package/src/lib/enrollment/gate-lookups.js +154 -0
- package/src/lib/enrollment/gate-lookups.js.map +1 -0
- package/src/lib/mailboxes/mailbox-api.d.ts +126 -0
- package/src/lib/mailboxes/mailbox-api.js +66 -0
- package/src/lib/mailboxes/mailbox-api.js.map +1 -0
- package/src/lib/mailboxes/mailbox-credentials.d.ts +95 -0
- package/src/lib/mailboxes/mailbox-credentials.js +102 -0
- package/src/lib/mailboxes/mailbox-credentials.js.map +1 -0
- package/src/lib/mailboxes/mailbox-erasure.d.ts +69 -0
- package/src/lib/mailboxes/mailbox-erasure.js +148 -0
- package/src/lib/mailboxes/mailbox-erasure.js.map +1 -0
- package/src/lib/mailboxes/mailbox-gate.d.ts +75 -0
- package/src/lib/mailboxes/mailbox-gate.js +98 -0
- package/src/lib/mailboxes/mailbox-gate.js.map +1 -0
- package/src/lib/mailboxes/mailbox-revoke.d.ts +59 -0
- package/src/lib/mailboxes/mailbox-revoke.js +41 -0
- package/src/lib/mailboxes/mailbox-revoke.js.map +1 -0
- package/src/lib/mailboxes/mailbox-routes.d.ts +119 -0
- package/src/lib/mailboxes/mailbox-routes.js +605 -0
- package/src/lib/mailboxes/mailbox-routes.js.map +1 -0
- package/src/lib/mailboxes/mailbox-settings.d.ts +110 -0
- package/src/lib/mailboxes/mailbox-settings.js +212 -0
- package/src/lib/mailboxes/mailbox-settings.js.map +1 -0
- package/src/lib/mailboxes/mailbox-transport.d.ts +64 -0
- package/src/lib/mailboxes/mailbox-transport.js +94 -0
- package/src/lib/mailboxes/mailbox-transport.js.map +1 -0
- package/src/lib/mailboxes/oauth-redirect.d.ts +41 -0
- package/src/lib/mailboxes/oauth-redirect.js +63 -0
- package/src/lib/mailboxes/oauth-redirect.js.map +1 -0
- package/src/lib/mailboxes/oauth-state.d.ts +152 -0
- package/src/lib/mailboxes/oauth-state.js +212 -0
- package/src/lib/mailboxes/oauth-state.js.map +1 -0
- package/src/lib/mailboxes/outreach-config.d.ts +64 -0
- package/src/lib/mailboxes/outreach-config.js +77 -0
- package/src/lib/mailboxes/outreach-config.js.map +1 -0
- package/src/lib/mailboxes/register-mailbox-routes.d.ts +47 -0
- package/src/lib/mailboxes/register-mailbox-routes.js +135 -0
- package/src/lib/mailboxes/register-mailbox-routes.js.map +1 -0
- package/src/lib/model/compliance-settings.d.ts +78 -0
- package/src/lib/model/compliance-settings.js +155 -0
- package/src/lib/model/compliance-settings.js.map +1 -0
- package/src/lib/model/outreach-api.d.ts +210 -0
- package/src/lib/model/outreach-api.js +28 -0
- package/src/lib/model/outreach-api.js.map +1 -0
- package/src/lib/model/outreach.types.d.ts +563 -0
- package/src/lib/model/outreach.types.js +225 -0
- package/src/lib/model/outreach.types.js.map +1 -0
- package/src/lib/model/sequence-draft.d.ts +84 -0
- package/src/lib/model/sequence-draft.js +239 -0
- package/src/lib/model/sequence-draft.js.map +1 -0
- package/src/lib/model/step-preview.d.ts +45 -0
- package/src/lib/model/step-preview.js +98 -0
- package/src/lib/model/step-preview.js.map +1 -0
- package/src/lib/model/stored-records.d.ts +23 -0
- package/src/lib/model/stored-records.js +84 -0
- package/src/lib/model/stored-records.js.map +1 -0
- package/src/lib/plugin.d.ts +46 -0
- package/src/lib/plugin.js +86 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/routes/enroll-routes.d.ts +64 -0
- package/src/lib/routes/enroll-routes.js +350 -0
- package/src/lib/routes/enroll-routes.js.map +1 -0
- package/src/lib/routes/enrollment-routes.d.ts +19 -0
- package/src/lib/routes/enrollment-routes.js +171 -0
- package/src/lib/routes/enrollment-routes.js.map +1 -0
- package/src/lib/routes/platform-deps.d.ts +51 -0
- package/src/lib/routes/platform-deps.js +66 -0
- package/src/lib/routes/platform-deps.js.map +1 -0
- package/src/lib/routes/preview-routes.d.ts +33 -0
- package/src/lib/routes/preview-routes.js +117 -0
- package/src/lib/routes/preview-routes.js.map +1 -0
- package/src/lib/routes/register-routes.d.ts +22 -0
- package/src/lib/routes/register-routes.js +92 -0
- package/src/lib/routes/register-routes.js.map +1 -0
- package/src/lib/routes/route-deps.d.ts +49 -0
- package/src/lib/routes/route-deps.js +27 -0
- package/src/lib/routes/route-deps.js.map +1 -0
- package/src/lib/routes/route-gate.d.ts +94 -0
- package/src/lib/routes/route-gate.js +87 -0
- package/src/lib/routes/route-gate.js.map +1 -0
- package/src/lib/routes/route-http.d.ts +32 -0
- package/src/lib/routes/route-http.js +62 -0
- package/src/lib/routes/route-http.js.map +1 -0
- package/src/lib/routes/sequence-routes.d.ts +32 -0
- package/src/lib/routes/sequence-routes.js +359 -0
- package/src/lib/routes/sequence-routes.js.map +1 -0
- package/src/lib/routes/settings-routes.d.ts +30 -0
- package/src/lib/routes/settings-routes.js +73 -0
- package/src/lib/routes/settings-routes.js.map +1 -0
- package/src/lib/runtime/enrollment-events.d.ts +86 -0
- package/src/lib/runtime/enrollment-events.js +141 -0
- package/src/lib/runtime/enrollment-events.js.map +1 -0
- package/src/lib/runtime/fixtures/fake-gmail.d.ts +121 -0
- package/src/lib/runtime/fixtures/fake-gmail.js +312 -0
- package/src/lib/runtime/fixtures/fake-gmail.js.map +1 -0
- package/src/lib/runtime/mailbox-health-store.d.ts +47 -0
- package/src/lib/runtime/mailbox-health-store.js +168 -0
- package/src/lib/runtime/mailbox-health-store.js.map +1 -0
- package/src/lib/runtime/person-erasure.d.ts +39 -0
- package/src/lib/runtime/person-erasure.js +57 -0
- package/src/lib/runtime/person-erasure.js.map +1 -0
- package/src/lib/runtime/platform-runtime-deps.d.ts +29 -0
- package/src/lib/runtime/platform-runtime-deps.js +98 -0
- package/src/lib/runtime/platform-runtime-deps.js.map +1 -0
- package/src/lib/runtime/runtime-deps.d.ts +77 -0
- package/src/lib/runtime/runtime-deps.js +18 -0
- package/src/lib/runtime/runtime-deps.js.map +1 -0
- package/src/lib/runtime/send-job.d.ts +42 -0
- package/src/lib/runtime/send-job.js +780 -0
- package/src/lib/runtime/send-job.js.map +1 -0
- package/src/lib/runtime/sync-job.d.ts +41 -0
- package/src/lib/runtime/sync-job.js +480 -0
- package/src/lib/runtime/sync-job.js.map +1 -0
- package/src/lib/runtime/timeline.d.ts +67 -0
- package/src/lib/runtime/timeline.js +93 -0
- package/src/lib/runtime/timeline.js.map +1 -0
- package/src/lib/runtime/unsubscribe-link.d.ts +75 -0
- package/src/lib/runtime/unsubscribe-link.js +121 -0
- package/src/lib/runtime/unsubscribe-link.js.map +1 -0
- package/src/lib/runtime/unsubscribe-route.d.ts +24 -0
- package/src/lib/runtime/unsubscribe-route.js +103 -0
- package/src/lib/runtime/unsubscribe-route.js.map +1 -0
- package/src/lib/server.d.ts +53 -0
- package/src/lib/server.js +94 -0
- package/src/lib/server.js.map +1 -0
- package/src/lib/storage/compliance-settings-store.d.ts +44 -0
- package/src/lib/storage/compliance-settings-store.js +78 -0
- package/src/lib/storage/compliance-settings-store.js.map +1 -0
- package/src/lib/storage/do-not-contact-store.d.ts +60 -0
- package/src/lib/storage/do-not-contact-store.js +168 -0
- package/src/lib/storage/do-not-contact-store.js.map +1 -0
- package/src/lib/storage/outreach-records.d.ts +33 -0
- package/src/lib/storage/outreach-records.js +35 -0
- package/src/lib/storage/outreach-records.js.map +1 -0
- package/src/lib/subprocessors.d.ts +48 -0
- package/src/lib/subprocessors.js +70 -0
- package/src/lib/subprocessors.js.map +1 -0
- package/src/lib/transport/gmail-client.d.ts +145 -0
- package/src/lib/transport/gmail-client.js +229 -0
- package/src/lib/transport/gmail-client.js.map +1 -0
- package/src/lib/transport/gmail-errors.d.ts +84 -0
- package/src/lib/transport/gmail-errors.js +138 -0
- package/src/lib/transport/gmail-errors.js.map +1 -0
- package/src/lib/transport/google-oauth.d.ts +138 -0
- package/src/lib/transport/google-oauth.js +247 -0
- package/src/lib/transport/google-oauth.js.map +1 -0
- package/src/lib/transport/http.d.ts +53 -0
- package/src/lib/transport/http.js +79 -0
- package/src/lib/transport/http.js.map +1 -0
- package/src/lib/transport/rfc5322.d.ts +116 -0
- package/src/lib/transport/rfc5322.js +330 -0
- package/src/lib/transport/rfc5322.js.map +1 -0
- package/src/lib/transport/send-message.d.ts +69 -0
- package/src/lib/transport/send-message.js +77 -0
- package/src/lib/transport/send-message.js.map +1 -0
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
*/ import { SecretBoxError } from "@aglyn/shared-util-tools/secret-box";
|
|
17
|
+
import { GmailTransportError } from "../transport/gmail-errors.js";
|
|
18
|
+
import { revokeGoogleToken } from "../transport/google-oauth.js";
|
|
19
|
+
import { countOtherCredentialsForAccount, openMailboxRefreshToken } from "./mailbox-credentials.js";
|
|
20
|
+
/** Revokes one stored grant at Google, unless it is still shared. Never throws. */ export async function revokeMailboxGrant(firestore, credential, deps, options = {}) {
|
|
21
|
+
try {
|
|
22
|
+
const others = await countOtherCredentialsForAccount(firestore, {
|
|
23
|
+
providerAccountId: credential.providerAccountId,
|
|
24
|
+
mailboxId: credential.mailboxId,
|
|
25
|
+
excludeOrgId: options.excludeOrgId,
|
|
26
|
+
excludeMailboxIds: options.excludeMailboxIds
|
|
27
|
+
});
|
|
28
|
+
if (others > 0) return 'kept-for-other-mailbox';
|
|
29
|
+
const config = deps.readConfig();
|
|
30
|
+
if (!config.configured) return 'failed';
|
|
31
|
+
const { refreshToken } = openMailboxRefreshToken(credential, config.config.keyring);
|
|
32
|
+
return await revokeGoogleToken(refreshToken, deps.transport);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (!(error instanceof GmailTransportError) && !(error instanceof SecretBoxError)) {
|
|
35
|
+
console.error('[outreach] revoking a mailbox grant failed', error);
|
|
36
|
+
}
|
|
37
|
+
return 'failed';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=mailbox-revoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/outreach/src/lib/mailboxes/mailbox-revoke.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SecretBoxError } from '@aglyn/shared-util-tools/secret-box'\nimport { GmailTransportError } from '../transport/gmail-errors'\nimport { revokeGoogleToken } from '../transport/google-oauth'\nimport type { TransportDeps } from '../transport/http'\nimport type { OutreachMailboxDisconnectResponse } from './mailbox-api'\nimport {\n countOtherCredentialsForAccount,\n openMailboxRefreshToken,\n type OutreachGoogleMailboxCredentials,\n} from './mailbox-credentials'\nimport type { OutreachGoogleConfigResult } from './outreach-config'\n\n/**\n * TELLING GOOGLE A STORED GRANT IS OVER (AGL-2978).\n *\n * A disconnect, a workspace erasure and an account erasure all end a\n * mailbox's grant the same way: open its sealed refresh token with this\n * deployment's key and revoke it at Google — unless another stored\n * credential still uses the same Google account, because Google's\n * revocation ends the whole grant this client holds for the account, and\n * revoking it would silently break that other mailbox.\n *\n * Never throws. A grant that cannot be revoked is still deleted by whoever\n * called this; the outcome says which happened.\n */\n\n/**\n * What became of a grant at Google: `revoked`, `already-invalid`,\n * `kept-for-other-mailbox` while another credential still uses the account,\n * or `failed` when Google could not be told — the token would not open, the\n * deployment is not configured, or Google did not answer.\n */\nexport type OutreachGrantRevocation = OutreachMailboxDisconnectResponse['revocation']\n\nexport interface OutreachRevokeDeps {\n readConfig(): OutreachGoogleConfigResult\n /** The network and retry policy the revocation call uses. */\n transport: TransportDeps\n}\n\nexport interface RevokeMailboxGrantOptions {\n /**\n * Credentials of this organization do not count as another use of the\n * account: the workspace erasure is ending all of them.\n */\n excludeOrgId?: string\n /**\n * These credentials do not count as another use of the account either:\n * the account erasure is ending every one of the person's grants.\n */\n excludeMailboxIds?: ReadonlySet<string>\n}\n\n/** Revokes one stored grant at Google, unless it is still shared. Never throws. */\nexport async function revokeMailboxGrant(\n firestore: FirebaseFirestore.Firestore,\n credential: OutreachGoogleMailboxCredentials,\n deps: OutreachRevokeDeps,\n options: RevokeMailboxGrantOptions = {},\n): Promise<OutreachGrantRevocation> {\n try {\n const others = await countOtherCredentialsForAccount(firestore, {\n providerAccountId: credential.providerAccountId,\n mailboxId: credential.mailboxId,\n excludeOrgId: options.excludeOrgId,\n excludeMailboxIds: options.excludeMailboxIds,\n })\n if (others > 0) return 'kept-for-other-mailbox'\n const config = deps.readConfig()\n if (!config.configured) return 'failed'\n const { refreshToken } = openMailboxRefreshToken(credential, config.config.keyring)\n return await revokeGoogleToken(refreshToken, deps.transport)\n } catch (error) {\n if (!(error instanceof GmailTransportError) && !(error instanceof SecretBoxError)) {\n console.error('[outreach] revoking a mailbox grant failed', error)\n }\n return 'failed'\n }\n}\n"],"names":["SecretBoxError","GmailTransportError","revokeGoogleToken","countOtherCredentialsForAccount","openMailboxRefreshToken","revokeMailboxGrant","firestore","credential","deps","options","others","providerAccountId","mailboxId","excludeOrgId","excludeMailboxIds","config","readConfig","configured","refreshToken","keyring","transport","error","console"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,cAAc,QAAQ,sCAAqC;AACpE,SAASC,mBAAmB,QAAQ,+BAA2B;AAC/D,SAASC,iBAAiB,QAAQ,+BAA2B;AAG7D,SACEC,+BAA+B,EAC/BC,uBAAuB,QAElB,2BAAuB;AA4C9B,iFAAiF,GACjF,OAAO,eAAeC,mBACpBC,SAAsC,EACtCC,UAA4C,EAC5CC,IAAwB,EACxBC,UAAqC,CAAC,CAAC;IAEvC,IAAI;QACF,MAAMC,SAAS,MAAMP,gCAAgCG,WAAW;YAC9DK,mBAAmBJ,WAAWI,iBAAiB;YAC/CC,WAAWL,WAAWK,SAAS;YAC/BC,cAAcJ,QAAQI,YAAY;YAClCC,mBAAmBL,QAAQK,iBAAiB;QAC9C;QACA,IAAIJ,SAAS,GAAG,OAAO;QACvB,MAAMK,SAASP,KAAKQ,UAAU;QAC9B,IAAI,CAACD,OAAOE,UAAU,EAAE,OAAO;QAC/B,MAAM,EAAEC,YAAY,EAAE,GAAGd,wBAAwBG,YAAYQ,OAAOA,MAAM,CAACI,OAAO;QAClF,OAAO,MAAMjB,kBAAkBgB,cAAcV,KAAKY,SAAS;IAC7D,EAAE,OAAOC,OAAO;QACd,IAAI,CAAEA,CAAAA,iBAAiBpB,mBAAkB,KAAM,CAAEoB,CAAAA,iBAAiBrB,cAAa,GAAI;YACjFsB,QAAQD,KAAK,CAAC,8CAA8CA;QAC9D;QACA,OAAO;IACT;AACF"}
|
|
@@ -0,0 +1,119 @@
|
|
|
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 { PluginWebApiHandler } from '@aglyn/aglyn/server';
|
|
18
|
+
import type { TransportDeps } from '../transport/http';
|
|
19
|
+
import { type OutreachGateDeps } from './mailbox-gate';
|
|
20
|
+
import { type OutreachGoogleConfigResult } from './outreach-config';
|
|
21
|
+
/**
|
|
22
|
+
* THE MAILBOX ROUTES (AGL-2978): connect a rep's Google mailbox, keep its
|
|
23
|
+
* settings, pause it, test it, and disconnect it.
|
|
24
|
+
*
|
|
25
|
+
* ## The connect, end to end
|
|
26
|
+
*
|
|
27
|
+
* 1. `connect` (the member's session) mints a signed, single-use state bound
|
|
28
|
+
* to the member and the organization, records its pending entry, and
|
|
29
|
+
* answers Google's consent address — offline access, the consent prompt,
|
|
30
|
+
* a PKCE challenge and an OpenID nonce, both derived from the state.
|
|
31
|
+
* 2. Google redirects the browser to `oauth/callback`. That request carries
|
|
32
|
+
* no bearer token, so it DOES nothing: it verifies the state's signature,
|
|
33
|
+
* finds the organization's console path, and redirects to the Mailboxes
|
|
34
|
+
* page with the code in the URL FRAGMENT, where no server and no `Referer`
|
|
35
|
+
* sees it. Its release gate was asked about the organization and the
|
|
36
|
+
* member the state names (the route's declared subject).
|
|
37
|
+
* 3. The page takes the code out of the address bar and posts it to
|
|
38
|
+
* `connect/complete` with the member's own session. That is where the
|
|
39
|
+
* state is consumed, where it is refused if it was minted for anyone else,
|
|
40
|
+
* and where the code is exchanged. So a consent screen someone else was
|
|
41
|
+
* tricked into completing cannot connect THEIR mailbox to the member who
|
|
42
|
+
* started it: the code arrives in the wrong browser, whose session is not
|
|
43
|
+
* the state's member.
|
|
44
|
+
*
|
|
45
|
+
* ## Refusals, in order, on `connect/complete`
|
|
46
|
+
*
|
|
47
|
+
* A state that is invalid, minted for another member or organization,
|
|
48
|
+
* expired, already used or superseded; a code Google refuses; a grant with no
|
|
49
|
+
* refresh token; a grant missing `gmail.send` or `gmail.readonly` (the consent
|
|
50
|
+
* screen lets a person untick them); an ID token that is not about this
|
|
51
|
+
* exchange or whose address Google has not verified; a Gmail profile whose
|
|
52
|
+
* address is not the ID token's; and a member at their mailbox limit.
|
|
53
|
+
*
|
|
54
|
+
* A grant refused after the code exchange is dropped, not revoked. Google's
|
|
55
|
+
* revocation ends the whole grant this client holds for the account, and the
|
|
56
|
+
* same account may already be connected — by this member in another
|
|
57
|
+
* organization, or by a teammate — so revoking a token this route merely
|
|
58
|
+
* declines to keep could disconnect a mailbox that is working.
|
|
59
|
+
*
|
|
60
|
+
* ## Who may do what
|
|
61
|
+
*
|
|
62
|
+
* Every route but the callback climbs `outreachMemberGate`. The member who
|
|
63
|
+
* connected a mailbox manages it; an organization owner or admin may also
|
|
64
|
+
* change its settings, pause it and disconnect it — a departing rep's mailbox
|
|
65
|
+
* has to be stoppable by somebody. Only its own member can send a test from
|
|
66
|
+
* it, since the test lands in their inbox.
|
|
67
|
+
*/
|
|
68
|
+
export interface OutreachMailboxRouteDeps {
|
|
69
|
+
firestore(): FirebaseFirestore.Firestore;
|
|
70
|
+
gate: OutreachGateDeps;
|
|
71
|
+
readConfig(): OutreachGoogleConfigResult;
|
|
72
|
+
/** Whether the signing secret the OAuth state needs is configured. */
|
|
73
|
+
stateSigningConfigured(): boolean;
|
|
74
|
+
redirectUri(requestUrl: string): string | null;
|
|
75
|
+
now(): number;
|
|
76
|
+
/** The network and retry policy every Google call uses. */
|
|
77
|
+
transport: TransportDeps;
|
|
78
|
+
consumeRateLimit(key: string, options: {
|
|
79
|
+
limit: number;
|
|
80
|
+
windowMs: number;
|
|
81
|
+
}): Promise<{
|
|
82
|
+
allowed: boolean;
|
|
83
|
+
}>;
|
|
84
|
+
logOrgActivity(orgId: string, actor: {
|
|
85
|
+
uid: string;
|
|
86
|
+
email?: string | null;
|
|
87
|
+
}, action: string, target: {
|
|
88
|
+
type: typeof OUTREACH_MAILBOX_ACTIVITY_TARGET;
|
|
89
|
+
id: string;
|
|
90
|
+
name: string;
|
|
91
|
+
}): Promise<void>;
|
|
92
|
+
confirmAliasesByProvider(firestore: FirebaseFirestore.Firestore, input: {
|
|
93
|
+
orgId: string;
|
|
94
|
+
uid: string;
|
|
95
|
+
addresses: readonly string[];
|
|
96
|
+
nowMs: number;
|
|
97
|
+
}): Promise<{
|
|
98
|
+
ok: boolean;
|
|
99
|
+
confirmed?: string[];
|
|
100
|
+
}>;
|
|
101
|
+
}
|
|
102
|
+
export interface OutreachMailboxRoutes {
|
|
103
|
+
availability: PluginWebApiHandler;
|
|
104
|
+
connect: PluginWebApiHandler;
|
|
105
|
+
oauthCallback: PluginWebApiHandler;
|
|
106
|
+
connectComplete: PluginWebApiHandler;
|
|
107
|
+
settings: PluginWebApiHandler;
|
|
108
|
+
status: PluginWebApiHandler;
|
|
109
|
+
test: PluginWebApiHandler;
|
|
110
|
+
disconnect: PluginWebApiHandler;
|
|
111
|
+
}
|
|
112
|
+
/** Test sends one mailbox may make in an hour. */
|
|
113
|
+
export declare const OUTREACH_TEST_SENDS_PER_HOUR = 5;
|
|
114
|
+
/**
|
|
115
|
+
* The org activity target a mailbox's rows are filed under: Outreach's own
|
|
116
|
+
* namespaced resource, which the feed reads as "Mailbox".
|
|
117
|
+
*/
|
|
118
|
+
export declare const OUTREACH_MAILBOX_ACTIVITY_TARGET = "outreach:mailbox";
|
|
119
|
+
export declare function createOutreachMailboxRoutes(deps: OutreachMailboxRouteDeps): OutreachMailboxRoutes;
|