From 65af6ca9bc97a8fe60e4a84b5a9b51cfc4314063 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Mon, 30 Jan 2023 22:40:11 +0000 Subject: [PATCH] style authorization screen --- frontend/src/components/avatar/index.tsx | 6 +- .../routes/(admin)/oauth/authorize/index.tsx | 127 +++++++++++++----- 2 files changed, 95 insertions(+), 38 deletions(-) diff --git a/frontend/src/components/avatar/index.tsx b/frontend/src/components/avatar/index.tsx index 4451a0d..9c6e15a 100644 --- a/frontend/src/components/avatar/index.tsx +++ b/frontend/src/components/avatar/index.tsx @@ -1,9 +1,11 @@ import { component$ } from '@builder.io/qwik' import type { Account } from '~/types' +type AvatarDetails = Pick + type Props = { - primary: Account - secondary: Account | null + primary: AvatarDetails + secondary: AvatarDetails | null } export const Avatar = component$(({ primary, secondary }) => { diff --git a/frontend/src/routes/(admin)/oauth/authorize/index.tsx b/frontend/src/routes/(admin)/oauth/authorize/index.tsx index e9f4052..9b95d4a 100644 --- a/frontend/src/routes/(admin)/oauth/authorize/index.tsx +++ b/frontend/src/routes/(admin)/oauth/authorize/index.tsx @@ -4,6 +4,8 @@ import type { Client } from 'wildebeest/backend/src/mastodon/client' import { getClientById } from 'wildebeest/backend/src/mastodon/client' import { DocumentHead, loader$ } from '@builder.io/qwik-city' import { WildebeestLogo } from '~/components/MastodonLogo' +import { Avatar } from '~/components/avatar' +import { getPersonByEmail } from 'wildebeest/backend/src/activitypub/actors' export const clientLoader = loader$<{ DATABASE: D1Database }, Promise>(async ({ platform, query }) => { const client_id = query.get('client_id') || '' @@ -14,50 +16,103 @@ export const clientLoader = loader$<{ DATABASE: D1Database }, Promise>(a return client }) -export const userLoader = loader$<{ DATABASE: D1Database; domain: string }, Promise<{ email: string }>>( - async ({ cookie }) => { - const jwt = cookie.get('CF_Authorization') - if (jwt === null) { - throw new Error('missing authorization') - } - try { - // TODO: eventually, verify the JWT with Access, however this - // is not critical. - const payload = access.getPayload(jwt.value) - return { email: payload.email } - } catch (err: unknown) { - console.warn(err.stack) - throw new Error('failed to validate Access JWT') - } +export const userLoader = loader$< + { DATABASE: D1Database; domain: string }, + Promise<{ email: string; avatar: URL; name: string; url: URL }> +>(async ({ cookie, platform }) => { + const jwt = cookie.get('CF_Authorization') + if (jwt === null) { + throw new Error('missing authorization') } -) + let payload: access.JWTPayload + try { + // TODO: eventually, verify the JWT with Access, however this + // is not critical. + payload = access.getPayload(jwt.value) + } catch (err: unknown) { + console.warn((err as { stack: unknown }).stack) + throw new Error('failed to validate Access JWT') + } + + if (!payload.email) { + throw new Error("The Access JWT doesn't contain an email") + } + + const person = await getPersonByEmail(platform.DATABASE, payload.email) + if (!person) { + throw new Error(`Failed to fetch a person from the provided email (${payload.email})`) + } + + const name = person.name + const avatar = person.icon?.url + const url = person.url + + if (!name || !avatar) { + throw new Error(`The person associated with the Access JWT does't include a name or avatar`) + } + + return { email: payload.email, avatar, name, url } +}) export default component$(() => { const client = clientLoader.use().value - const user = userLoader.use().value + const { email, avatar, name: display_name, url } = userLoader.use().value return ( -
-

- +
+

+

-
-

Signed in as: {user.email}.

-

- Click here to change account. +


+
+
+
+
+ +
+

Signed in as:

+

{email}

+
+ +
+ +
+
+
+

Authorization required

+

+ {client.name} + + {' '} + would like permission to access your account. It is a third-party application. + + If you do not trust it, then you should not authorize it.

+

Review permissions

+
+ + Everything + Read and write access +
+
+ +
-

- {client.name} would like permission to access your account. It is a third-party application. If you do - not trust it, then you should not authorize it. -

-
- -
) })