// SPDX-License-Identifier: AGPL-3.0-or-later import {randomUUID} from 'node:crypto'; import type {ApplicationResponse} from '@fluxer/schema/src/domains/oauth/OAuthSchemas'; import {createTestAccount} from '../../auth/tests/AuthTestUtils'; import type {ApiTestHarness} from '../../test/ApiTestHarness'; import {createBuilder} from '../../test/TestRequestBuilder'; interface TestBotAccount { appId: string; botUserId: string; botToken: string; clientSecret: string; ownerEmail: string; ownerPassword: string; ownerUserId: string; ownerToken: string; } async function createOAuth2BotApplication( harness: ApiTestHarness, ownerToken: string, name: string, redirectURIs: Array = [], ): Promise<{ appId: string; botUserId: string; botToken: string; clientSecret: string; }> { const app = await createBuilder(harness, ownerToken) .post('/oauth2/applications') .body({ name, redirect_uris: redirectURIs, }) .execute(); if (!app.id || !app.client_secret || !app.bot?.id || !app.bot?.token) { throw new Error('Application response missing required fields'); } return { appId: app.id, botUserId: app.bot.id, botToken: app.bot.token, clientSecret: app.client_secret, }; } export async function createTestBotAccount( harness: ApiTestHarness, params?: { appName?: string; redirectURIs?: Array; }, ): Promise { const owner = await createTestAccount(harness); const appName = params?.appName ?? `Test Bot ${randomUUID()}`; const botApp = await createOAuth2BotApplication(harness, owner.token, appName, params?.redirectURIs); return { appId: botApp.appId, botUserId: botApp.botUserId, botToken: botApp.botToken, clientSecret: botApp.clientSecret, ownerEmail: owner.email, ownerPassword: owner.password, ownerUserId: owner.userId, ownerToken: owner.token, }; } export async function authorizeBot( harness: ApiTestHarness, userToken: string, clientId: string, scopes: Array, guildId?: string, permissions?: string, ): Promise<{ redirectUrl: string; }> { const body: Record = { client_id: clientId, scope: scopes.join(' '), }; if (guildId) { body.guild_id = guildId; } if (permissions) { body.permissions = permissions; } const consent = await createBuilder<{ redirect_to: string; }>(harness, userToken) .post('/oauth2/authorize/consent') .body(body) .execute(); if (!consent.redirect_to) { throw new Error('Authorization response missing redirect_to'); } return {redirectUrl: consent.redirect_to}; }