@@ -15,6 +15,7 @@ import {
1515 handleReconnectCredential ,
1616} from '@/lib/credentials/draft-hooks'
1717import { completeOrganizationCredentialDraft } from '@/lib/credentials/organization-draft'
18+ import { resumeConnectorsAfterCredentialReconnect } from '@/lib/knowledge/connectors/credential-recovery'
1819import { APP_ENTRY_PATH } from '@/lib/navigation/paths'
1920import { clearOAuthRefreshFailure } from '@/lib/oauth/credential-service'
2021import { OAUTH_PROVIDERS } from '@/lib/oauth/oauth'
@@ -125,7 +126,6 @@ interface CredentialReconnectConflictParams {
125126 idToken ?: string | null
126127 accessTokenExpiresAt ?: Date | null
127128 refreshTokenExpiresAt ?: Date | null
128- scope ?: string | null
129129 }
130130 oauthState : OAuthStateWithCallbackUrl | null | undefined
131131}
@@ -144,9 +144,10 @@ interface CredentialReconnectConflictParams {
144144 *
145145 * Returning before the insert leaves every credential bound to the account it
146146 * had. The grant itself is still real, so its tokens replace the ones on the
147- * identity's existing rows, the same tokens those credentials would have
148- * inherited from the new row, and a provider that rotates on reauthorization
149- * cannot strand them on a dead chain.
147+ * identity's existing rows and their connectors resume, as they would have on
148+ * the new row, and a provider that rotates on reauthorization cannot strand
149+ * them on a dead chain. Each row keeps its stored scope, which can carry state
150+ * a fresh grant does not repeat (a Salesforce instance host).
150151 */
151152export async function refuseConflictingCredentialReconnect (
152153 params : CredentialReconnectConflictParams
@@ -197,6 +198,7 @@ export async function refuseConflictingCredentialReconnect(
197198 } )
198199 if ( ! conflicting ) return null
199200
201+ const now = new Date ( )
200202 await db
201203 . update ( schema . account )
202204 . set ( {
@@ -206,12 +208,14 @@ export async function refuseConflictingCredentialReconnect(
206208 idToken : account . idToken ?? undefined ,
207209 accessTokenExpiresAt : account . accessTokenExpiresAt ?? undefined ,
208210 refreshTokenExpiresAt : account . refreshTokenExpiresAt ?? undefined ,
209- scope : account . scope ?? undefined ,
210211 } ) ,
211- updatedAt : new Date ( ) ,
212+ updatedAt : now ,
212213 } )
213214 . where ( inArray ( schema . account . id , identityAccountIds ) )
214- await Promise . all ( identityAccountIds . map ( ( id ) => clearOAuthRefreshFailure ( id ) ) )
215+ for ( const id of identityAccountIds ) {
216+ await clearOAuthRefreshFailure ( id )
217+ await resumeConnectorsAfterCredentialReconnect ( id , now )
218+ }
215219
216220 await db
217221 . delete ( schema . pendingCredentialDraft )
0 commit comments