diff --git a/packages/server/src/api/controllers/oauth2.ts b/packages/server/src/api/controllers/oauth2.ts index 6447d60f0b..ff741b0065 100644 --- a/packages/server/src/api/controllers/oauth2.ts +++ b/packages/server/src/api/controllers/oauth2.ts @@ -7,6 +7,8 @@ import { RequiredKeys, OAuth2ConfigResponse, PASSWORD_REPLACEMENT, + ValidateConfigResponse, + ValidateConfigRequest, } from "@budibase/types" import sdk from "../../sdk" @@ -75,3 +77,18 @@ export async function remove( await sdk.oauth2.remove(configToRemove) ctx.status = 204 } + +export async function validate( + ctx: Ctx +) { + const { body } = ctx.request + const config = { + url: body.url, + clientId: body.clientId, + clientSecret: body.clientSecret, + } + + const validation = await sdk.oauth2.validateConfig(config) + ctx.status = 201 + ctx.body = validation +} diff --git a/packages/server/src/api/routes/oauth2.ts b/packages/server/src/api/routes/oauth2.ts index 2ae3cbdf82..5f005fc408 100644 --- a/packages/server/src/api/routes/oauth2.ts +++ b/packages/server/src/api/routes/oauth2.ts @@ -38,5 +38,10 @@ router.delete( authorized(PermissionType.BUILDER), controller.remove ) +router.post( + "/api/oauth2/:id/validate", + authorized(PermissionType.BUILDER), + controller.validate +) export default router diff --git a/packages/server/src/sdk/app/oauth2/utils.ts b/packages/server/src/sdk/app/oauth2/utils.ts index da36cd0478..517b648379 100644 --- a/packages/server/src/sdk/app/oauth2/utils.ts +++ b/packages/server/src/sdk/app/oauth2/utils.ts @@ -31,3 +31,30 @@ export async function generateToken(id: string) { return `${jsonResponse.token_type} ${jsonResponse.access_token}` } + +export async function validateConfig(config: { + url: string + clientId: string + clientSecret: string +}): Promise<{ valid: boolean; message?: string }> { + const resp = await fetch(config.url, { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: new URLSearchParams({ + grant_type: "client_credentials", + client_id: config.clientId, + client_secret: config.clientSecret, + }), + redirect: "follow", + }) + + const jsonResponse = await resp.json() + if (!resp.ok) { + const message = jsonResponse.error_description ?? resp.statusText + return { valid: false, message } + } + + return { valid: true } +} diff --git a/packages/types/src/api/web/app/oauth2.ts b/packages/types/src/api/web/app/oauth2.ts index 1790676c0d..9c915007b9 100644 --- a/packages/types/src/api/web/app/oauth2.ts +++ b/packages/types/src/api/web/app/oauth2.ts @@ -20,3 +20,14 @@ export interface UpsertOAuth2ConfigRequest { export interface UpsertOAuth2ConfigResponse { config: OAuth2ConfigResponse } + +export interface ValidateConfigRequest { + url: string + clientId: string + clientSecret: string +} + +export interface ValidateConfigResponse { + valid: boolean + message?: string +}