import type { ConnectorMetadata } from '@logto/connector-kit'; import { ConnectorType } from '@logto/connector-kit'; import { adminConsoleApplicationId } from '@logto/schemas'; import etag from 'etag'; import type { Provider } from 'oidc-provider'; import { getLogtoConnectors } from '#src/connectors/index.js'; import { getApplicationIdFromInteraction } from '#src/libraries/session.js'; import { getSignInExperienceForApplication } from '#src/libraries/sign-in-experience/index.js'; import type { AnonymousRouter } from './types.js'; 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 }) => type === ConnectorType.Sms), email: logtoConnectors.some(({ type }) => type === ConnectorType.Email), }; const socialConnectors = applicationId === adminConsoleApplicationId ? [] : signInExperience.socialSignInConnectorTargets.reduce< Array >((previous, connectorTarget) => { const connectors = logtoConnectors.filter( ({ metadata: { target } }) => target === connectorTarget ); 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; } } ); }