Merge pull request #157 from cloudflare/sven/gh-86

gh-86: implement authorization screen
pull/158/head
Sven Sauleau 2023-01-30 13:00:19 +01:00 zatwierdzone przez GitHub
commit 74f0ff9097
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
3 zmienionych plików z 84 dodań i 9 usunięć

Wyświetl plik

@ -35,11 +35,11 @@ describe('Mastodon APIs', () => {
const db = await makeDB()
let req = new Request('https://example.com/oauth/authorize')
let res = await oauth_authorize.handleRequest(req, db, userKEK, accessDomain, accessAud)
let res = await oauth_authorize.handleRequestPost(req, db, userKEK, accessDomain, accessAud)
assert.equal(res.status, 400)
req = new Request('https://example.com/oauth/authorize?scope=foobar')
res = await oauth_authorize.handleRequest(req, db, userKEK, accessDomain, accessAud)
res = await oauth_authorize.handleRequestPost(req, db, userKEK, accessDomain, accessAud)
assert.equal(res.status, 400)
})
@ -53,7 +53,7 @@ describe('Mastodon APIs', () => {
})
const req = new Request('https://example.com/oauth/authorize?' + params)
const res = await oauth_authorize.handleRequest(req, db, userKEK, accessDomain, accessAud)
const res = await oauth_authorize.handleRequestPost(req, db, userKEK, accessDomain, accessAud)
assert.equal(res.status, 400)
})
@ -72,7 +72,7 @@ describe('Mastodon APIs', () => {
const req = new Request('https://example.com/oauth/authorize?' + params, {
headers,
})
const res = await oauth_authorize.handleRequest(req, db, userKEK, accessDomain, accessAud)
const res = await oauth_authorize.handleRequestPost(req, db, userKEK, accessDomain, accessAud)
assert.equal(res.status, 403)
})
@ -91,7 +91,7 @@ describe('Mastodon APIs', () => {
const req = new Request('https://example.com/oauth/authorize?' + params, {
headers,
})
const res = await oauth_authorize.handleRequest(req, db, userKEK, accessDomain, accessAud)
const res = await oauth_authorize.handleRequestPost(req, db, userKEK, accessDomain, accessAud)
assert.equal(res.status, 302)
const location = new URL(res.headers.get('location') || '')
@ -223,7 +223,7 @@ describe('Mastodon APIs', () => {
const req = new Request('https://example.com/oauth/authorize', {
method: 'OPTIONS',
})
const res = await oauth_authorize.handleRequest(req, db, userKEK, accessDomain, accessAud)
const res = await oauth_authorize.handleRequestPost(req, db, userKEK, accessDomain, accessAud)
assert.equal(res.status, 200)
assertCORS(res)
})

Wyświetl plik

@ -0,0 +1,75 @@
import { component$ } from '@builder.io/qwik'
import * as access from 'wildebeest/backend/src/access'
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'
export const clientLoader = loader$<{ DATABASE: D1Database }, Promise<Client>>(async ({ platform, query }) => {
const client_id = query.get('client_id') || ''
const client = await getClientById(platform.DATABASE, client_id)
if (client === null) {
throw new Error('client not found')
}
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 default component$(() => {
const client = clientLoader.use().value
const user = userLoader.use().value
return (
<div class="flex flex-col p-5 items-center">
<h1 class="text-center mt-7 mb-9 flex items-center">
<WildebeestLogo size="large" />
</h1>
<div class="text-left">
<p>Signed in as: {user.email}.</p>
<p>
<a href="/cdn-cgi/access/logout">Click here to change account</a>.
</p>
</div>
<p class="text-left">
<b>{client.name}</b> 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.
</p>
<form method="post" class="flex flex-col w-full max-w-md">
<button
type="submit"
class="mb-9 bg-wildebeest-vibrant-600 hover:bg-wildebeest-vibrant-500 p-3 text-white text-uppercase border-wildebeest-vibrant-600 text-lg text-semi outline-none border rounded hover:border-wildebeest-vibrant-500 focus:border-wildebeest-vibrant-500"
>
Authorize
</button>
</form>
</div>
)
})
export const head: DocumentHead = () => {
return {
title: 'Wildebeest Authorization required',
meta: [
{
name: 'description',
content: 'Wildebeest Authorization required',
},
],
}
}

Wyświetl plik

@ -11,11 +11,11 @@ import { getPersonByEmail } from 'wildebeest/backend/src/activitypub/actors'
// Extract the JWT token sent by Access (running before us).
const extractJWTFromRequest = (request: Request) => request.headers.get('Cf-Access-Jwt-Assertion') || ''
export const onRequest: PagesFunction<Env, any, ContextData> = async ({ request, env }) => {
return handleRequest(request, env.DATABASE, env.userKEK, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
export const onRequestPost: PagesFunction<Env, any, ContextData> = async ({ request, env }) => {
return handleRequestPost(request, env.DATABASE, env.userKEK, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
}
export async function handleRequest(
export async function handleRequestPost(
request: Request,
db: D1Database,
userKEK: string,