@@ -5,6 +5,7 @@ import { and, eq, inArray, isNull, lte, or, sql } from 'drizzle-orm'
55import { z } from 'zod'
66import type { OperationUseCase } from '@/lib/core/application/operation'
77import { OrchestrationError } from '@/lib/core/orchestration/types'
8+ import type { DbTransaction } from '@/lib/db/types'
89import { loadSlackAppConfiguration } from '@/lib/slack-search/app-configuration'
910
1011const id = z . string ( ) . min ( 1 ) . max ( 200 )
@@ -65,6 +66,11 @@ export const revokeSlackSearchAccess: OperationUseCase<
6566 or ( isNull ( credential . grantedAt ) , lte ( credential . grantedAt , occurredAt ) ) ,
6667 ...( uninstall ? [ ] : [ inArray ( credential . providerSubjectId , revokedUsers ) ] )
6768 )
69+ const revokeMemberGrants = ( tx : DbTransaction , organizationId ?: string ) =>
70+ tx
71+ . update ( credential )
72+ . set ( { managedOauthStatus : 'needs_reauth' , updatedAt : new Date ( ) } )
73+ . where ( memberGrants ( organizationId ) )
6874 await db . transaction ( async ( tx ) => {
6975 const [ installation ] = await tx
7076 . select ( )
@@ -79,28 +85,28 @@ export const revokeSlackSearchAccess: OperationUseCase<
7985 . limit ( 1 )
8086 /** Member sign-in through the shared app needs no Search bot, so it has no installation. */
8187 if ( ! installation ) {
82- if ( sharedApp && ( uninstall || revokedUsers . length ) )
83- await tx
84- . update ( credential )
85- . set ( { managedOauthStatus : 'needs_reauth' , updatedAt : new Date ( ) } )
86- . where ( memberGrants ( ) )
88+ if ( sharedApp && ( uninstall || revokedUsers . length ) ) await revokeMemberGrants ( tx )
8789 return
8890 }
8991 if ( app . app . kind === 'custom' && app . app . organizationId !== installation . organizationId )
9092 throw new Error ( 'Slack installation ownership is inconsistent' )
9193 const staleInstallation = installation . updatedAt > occurredAt
92- if ( uninstall && staleInstallation ) return
94+ if ( uninstall && staleInstallation ) {
95+ /** A reinstall keeps its bot, but shared-app grants issued before the uninstall are gone. */
96+ if ( sharedApp ) await revokeMemberGrants ( tx )
97+ return
98+ }
9399 const revokeBot =
94100 ! staleInstallation &&
95101 ( uninstall ||
96102 ( input . event . type === 'tokens_revoked' &&
97103 ( input . event . tokens . bot ?? [ ] ) . includes ( installation . botUserId ) ) )
98104 let revokedMemberIds : string [ ] = [ ]
99105 if ( uninstall || revokedUsers . length ) {
100- const revokeCredentials = tx
101- . update ( credential )
102- . set ( { managedOauthStatus : 'needs_reauth' , updatedAt : new Date ( ) } )
103- . where ( memberGrants ( sharedApp ? undefined : installation . organizationId ) )
106+ const revokeCredentials = revokeMemberGrants (
107+ tx ,
108+ sharedApp ? undefined : installation . organizationId
109+ )
104110 if ( revokeBot ) await revokeCredentials
105111 else {
106112 const revokedCredentials = await revokeCredentials . returning ( {
0 commit comments