import type { ConnectorMetadata } from '@logto/connector-kit'; import { ConnectorType } from '@logto/connector-kit'; import { adminConsoleApplicationId } from '@logto/schemas/lib/seeds'; import etag from 'etag'; import type { Provider } from 'oidc-provider'; import { getLogtoConnectors } from '@/connectors'; import { getApplicationIdFromInteraction } from '@/lib/session'; import { getSignInExperienceForApplication } from '@/lib/sign-in-experience'; import type { AnonymousRouter } from './types'; export default function wellKnownRoutes(router: T, provider: Provider) { router.get( '/.well-known/sign-in-exp', async (ctx, next) => { const applicationId = await getApplicationIdFromInteraction(ctx, provider); const [signInExperience, logtoConnectors] = await Promise.all([ getSignInExperienceForApplication(applicationId), getLogtoConnectors(), ]); const forgotPassword = { sms: logtoConnectors.some( ({ type, dbEntry: { enabled } }) => type === ConnectorType.Sms && enabled ), email: logtoConnectors.some( ({ type, dbEntry: { enabled } }) => type === ConnectorType.Email && enabled ), }; const socialConnectors = applicationId === adminConsoleApplicationId ? [] : signInExperience.socialSignInConnectorTargets.reduce< Array >((previous, connectorTarget) => { const connectors = logtoConnectors.filter( ({ metadata: { target }, dbEntry: { enabled } }) => target === connectorTarget && enabled ); return [ ...previous, ...connectors.map(({ metadata, dbEntry: { id } }) => ({ ...metadata, id })), ]; }, []); ctx.body = { ...signInExperience, socialConnectors, forgotPassword, }; return next(); }, async (ctx, next) => { await next(); ctx.response.etag = etag(JSON.stringify(ctx.body)); if (ctx.fresh) { ctx.status = 304; ctx.body = null; } } ); }