refactor: isolate Slack registration credential cleanup

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-06 21:59:23 -05:00
1 parent 95e3f17f01
commit 47e3ea3066
3 files changed
+21 -14

No files matched your search

@@ -0,0 +1,19 @@
import { and, eq, like } from "drizzle-orm";
import { chatEndpoints, chatSlackRegistrations, toolOauthStates, type Db } from "@paperclipai/db";
import { secretService } from "./secrets.js";
import type { CredentialMutationLeaseGuard } from "./chat-credential-mutation-lease.js";
// Keep generic connection removal independent of the registration service's
// authorization graph; access routes already load tool-access through the barrel.
export async function removeSlackRegistration(db: Db, endpointId: string, lease: CredentialMutationLeaseGuard) {
const vault = secretService(db);
const [row] = await db.select().from(chatSlackRegistrations).where(eq(chatSlackRegistrations.endpointId, endpointId));
if (!row) return;
await lease.assertOwned();
await db.update(chatSlackRegistrations).set({ status: "removed", updatedAt: new Date() }).where(eq(chatSlackRegistrations.endpointId, endpointId));
const [current] = await db.select().from(chatEndpoints).where(eq(chatEndpoints.id, endpointId));
if (current) await db.delete(toolOauthStates).where(and(eq(toolOauthStates.connectionId, current.connectionId), like(toolOauthStates.state, "slack-install.%")));
for (const id of Object.values(row.secretIds)) { await lease.assertOwned(); await vault.remove(id); }
await lease.assertOwned();
await db.update(chatSlackRegistrations).set({ secretIds: {} }).where(eq(chatSlackRegistrations.endpointId, endpointId));
}
+1 -13
View File
@@ -1,3 +1,4 @@
import { removeSlackRegistration } from "./chat-slack-registration-cleanup.js";
import { createHash, randomBytes } from "node:crypto";
import { and, eq, gt, like } from "drizzle-orm";
import { agents, chatEndpoints, chatSlackRegistrations, companies, toolConnections, toolOauthStates, type Db } from "@paperclipai/db";
@@ -324,16 +325,3 @@ export function slackChatRegistrationService(db: Db, options: {
return { create, install, pending, expiredReturn, complete, cleanup, returnPath, registration,
resume: (endpointId: string, actor: SlackSetupActor) => options.withLock(endpointId, lease => resumeLocked(endpointId, actor, lease)) };
}
export async function removeSlackRegistration(db: Db, endpointId: string, lease: CredentialMutationLeaseGuard) {
const vault = secretService(db);
const [row] = await db.select().from(chatSlackRegistrations).where(eq(chatSlackRegistrations.endpointId, endpointId));
if (!row) return;
await lease.assertOwned();
await db.update(chatSlackRegistrations).set({ status: "removed", updatedAt: new Date() }).where(eq(chatSlackRegistrations.endpointId, endpointId));
const [current] = await db.select().from(chatEndpoints).where(eq(chatEndpoints.id, endpointId));
if (current) await db.delete(toolOauthStates).where(and(eq(toolOauthStates.connectionId, current.connectionId), like(toolOauthStates.state, `${prefix}%`)));
for (const id of Object.values(row.secretIds)) { await lease.assertOwned(); await vault.remove(id); }
await lease.assertOwned();
await db.update(chatSlackRegistrations).set({ secretIds: {} }).where(eq(chatSlackRegistrations.endpointId, endpointId));
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { chatCredentialMutationLease } from "./chat-credential-mutation-lease.js";
import { removeSlackRegistration } from "./chat-slack-registration.js";
import { removeSlackRegistration } from "./chat-slack-registration-cleanup.js";
import { chatEndpoints } from "@paperclipai/db";
import { AGGREGATOR_NAMES, isAppAggregator, type AggregatorAppsResponse, type ArcadeDiscoverySetupInput } from "@paperclipai/shared/aggregator-apps";
import { resolveAggregatorApp, type AppCatalogAggregator } from "@paperclipai/shared/aggregator-app-catalog";