fix(settings): revalidate queued credentials and handle status failures
This commit is contained in:
parent
2b4e5240e7
commit
cc4dc933e8
|
|
@ -101,6 +101,10 @@ export function useMCPConnectionSettings(
|
|||
const connection = services.save({ ...target, enabled: false })
|
||||
if (target.authenticationType === 'none') await services.setCredential(connection.id, '')
|
||||
else if (token.trim()) await services.setCredential(connection.id, token)
|
||||
else if (target.enabled && (await services.status(connection.id)) !== 'configured') {
|
||||
throw new Error(automation.value.bearerTokenRequired)
|
||||
}
|
||||
|
||||
services.save({ ...target, id: connection.id })
|
||||
})
|
||||
if (!current(request)) return false
|
||||
|
|
|
|||
|
|
@ -42,10 +42,18 @@ export function useStorageSettings(credentialDrafts: Ref<Record<string, string>>
|
|||
|
||||
async function refreshStatuses(): Promise<void> {
|
||||
const request = ++statusRequest
|
||||
const id = provider.value.id
|
||||
const statuses = await storageCredentialStatuses(id)
|
||||
if (!disposed && statusRequest === request && provider.value.id === id)
|
||||
credentialStatuses.value = statuses
|
||||
const target = provider.value
|
||||
try {
|
||||
const statuses = await storageCredentialStatuses(target.id)
|
||||
if (!disposed && statusRequest === request && provider.value.id === target.id)
|
||||
credentialStatuses.value = statuses
|
||||
} catch {
|
||||
if (!disposed && statusRequest === request && provider.value.id === target.id) {
|
||||
credentialStatuses.value = Object.fromEntries(
|
||||
target.credentialFields.map((field) => [field.id, 'unavailable' as const])
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function savePreferences(): void {
|
||||
|
|
|
|||
|
|
@ -280,3 +280,41 @@ test('reopened editors serialize writes to the same connection while other conne
|
|||
secondScope.stop()
|
||||
}
|
||||
})
|
||||
|
||||
test('blank-token save rechecks status after a different editor clears the credential', async () => {
|
||||
const scope = effectScope()
|
||||
let configured = true
|
||||
const enabled: boolean[] = []
|
||||
const services = {
|
||||
status: async () => (configured ? ('configured' as const) : ('missing' as const)),
|
||||
setCredential: async (_id: string, value: string) => {
|
||||
configured = Boolean(value)
|
||||
},
|
||||
save: (draft: { enabled: boolean }) => {
|
||||
enabled.push(draft.enabled)
|
||||
return connection
|
||||
},
|
||||
remove: async () => undefined
|
||||
}
|
||||
try {
|
||||
const first = scope.run(() =>
|
||||
useMCPConnectionSettings(ref(''), ref({ bearerTokenRequired: 'Required' }), services)
|
||||
)
|
||||
const second = scope.run(() =>
|
||||
useMCPConnectionSettings(ref(''), ref({ bearerTokenRequired: 'Required' }), services)
|
||||
)
|
||||
if (!first || !second) throw new Error('Missing scope')
|
||||
await first.startEdit(connection.id)
|
||||
await second.startEdit(connection.id)
|
||||
second.draft.value.authenticationType = 'bearer'
|
||||
second.draft.value.enabled = true
|
||||
const clearing = first.clearCredential()
|
||||
const saving = second.save()
|
||||
await clearing
|
||||
expect(await saving).toBe(false)
|
||||
expect(second.error.value).toBe('Required')
|
||||
expect(enabled).toEqual([false, false])
|
||||
} finally {
|
||||
scope.stop()
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue