kopia lustrzana https://github.com/cloudflare/wildebeest
Merge pull request #57 from cloudflare/sven/debug-login
/oauth/token supports both JSON and FormDatapull/59/head
commit
bc2c5d7ef5
|
@ -0,0 +1,20 @@
|
|||
// Extract the request body as the type `T`. Use this function when the requset
|
||||
// can be url encoded, form data or JSON. However, not working for formData
|
||||
// containing binary data (like File).
|
||||
export async function readBody<T>(request: Request): Promise<T> {
|
||||
const contentType = request.headers.get('content-type')
|
||||
if (contentType === null) {
|
||||
throw new Error('invalid request')
|
||||
}
|
||||
if (contentType.startsWith('application/json')) {
|
||||
return request.json<T>()
|
||||
} else {
|
||||
const form = await request.formData()
|
||||
let out: any = {}
|
||||
|
||||
for (const [key, value] of form) {
|
||||
out[key] = value
|
||||
}
|
||||
return out as T
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import { strict as assert } from 'node:assert/strict'
|
|||
|
||||
import { parseHandle } from '../src/utils/parse'
|
||||
import { urlToHandle } from '../src/utils/handle'
|
||||
|
||||
import { readBody } from 'wildebeest/backend/src/utils/body'
|
||||
import { generateUserKey, unwrapPrivateKey, importPublicKey } from 'wildebeest/backend/src/utils/key-ops'
|
||||
import { signRequest } from 'wildebeest/backend/src/utils/http-signing'
|
||||
import { generateDigestHeader } from 'wildebeest/backend/src/utils/http-signing-cavage'
|
||||
|
@ -69,4 +69,37 @@ describe('utils', () => {
|
|||
const res = urlToHandle(new URL('https://host.org/users/foobar'))
|
||||
assert.equal(res, 'foobar@host.org')
|
||||
})
|
||||
|
||||
test('read body handles JSON', async () => {
|
||||
const body = JSON.stringify({ a: 1 })
|
||||
const headers = {
|
||||
'content-type': 'application/json;charset=utf-8',
|
||||
}
|
||||
const req = new Request('https://a.com', { method: 'POST', headers, body })
|
||||
|
||||
const data = await readBody<any>(req)
|
||||
assert.equal(data.a, 1)
|
||||
})
|
||||
|
||||
test('read body handles FormData', async () => {
|
||||
const body = new FormData()
|
||||
body.append('a', '1')
|
||||
|
||||
const headers = {}
|
||||
const req = new Request('https://a.com', { method: 'POST', headers, body })
|
||||
|
||||
const data = await readBody<any>(req)
|
||||
assert.equal(data.a, '1')
|
||||
})
|
||||
|
||||
test('read body handles URL encoded', async () => {
|
||||
const body = new URLSearchParams({ a: '1' })
|
||||
const headers = {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
const req = new Request('https://a.com', { method: 'POST', headers, body })
|
||||
|
||||
const data = await readBody<any>(req)
|
||||
assert.equal(data.a, '1')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -2,8 +2,13 @@
|
|||
|
||||
import * as errors from 'wildebeest/backend/src/errors'
|
||||
import type { Env } from 'wildebeest/backend/src/types/env'
|
||||
import { readBody } from 'wildebeest/backend/src/utils/body'
|
||||
import { getClientById } from 'wildebeest/backend/src/mastodon/client'
|
||||
|
||||
type Body = {
|
||||
code: string | null
|
||||
}
|
||||
|
||||
export const onRequest: PagesFunction<Env, any> = async ({ params, request, env }) => {
|
||||
return handleRequest(env.DATABASE, request)
|
||||
}
|
||||
|
@ -19,13 +24,12 @@ export async function handleRequest(db: D1Database, request: Request): Promise<R
|
|||
return new Response('', { headers })
|
||||
}
|
||||
|
||||
const formData = await request.formData()
|
||||
const code = formData.get('code')
|
||||
if (!code) {
|
||||
const data = await readBody<Body>(request)
|
||||
if (!data.code) {
|
||||
return errors.notAuthorized('missing authorization')
|
||||
}
|
||||
|
||||
const parts = code.split('.')
|
||||
const parts = data.code.split('.')
|
||||
const clientId = parts[0]
|
||||
|
||||
const client = await getClientById(db, clientId)
|
||||
|
@ -34,7 +38,7 @@ export async function handleRequest(db: D1Database, request: Request): Promise<R
|
|||
}
|
||||
|
||||
const res = {
|
||||
access_token: code,
|
||||
access_token: data.code,
|
||||
token_type: 'Bearer',
|
||||
scope: client.scopes,
|
||||
created_at: (Date.now() / 1000) | 0,
|
||||
|
|
Ładowanie…
Reference in New Issue