diff --git a/src/controllers/api/oauth.ts b/src/controllers/api/oauth.ts index c59b73f8..c56b27eb 100644 --- a/src/controllers/api/oauth.ts +++ b/src/controllers/api/oauth.ts @@ -12,26 +12,42 @@ const codeGrantSchema = z.object({ code: z.string(), }); +const credentialsGrantSchema = z.object({ + grant_type: z.literal('client_credentials'), +}); + const createTokenSchema = z.discriminatedUnion('grant_type', [ passwordGrantSchema, codeGrantSchema, + credentialsGrantSchema, ]); const createTokenController: AppController = async (c) => { const body = await parseBody(c.req.raw); - const data = createTokenSchema.parse(body); + const result = createTokenSchema.safeParse(body); - switch (data.grant_type) { + if (!result.success) { + return c.json({ error: 'Invalid request', issues: result.error.issues }, 400); + } + + switch (result.data.grant_type) { case 'password': return c.json({ - access_token: data.password, + access_token: result.data.password, token_type: 'Bearer', scope: 'read write follow push', created_at: Math.floor(new Date().getTime() / 1000), }); case 'authorization_code': return c.json({ - access_token: data.code, + access_token: result.data.code, + token_type: 'Bearer', + scope: 'read write follow push', + created_at: Math.floor(new Date().getTime() / 1000), + }); + case 'client_credentials': + return c.json({ + access_token: '_', token_type: 'Bearer', scope: 'read write follow push', created_at: Math.floor(new Date().getTime() / 1000), diff --git a/src/transmute.ts b/src/transmute.ts index 898f6543..936f6e51 100644 --- a/src/transmute.ts +++ b/src/transmute.ts @@ -39,12 +39,20 @@ async function toAccount(event: Event<0>, opts: ToAccountOpts = {}) { avatar_static: picture || DEFAULT_AVATAR, bot: false, created_at: event ? new Date(event.created_at * 1000).toISOString() : new Date().toISOString(), + discoverable: true, display_name: name, emojis: toEmojis(event), fields: [], follow_requests_count: 0, followers_count: 0, following_count: 0, + fqn: parsed05?.handle || npub, + header: banner || DEFAULT_BANNER, + header_static: banner || DEFAULT_BANNER, + last_status_at: null, + locked: false, + note: lodash.escape(about), + roles: [], source: withSource ? { fields: [], @@ -56,11 +64,6 @@ async function toAccount(event: Event<0>, opts: ToAccountOpts = {}) { } : undefined, statuses_count: 0, - header: banner || DEFAULT_BANNER, - header_static: banner || DEFAULT_BANNER, - locked: false, - note: lodash.escape(about), - fqn: parsed05?.handle || npub, url: `${origin}/users/${pubkey}`, username: parsed05?.nickname || npub.substring(0, 8), };