kopia lustrzana https://github.com/cloudflare/wildebeest
MOW-100: protect first-login behind Access
rodzic
87581e235d
commit
e00f05cdf2
|
@ -104,12 +104,11 @@ describe('Mastodon APIs', () => {
|
|||
assert.equal(count, 0)
|
||||
})
|
||||
|
||||
test('first login creates the user and redirects', async () => {
|
||||
test('first login is protected by Access', async () => {
|
||||
const db = await makeDB()
|
||||
|
||||
const params = new URLSearchParams({
|
||||
redirect_uri: 'https://redirect.com/a',
|
||||
email: 'a@cloudflare.com',
|
||||
})
|
||||
|
||||
const formData = new FormData()
|
||||
|
@ -120,7 +119,29 @@ describe('Mastodon APIs', () => {
|
|||
method: 'POST',
|
||||
body: formData,
|
||||
})
|
||||
const res = await first_login.handlePostRequest(req, db, userKEK)
|
||||
const res = await first_login.handlePostRequest(req, db, userKEK, accessDomain, accessAud)
|
||||
assert.equal(res.status, 401)
|
||||
})
|
||||
|
||||
test('first login creates the user and redirects', async () => {
|
||||
const db = await makeDB()
|
||||
|
||||
const params = new URLSearchParams({
|
||||
redirect_uri: 'https://redirect.com/a',
|
||||
})
|
||||
|
||||
const formData = new FormData()
|
||||
formData.set('username', 'username')
|
||||
formData.set('name', 'name')
|
||||
|
||||
const req = new Request('https://example.com/first-login?' + params, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
cookie: `CF_Authorization=${TEST_JWT}`,
|
||||
},
|
||||
})
|
||||
const res = await first_login.handlePostRequest(req, db, userKEK, accessDomain, accessAud)
|
||||
assert.equal(res.status, 302)
|
||||
|
||||
const location = res.headers.get('location')
|
||||
|
@ -129,7 +150,7 @@ describe('Mastodon APIs', () => {
|
|||
const actor = await db.prepare('SELECT * FROM actors').first()
|
||||
const properties = JSON.parse(actor.properties)
|
||||
|
||||
assert.equal(actor.email, 'a@cloudflare.com')
|
||||
assert.equal(actor.email, 'sven@cloudflare.com')
|
||||
assert.equal(properties.preferredUsername, 'username')
|
||||
assert.equal(properties.name, 'name')
|
||||
assert(isUrlValid(actor.id))
|
||||
|
|
|
@ -3,17 +3,41 @@
|
|||
import type { Env } from 'wildebeest/backend/src/types/env'
|
||||
import type { ContextData } from 'wildebeest/backend/src/types/context'
|
||||
import { createPerson } from 'wildebeest/backend/src/activitypub/actors'
|
||||
import { parse } from 'cookie'
|
||||
import * as errors from 'wildebeest/backend/src/errors'
|
||||
import * as access from 'wildebeest/backend/src/access'
|
||||
|
||||
export const onRequestPost: PagesFunction<Env, any, ContextData> = async ({ request, env }) => {
|
||||
return handlePostRequest(request, env.DATABASE, env.userKEK)
|
||||
return handlePostRequest(request, env.DATABASE, env.userKEK, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
|
||||
}
|
||||
|
||||
// FIXME: move this behind Cloudflare Access. We can find the JWT in the cookies
|
||||
export async function handlePostRequest(request: Request, db: D1Database, userKEK: string): Promise<Response> {
|
||||
export async function handlePostRequest(
|
||||
request: Request,
|
||||
db: D1Database,
|
||||
userKEK: string,
|
||||
accessDomain: string,
|
||||
accessAud: string
|
||||
): Promise<Response> {
|
||||
const url = new URL(request.url)
|
||||
// TODO: email is in the JWT, should be parsed, verified and passed in the
|
||||
// request context.
|
||||
const email = url.searchParams.get('email') || ''
|
||||
const cookie = parse(request.headers.get('Cookie') || '')
|
||||
|
||||
const jwt = cookie['CF_Authorization']
|
||||
if (!jwt) {
|
||||
return errors.notAuthorized('missing CF_Authorization')
|
||||
}
|
||||
|
||||
const payload = access.getPayload(jwt)
|
||||
if (!payload.email) {
|
||||
return errors.notAuthorized('missing email')
|
||||
}
|
||||
|
||||
const validatate = access.generateValidator({
|
||||
jwt,
|
||||
domain: accessDomain,
|
||||
aud: accessAud,
|
||||
})
|
||||
await validatate(request)
|
||||
|
||||
const domain = url.hostname
|
||||
|
||||
const formData = await request.formData()
|
||||
|
@ -27,7 +51,7 @@ export async function handlePostRequest(request: Request, db: D1Database, userKE
|
|||
properties.name = formData.get('name') || ''
|
||||
}
|
||||
|
||||
await createPerson(domain, db, userKEK, email, properties)
|
||||
await createPerson(domain, db, userKEK, payload.email, properties)
|
||||
|
||||
if (!url.searchParams.has('redirect_uri')) {
|
||||
return new Response('', { status: 400 })
|
||||
|
|
Ładowanie…
Reference in New Issue