|
1 | 1 | import { stringifyQuery } from 'ufo' |
2 | 2 |
|
3 | | -import { defaultUserAgent } from '~~/server/utils/shared' |
| 3 | +import { defaultUserAgent, invalidateApp } from '~~/server/utils/shared' |
4 | 4 |
|
5 | 5 | export default defineEventHandler(async (event) => { |
6 | 6 | let { server, origin } = getRouterParams(event) |
@@ -43,7 +43,51 @@ export default defineEventHandler(async (event) => { |
43 | 43 | const url = `/signin/callback?${stringifyQuery({ server, token: result.access_token, vapid_key: app.vapid_key })}` |
44 | 44 | await sendRedirect(event, url, 302) |
45 | 45 | } |
46 | | - catch { |
| 46 | + catch (error: any) { |
| 47 | + // Check for invalid client error (OAuth app deleted) |
| 48 | + if (error?.data?.error === 'invalid_client' |
| 49 | + || (error?.statusCode === 401 && error?.data?.error_description?.includes('Client authentication failed'))) { |
| 50 | + // Invalidate cached app and retry once |
| 51 | + await invalidateApp(origin, server) |
| 52 | + |
| 53 | + try { |
| 54 | + const newApp = await getApp(origin, server) |
| 55 | + if (!newApp) { |
| 56 | + throw createError({ |
| 57 | + statusCode: 400, |
| 58 | + statusMessage: `Failed to re-register app for server: ${server}`, |
| 59 | + }) |
| 60 | + } |
| 61 | + |
| 62 | + const retryResult: any = await $fetch(`https://${server}/oauth/token`, { |
| 63 | + method: 'POST', |
| 64 | + headers: { |
| 65 | + 'user-agent': defaultUserAgent, |
| 66 | + }, |
| 67 | + body: { |
| 68 | + client_id: newApp.client_id, |
| 69 | + client_secret: newApp.client_secret, |
| 70 | + redirect_uri: getRedirectURI(origin, server), |
| 71 | + grant_type: 'authorization_code', |
| 72 | + code, |
| 73 | + scope: 'read write follow push', |
| 74 | + }, |
| 75 | + retry: 1, |
| 76 | + }) |
| 77 | + |
| 78 | + const url = `/signin/callback?${stringifyQuery({ server, token: retryResult.access_token, vapid_key: newApp.vapid_key })}` |
| 79 | + await sendRedirect(event, url, 302) |
| 80 | + return |
| 81 | + } |
| 82 | + catch { |
| 83 | + throw createError({ |
| 84 | + statusCode: 400, |
| 85 | + statusMessage: 'OAuth application recovery failed. Please try again.', |
| 86 | + }) |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + // Other errors (network, invalid code, etc.) |
47 | 91 | throw createError({ |
48 | 92 | statusCode: 400, |
49 | 93 | statusMessage: 'Could not complete log in.', |
|
0 commit comments