diff --git a/.changeset/thirty-turtles-carry.md b/.changeset/thirty-turtles-carry.md new file mode 100644 index 0000000000..96b0495561 --- /dev/null +++ b/.changeset/thirty-turtles-carry.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend': patch +--- + +Show better error message when configs defined under auth.providers. are undefined. diff --git a/plugins/auth-backend/src/service/router.ts b/plugins/auth-backend/src/service/router.ts index fa551f6ec2..e988fde97c 100644 --- a/plugins/auth-backend/src/service/router.ts +++ b/plugins/auth-backend/src/service/router.ts @@ -86,50 +86,69 @@ export async function createRouter({ ...providerFactories, }; const providersConfig = config.getConfig('auth.providers'); - const providers = providersConfig.keys(); + const configuredProviders = providersConfig.keys(); - for (const providerId of providers) { - logger.info(`Configuring provider, ${providerId}`); - try { - const providerFactory = allProviderFactories[providerId]; - if (!providerFactory) { - throw Error(`No auth provider available for '${providerId}'`); + for (const [providerId, providerFactory] of Object.entries( + allProviderFactories, + )) { + if (configuredProviders.includes(providerId)) { + logger.info(`Configuring provider, ${providerId}`); + try { + const provider = providerFactory({ + providerId, + globalConfig: { baseUrl: authUrl, appUrl }, + config: providersConfig.getConfig(providerId), + logger, + tokenIssuer, + discovery, + catalogApi, + }); + + const r = Router(); + + r.get('/start', provider.start.bind(provider)); + r.get('/handler/frame', provider.frameHandler.bind(provider)); + r.post('/handler/frame', provider.frameHandler.bind(provider)); + if (provider.logout) { + r.post('/logout', provider.logout.bind(provider)); + } + if (provider.refresh) { + r.get('/refresh', provider.refresh.bind(provider)); + } + + router.use(`/${providerId}`, r); + } catch (e) { + if (process.env.NODE_ENV !== 'development') { + throw new Error( + `Failed to initialize ${providerId} auth provider, ${e.message}`, + ); + } + + logger.warn(`Skipping ${providerId} auth provider, ${e.message}`); + + router.use(`/${providerId}`, () => { + // If the user added the provider under auth.providers but the clientId and clientSecret etc. were not found. + throw new NotFoundError( + `Auth provider registered for '${providerId}' is misconfigured. This could mean the configs under ` + + `auth.providers.${providerId} are missing or the environment variables used are not defined. ` + + `Check the auth backend plugin logs when the backend starts to see more details.`, + ); + }); } - - const provider = providerFactory({ - providerId, - globalConfig: { baseUrl: authUrl, appUrl }, - config: providersConfig.getConfig(providerId), - logger, - tokenIssuer, - discovery, - catalogApi, - }); - - const r = Router(); - - r.get('/start', provider.start.bind(provider)); - r.get('/handler/frame', provider.frameHandler.bind(provider)); - r.post('/handler/frame', provider.frameHandler.bind(provider)); - if (provider.logout) { - r.post('/logout', provider.logout.bind(provider)); - } - if (provider.refresh) { - r.get('/refresh', provider.refresh.bind(provider)); - } - - router.use(`/${providerId}`, r); - } catch (e) { - if (process.env.NODE_ENV !== 'development') { - throw new Error( - `Failed to initialize ${providerId} auth provider, ${e.message}`, + } else { + router.use(`/${providerId}`, () => { + throw new NotFoundError( + `No auth provider registered for '${providerId}'`, ); - } - - logger.warn(`Skipping ${providerId} auth provider, ${e.message}`); + }); } } + router.use('/:provider/', req => { + const { provider } = req.params; + throw new NotFoundError(`Unknown auth provider '${provider}'`); + }); + router.use( createOidcRouter({ tokenIssuer, @@ -137,10 +156,5 @@ export async function createRouter({ }), ); - router.use('/:provider/', req => { - const { provider } = req.params; - throw new NotFoundError(`No auth provider registered for '${provider}'`); - }); - return router; }