kopia lustrzana https://github.com/elk-zone/elk
fix: auto-recover from OAuth app deletion after token revocation (#3382)
rodzic
7b7334c27a
commit
37a91a0817
|
@ -1,6 +1,6 @@
|
|||
import { stringifyQuery } from 'ufo'
|
||||
|
||||
import { defaultUserAgent } from '~~/server/utils/shared'
|
||||
import { defaultUserAgent, invalidateApp } from '~~/server/utils/shared'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
let { server, origin } = getRouterParams(event)
|
||||
|
@ -43,7 +43,51 @@ export default defineEventHandler(async (event) => {
|
|||
const url = `/signin/callback?${stringifyQuery({ server, token: result.access_token, vapid_key: app.vapid_key })}`
|
||||
await sendRedirect(event, url, 302)
|
||||
}
|
||||
catch {
|
||||
catch (error: any) {
|
||||
// Check for invalid client error (OAuth app deleted)
|
||||
if (error?.data?.error === 'invalid_client'
|
||||
|| (error?.statusCode === 401 && error?.data?.error_description?.includes('Client authentication failed'))) {
|
||||
// Invalidate cached app and retry once
|
||||
await invalidateApp(origin, server)
|
||||
|
||||
try {
|
||||
const newApp = await getApp(origin, server)
|
||||
if (!newApp) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `Failed to re-register app for server: ${server}`,
|
||||
})
|
||||
}
|
||||
|
||||
const retryResult: any = await $fetch(`https://${server}/oauth/token`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'user-agent': defaultUserAgent,
|
||||
},
|
||||
body: {
|
||||
client_id: newApp.client_id,
|
||||
client_secret: newApp.client_secret,
|
||||
redirect_uri: getRedirectURI(origin, server),
|
||||
grant_type: 'authorization_code',
|
||||
code,
|
||||
scope: 'read write follow push',
|
||||
},
|
||||
retry: 1,
|
||||
})
|
||||
|
||||
const url = `/signin/callback?${stringifyQuery({ server, token: retryResult.access_token, vapid_key: newApp.vapid_key })}`
|
||||
await sendRedirect(event, url, 302)
|
||||
return
|
||||
}
|
||||
catch {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'OAuth application recovery failed. Please try again.',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Other errors (network, invalid code, etc.)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Could not complete log in.',
|
||||
|
|
|
@ -111,6 +111,12 @@ export async function deleteApp(server: string) {
|
|||
await storage.removeItem(key)
|
||||
}
|
||||
|
||||
export async function invalidateApp(origin: string, server: string) {
|
||||
const host = origin.replace(/^https?:\/\//, '').replace(/\W/g, '-').replace(/\?.*$/, '')
|
||||
const key = `servers:v4:${server}:${host}.json`.toLowerCase()
|
||||
await storage.removeItem(key)
|
||||
}
|
||||
|
||||
export async function listServers() {
|
||||
const keys = await storage.getKeys('servers:v4:')
|
||||
const servers = new Set<string>()
|
||||
|
|
Ładowanie…
Reference in New Issue