diff --git a/packages/backend/src/server/oauth.ts b/packages/backend/src/server/oauth.ts new file mode 100644 index 000000000..65261ccc9 --- /dev/null +++ b/packages/backend/src/server/oauth.ts @@ -0,0 +1,16 @@ +import { kinds } from '@/misc/api-permissions.js'; +import config from '@/config/index.js'; + +// Since it cannot change while the server is running, we can serialize it once +// instead of having to serialize it every time it is requested. +export const oauthMeta = JSON.stringify({ + issuer: config.url, + authorization_endpoint: `${config.url}/auth`, + token_endpoint: `${config.apiUrl}/auth/session/oauth`, + scopes_supported: kinds, + response_types_supported: ['code'], + grant_types_supported: ['authorization_code'], + token_endpoint_auth_methods_supported: ['client_secret_basic'], + service_documentation: `${config.url}/api-doc`, + code_challenge_methods_supported: ['S256'], +}); diff --git a/packages/backend/src/server/well-known.ts b/packages/backend/src/server/well-known.ts index f4db66354..527aa99bc 100644 --- a/packages/backend/src/server/well-known.ts +++ b/packages/backend/src/server/well-known.ts @@ -7,6 +7,7 @@ import { escapeAttribute, escapeValue } from '@/prelude/xml.js'; import { Users } from '@/models/index.js'; import { User } from '@/models/entities/user.js'; import { links } from './nodeinfo.js'; +import { oauthMeta } from './oauth.js'; // Init router const router = new Router(); @@ -62,10 +63,21 @@ router.get('/.well-known/nodeinfo', async ctx => { ctx.body = { links }; }); -/* TODO -router.get('/.well-known/change-password', async ctx => { -}); -*/ +function oauth(ctx) { + ctx.body = oauthMeta; + ctx.type = 'application/json'; + ctx.set('Cache-Control', 'max-age=31536000, immutable'); +} + +// implements RFC 8414 +router.get('/.well-known/oauth-authorization-server', oauth); +// From the above RFC: +//> The identifiers "/.well-known/openid-configuration" [...] contain strings +//> referring to the OpenID Connect family of specifications [...]. Despite the reuse +//> of these identifiers that appear to be OpenID specific, their usage in this +//> specification is actually referring to general OAuth 2.0 features that are not +//> specific to OpenID Connect. +router.get('/.well-known/openid-configuration', oauth); router.get(webFingerPath, async ctx => { const fromId = (id: User['id']): FindOptionsWhere => ({