diff --git a/server/api/[server]/login.ts b/server/api/[server]/login.ts index 35539c5e..ec193959 100644 --- a/server/api/[server]/login.ts +++ b/server/api/[server]/login.ts @@ -17,9 +17,9 @@ export default defineEventHandler(async (event) => { client_id: app.client_id, force_login: force_login === true ? 'true' : 'false', scope: 'read write follow push', - redirect_uri: getRedirectURI(origin, server), response_type: 'code', lang, + redirect_uri: getRedirectURI(origin, server), }) return `https://${server}/oauth/authorize?${query}` diff --git a/server/api/[server]/oauth.ts b/server/api/[server]/oauth.ts deleted file mode 100644 index 7f4df3d2..00000000 --- a/server/api/[server]/oauth.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { stringifyQuery } from 'ufo' - -export default defineEventHandler(async (event) => { - const { origin } = getQuery(event) as { origin: string } - let { server } = getRouterParams(event) - server = server.toLocaleLowerCase().trim() - const app = await getApp(origin, server) - - if (!app) { - throw createError({ - statusCode: 400, - statusMessage: `App not registered for server: ${server}`, - }) - } - - const { code } = getQuery(event) - if (!code) { - throw createError({ - statusCode: 422, - statusMessage: 'Missing authentication code.', - }) - } - - const result: any = await $fetch(`https://${server}/oauth/token`, { - method: 'POST', - body: { - client_id: app.client_id, - client_secret: app.client_secret, - redirect_uri: getRedirectURI(origin, server), - grant_type: 'authorization_code', - code, - scope: 'read write follow push', - }, - retry: 3, - }) - - const url = `/signin/callback?${stringifyQuery({ server, token: result.access_token, vapid_key: app.vapid_key })}` - await sendRedirect(event, url, 302) -}) diff --git a/server/api/[server]/oauth/[origin].ts b/server/api/[server]/oauth/[origin].ts new file mode 100644 index 00000000..af98aa25 --- /dev/null +++ b/server/api/[server]/oauth/[origin].ts @@ -0,0 +1,47 @@ +import { stringifyQuery } from 'ufo' + +export default defineEventHandler(async (event) => { + let { server, origin } = getRouterParams(event) + server = server.toLocaleLowerCase().trim() + origin = decodeURIComponent(origin) + const app = await getApp(origin, server) + + if (!app) { + throw createError({ + statusCode: 400, + statusMessage: `App not registered for server: ${server}`, + }) + } + + const { code } = getQuery(event) + if (!code) { + throw createError({ + statusCode: 422, + statusMessage: 'Missing authentication code.', + }) + } + + try { + const result: any = await $fetch(`https://${server}/oauth/token`, { + method: 'POST', + body: { + client_id: app.client_id, + client_secret: app.client_secret, + redirect_uri: getRedirectURI(origin, server), + grant_type: 'authorization_code', + code, + scope: 'read write follow push', + }, + retry: 3, + }) + + const url = `/signin/callback?${stringifyQuery({ server, token: result.access_token, vapid_key: app.vapid_key })}` + await sendRedirect(event, url, 302) + } + catch (e) { + throw createError({ + statusCode: 400, + statusMessage: 'Could not complete log in.', + }) + } +}) diff --git a/server/utils/shared.ts b/server/utils/shared.ts index 3f729893..537d6671 100644 --- a/server/utils/shared.ts +++ b/server/utils/shared.ts @@ -2,8 +2,6 @@ import fs from 'unstorage/drivers/fs' import memory from 'unstorage/drivers/memory' import kv from 'unstorage/drivers/cloudflare-kv-http' -import { stringifyQuery } from 'ufo' - import { $fetch } from 'ofetch' import type { Storage } from 'unstorage' @@ -36,7 +34,8 @@ else if (driver === 'memory') { } export function getRedirectURI(origin: string, server: string) { - return `${origin}/api/${server}/oauth?${stringifyQuery({ origin })}` + origin = origin.replace(/\?.*$/, '') + return `${origin}/api/${server}/oauth/${encodeURIComponent(origin)}` } async function fetchAppInfo(origin: string, server: string) { @@ -53,8 +52,8 @@ async function fetchAppInfo(origin: string, server: string) { } export async function getApp(origin: string, server: string) { - const host = origin.replace(/^https?:\/\//, '').replace(/[^\w\d]/g, '-') - const key = `servers:v2:${server}:${host}.json`.toLowerCase() + const host = origin.replace(/^https?:\/\//, '').replace(/[^\w\d]/g, '-').replace(/\?.*$/, '') + const key = `servers:v3:${server}:${host}.json`.toLowerCase() try { if (await storage.hasItem(key)) @@ -69,13 +68,13 @@ export async function getApp(origin: string, server: string) { } export async function deleteApp(server: string) { - const keys = (await storage.getKeys(`servers:v2:${server}:`)) + const keys = (await storage.getKeys(`servers:v3:${server}:`)) for (const key of keys) await storage.removeItem(key) } export async function listServers() { - const keys = await storage.getKeys('servers:v2:') + const keys = await storage.getKeys('servers:v3:') const servers = new Set() for await (const key of keys) { const id = key.split(':')[2]