mirror of
https://github.com/logto-io/logto.git
synced 2025-03-31 22:51:25 -05:00
fix(core): get per app sie (#2433)
This commit is contained in:
parent
9118b59288
commit
d634cb1b0e
12 changed files with 167 additions and 124 deletions
|
@ -1,6 +1,7 @@
|
|||
import { getUnixTime } from 'date-fns';
|
||||
import type { Context } from 'koa';
|
||||
import type { InteractionResults, Provider } from 'oidc-provider';
|
||||
import { errors } from 'oidc-provider';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { findUserById, updateUserById } from '@/queries/user';
|
||||
|
@ -66,3 +67,27 @@ export const saveUserFirstConsentedAppId = async (userId: string, applicationId:
|
|||
await updateUserById(userId, { applicationId });
|
||||
}
|
||||
};
|
||||
|
||||
export const getApplicationIdFromInteraction = async (
|
||||
ctx: Context,
|
||||
provider: Provider
|
||||
): Promise<string | undefined> => {
|
||||
const interaction = await provider
|
||||
.interactionDetails(ctx.req, ctx.res)
|
||||
.catch((error: unknown) => {
|
||||
// Should not block if interaction is not found
|
||||
if (error instanceof errors.SessionNotFound) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
|
||||
if (!interaction?.params) {
|
||||
return;
|
||||
}
|
||||
|
||||
return typeof interaction.params.client_id === 'string'
|
||||
? interaction.params.client_id
|
||||
: undefined;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import { builtInLanguages } from '@logto/phrases-ui';
|
||||
import type { Branding, LanguageInfo, TermsOfUse } from '@logto/schemas';
|
||||
import { ConnectorType, BrandingStyle } from '@logto/schemas';
|
||||
import type { Branding, LanguageInfo, SignInExperience, TermsOfUse } from '@logto/schemas';
|
||||
import { SignInMode, ConnectorType, BrandingStyle } from '@logto/schemas';
|
||||
import {
|
||||
adminConsoleApplicationId,
|
||||
adminConsoleSignInExperience,
|
||||
demoAppApplicationId,
|
||||
} from '@logto/schemas/lib/seeds';
|
||||
import i18next from 'i18next';
|
||||
|
||||
import { getLogtoConnectors } from '@/connectors';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
|
@ -9,6 +15,7 @@ import {
|
|||
findDefaultSignInExperience,
|
||||
updateDefaultSignInExperience,
|
||||
} from '@/queries/sign-in-experience';
|
||||
import { hasActiveUsers } from '@/queries/user';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
|
||||
export * from './sign-up';
|
||||
|
@ -56,3 +63,44 @@ export const removeUnavailableSocialConnectorTargets = async () => {
|
|||
),
|
||||
});
|
||||
};
|
||||
|
||||
export const getSignInExperienceForApplication = async (
|
||||
applicationId?: string
|
||||
): Promise<SignInExperience & { notification?: string }> => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
|
||||
// Hard code AdminConsole sign-in methods settings.
|
||||
if (applicationId === adminConsoleApplicationId) {
|
||||
return {
|
||||
...adminConsoleSignInExperience,
|
||||
branding: {
|
||||
...adminConsoleSignInExperience.branding,
|
||||
slogan: i18next.t('admin_console.welcome.title'),
|
||||
},
|
||||
languageInfo: signInExperience.languageInfo,
|
||||
signInMode: (await hasActiveUsers()) ? SignInMode.SignIn : SignInMode.Register,
|
||||
socialSignInConnectorTargets: [],
|
||||
};
|
||||
}
|
||||
|
||||
// Insert Demo App Notification
|
||||
if (applicationId === demoAppApplicationId) {
|
||||
const {
|
||||
socialSignInConnectorTargets,
|
||||
languageInfo: { autoDetect, fallbackLanguage },
|
||||
} = signInExperience;
|
||||
|
||||
const notification = i18next.t(
|
||||
'demo_app.notification',
|
||||
autoDetect ? undefined : { lng: fallbackLanguage }
|
||||
);
|
||||
|
||||
return {
|
||||
...signInExperience,
|
||||
socialSignInConnectorTargets,
|
||||
notification,
|
||||
};
|
||||
}
|
||||
|
||||
return signInExperience;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,11 @@ import { validateSignUp } from './sign-up';
|
|||
|
||||
const enabledConnectors = [mockAliyunDmConnector, mockAliyunSmsConnector];
|
||||
|
||||
jest.mock('@/lib/session', () => ({
|
||||
...jest.requireActual('@/lib/session'),
|
||||
getApplicationIdFromInteraction: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('validate sign-up', () => {
|
||||
describe('There must be at least one enabled connector for the specific identifier.', () => {
|
||||
test('should throw when there is no enabled email connector and identifier is email', async () => {
|
||||
|
|
|
@ -3,10 +3,10 @@ import type { Provider } from 'oidc-provider';
|
|||
import { object, string } from 'zod';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { assignInteractionResults } from '@/lib/session';
|
||||
import { assignInteractionResults, getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
import { encryptUserPassword } from '@/lib/user';
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import {
|
||||
findUserById,
|
||||
hasUser,
|
||||
|
@ -54,7 +54,9 @@ export default function continueRoutes<T extends AnonymousRouter>(router: T, pro
|
|||
passwordEncrypted,
|
||||
passwordEncryptionMethod,
|
||||
});
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, updatedUser, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: updatedUser.id } });
|
||||
|
||||
|
@ -92,7 +94,9 @@ export default function continueRoutes<T extends AnonymousRouter>(router: T, pro
|
|||
const updatedUser = await updateUserById(userId, {
|
||||
username,
|
||||
});
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, updatedUser, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: updatedUser.id } });
|
||||
|
||||
|
@ -127,7 +131,9 @@ export default function continueRoutes<T extends AnonymousRouter>(router: T, pro
|
|||
const updatedUser = await updateUserById(userId, {
|
||||
primaryEmail: email,
|
||||
});
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, updatedUser, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: updatedUser.id } });
|
||||
|
||||
|
@ -161,7 +167,9 @@ export default function continueRoutes<T extends AnonymousRouter>(router: T, pro
|
|||
const updatedUser = await updateUserById(userId, {
|
||||
primaryPhone: phone,
|
||||
});
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, updatedUser, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: updatedUser.id } });
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ import type { Provider } from 'oidc-provider';
|
|||
import { errors } from 'oidc-provider';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import { getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
|
||||
export default function koaGuardSessionAction<StateT, ContextT, ResponseBodyT>(
|
||||
|
@ -34,7 +35,9 @@ export default function koaGuardSessionAction<StateT, ContextT, ResponseBodyT>(
|
|||
return next();
|
||||
}
|
||||
|
||||
const { signInMode } = await findDefaultSignInExperience();
|
||||
const { signInMode } = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
|
||||
if (forType === 'sign-in') {
|
||||
assertThat(signInMode !== SignInMode.Register, forbiddenError);
|
||||
|
|
|
@ -3,10 +3,10 @@ import type { MiddlewareType } from 'koa';
|
|||
import type { Provider } from 'oidc-provider';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { assignInteractionResults } from '@/lib/session';
|
||||
import { assignInteractionResults, getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
import { generateUserId, insertUser } from '@/lib/user';
|
||||
import type { WithLogContext } from '@/middleware/koa-log';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import {
|
||||
hasUserWithPhone,
|
||||
hasUserWithEmail,
|
||||
|
@ -28,7 +28,9 @@ export const smsSignInAction = <StateT, ContextT extends WithLogContext, Respons
|
|||
provider: Provider
|
||||
): MiddlewareType<StateT, ContextT, ResponseBodyT> => {
|
||||
return async (ctx, next) => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signIn.methods.some(
|
||||
({ identifier, verificationCode }) =>
|
||||
|
@ -71,7 +73,9 @@ export const emailSignInAction = <StateT, ContextT extends WithLogContext, Respo
|
|||
provider: Provider
|
||||
): MiddlewareType<StateT, ContextT, ResponseBodyT> => {
|
||||
return async (ctx, next) => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signIn.methods.some(
|
||||
({ identifier, verificationCode }) =>
|
||||
|
@ -114,7 +118,9 @@ export const smsRegisterAction = <StateT, ContextT extends WithLogContext, Respo
|
|||
provider: Provider
|
||||
): MiddlewareType<StateT, ContextT, ResponseBodyT> => {
|
||||
return async (ctx, next) => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signUp.identifier === SignUpIdentifier.Sms ||
|
||||
signInExperience.signUp.identifier === SignUpIdentifier.EmailOrSms,
|
||||
|
@ -156,7 +162,9 @@ export const emailRegisterAction = <StateT, ContextT extends WithLogContext, Res
|
|||
provider: Provider
|
||||
): MiddlewareType<StateT, ContextT, ResponseBodyT> => {
|
||||
return async (ctx, next) => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signUp.identifier === SignUpIdentifier.Email ||
|
||||
signInExperience.signUp.identifier === SignUpIdentifier.EmailOrSms,
|
||||
|
|
|
@ -51,6 +51,11 @@ jest.mock('@/lib/user', () => ({
|
|||
insertUser: async (...args: unknown[]) => insertUser(...args),
|
||||
}));
|
||||
|
||||
jest.mock('@/lib/session', () => ({
|
||||
...jest.requireActual('@/lib/session'),
|
||||
getApplicationIdFromInteraction: jest.fn(),
|
||||
}));
|
||||
|
||||
const grantSave = jest.fn(async () => 'finalGrantId');
|
||||
const grantAddOIDCScope = jest.fn();
|
||||
const grantAddResourceScope = jest.fn();
|
||||
|
|
|
@ -5,10 +5,10 @@ import type { Provider } from 'oidc-provider';
|
|||
import { object, string } from 'zod';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { assignInteractionResults } from '@/lib/session';
|
||||
import { assignInteractionResults, getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
import { encryptUserPassword, generateUserId, insertUser } from '@/lib/user';
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import {
|
||||
findUserByEmail,
|
||||
findUserByPhone,
|
||||
|
@ -104,7 +104,9 @@ export default function passwordRoutes<T extends AnonymousRouter>(router: T, pro
|
|||
async (ctx, next) => {
|
||||
const { username } = ctx.guard.body;
|
||||
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signUp.identifier === SignUpIdentifier.Username,
|
||||
new RequestError({
|
||||
|
@ -140,7 +142,9 @@ export default function passwordRoutes<T extends AnonymousRouter>(router: T, pro
|
|||
const type = 'RegisterUsernamePassword';
|
||||
ctx.log(type, { username });
|
||||
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signUp.identifier === SignUpIdentifier.Username,
|
||||
new RequestError({
|
||||
|
|
|
@ -34,6 +34,11 @@ jest.mock('@/lib/user', () => ({
|
|||
insertUser: async (...args: unknown[]) => insertUser(...args),
|
||||
}));
|
||||
|
||||
jest.mock('@/lib/session', () => ({
|
||||
...jest.requireActual('@/lib/session'),
|
||||
getApplicationIdFromInteraction: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@/queries/user', () => ({
|
||||
findUserById: async () => findUserById(),
|
||||
findUserByPhone: async () => findUserByPhone(),
|
||||
|
|
|
@ -6,7 +6,8 @@ import { object, string, unknown } from 'zod';
|
|||
|
||||
import { getLogtoConnectorById } from '@/connectors';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { assignInteractionResults } from '@/lib/session';
|
||||
import { assignInteractionResults, getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
import {
|
||||
findSocialRelatedUser,
|
||||
getUserInfoByAuthCode,
|
||||
|
@ -14,7 +15,6 @@ import {
|
|||
} from '@/lib/social';
|
||||
import { generateUserId, insertUser } from '@/lib/user';
|
||||
import koaGuard from '@/middleware/koa-guard';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import {
|
||||
hasUserWithIdentity,
|
||||
findUserById,
|
||||
|
@ -104,7 +104,9 @@ export default function socialRoutes<T extends AnonymousRouter>(router: T, provi
|
|||
lastSignInAt: Date.now(),
|
||||
});
|
||||
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, user, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: id } });
|
||||
|
||||
|
@ -143,7 +145,9 @@ export default function socialRoutes<T extends AnonymousRouter>(router: T, provi
|
|||
lastSignInAt: Date.now(),
|
||||
});
|
||||
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, user, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: id } });
|
||||
|
||||
|
@ -191,7 +195,9 @@ export default function socialRoutes<T extends AnonymousRouter>(router: T, provi
|
|||
});
|
||||
ctx.log(type, { userId: id });
|
||||
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
await checkRequiredProfile(ctx, provider, user, signInExperience);
|
||||
await assignInteractionResults(ctx, provider, { login: { accountId: id } });
|
||||
|
||||
|
|
|
@ -15,10 +15,10 @@ import type { ZodType } from 'zod';
|
|||
import { z } from 'zod';
|
||||
|
||||
import RequestError from '@/errors/RequestError';
|
||||
import { assignInteractionResults } from '@/lib/session';
|
||||
import { assignInteractionResults, getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
import { verifyUserPassword } from '@/lib/user';
|
||||
import type { LogContext } from '@/middleware/koa-log';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import { hasUser, hasUserWithEmail, hasUserWithPhone, updateUserById } from '@/queries/user';
|
||||
import assertThat from '@/utils/assert-that';
|
||||
|
||||
|
@ -196,32 +196,6 @@ export const checkRequiredProfile = async (
|
|||
throw new RequestError({ code: 'user.require_email_or_sms', status: 422 });
|
||||
}
|
||||
};
|
||||
|
||||
export const checkRequiredSignUpIdentifiers = async (identifiers: {
|
||||
username?: Nullable<string>;
|
||||
primaryEmail?: Nullable<string>;
|
||||
primaryPhone?: Nullable<string>;
|
||||
}) => {
|
||||
const { username, primaryEmail, primaryPhone } = identifiers;
|
||||
|
||||
const { signUp } = await findDefaultSignInExperience();
|
||||
|
||||
if (signUp.identifier === SignUpIdentifier.Username && !username) {
|
||||
throw new RequestError({ code: 'user.require_username', status: 422 });
|
||||
}
|
||||
|
||||
if (signUp.identifier === SignUpIdentifier.Email && !primaryEmail) {
|
||||
throw new RequestError({ code: 'user.require_email', status: 422 });
|
||||
}
|
||||
|
||||
if (signUp.identifier === SignUpIdentifier.Sms && !primaryPhone) {
|
||||
throw new RequestError({ code: 'user.require_sms', status: 422 });
|
||||
}
|
||||
|
||||
if (signUp.identifier === SignUpIdentifier.EmailOrSms && !primaryEmail && !primaryPhone) {
|
||||
throw new RequestError({ code: 'user.require_email_or_sms', status: 422 });
|
||||
}
|
||||
};
|
||||
/* eslint-enable complexity */
|
||||
|
||||
export const checkExistingSignUpIdentifiers = async (
|
||||
|
@ -260,7 +234,9 @@ export const signInWithPassword = async (
|
|||
provider: Provider,
|
||||
{ identifier, findUser, password, logType, logPayload }: SignInWithPasswordParameter
|
||||
) => {
|
||||
const signInExperience = await findDefaultSignInExperience();
|
||||
const signInExperience = await getSignInExperienceForApplication(
|
||||
await getApplicationIdFromInteraction(ctx, provider)
|
||||
);
|
||||
assertThat(
|
||||
signInExperience.signIn.methods.some(
|
||||
(method) => method.password && method.identifier === identifier
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
import type { ConnectorMetadata } from '@logto/connector-kit';
|
||||
import { ConnectorType } from '@logto/connector-kit';
|
||||
import { SignInMode } from '@logto/schemas';
|
||||
import {
|
||||
adminConsoleApplicationId,
|
||||
adminConsoleSignInExperience,
|
||||
demoAppApplicationId,
|
||||
} from '@logto/schemas/lib/seeds';
|
||||
import { adminConsoleApplicationId } from '@logto/schemas/lib/seeds';
|
||||
import etag from 'etag';
|
||||
import i18next from 'i18next';
|
||||
import type { Provider } from 'oidc-provider';
|
||||
import { errors } from 'oidc-provider';
|
||||
|
||||
import { getLogtoConnectors } from '@/connectors';
|
||||
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||
import { hasActiveUsers } from '@/queries/user';
|
||||
import { getApplicationIdFromInteraction } from '@/lib/session';
|
||||
import { getSignInExperienceForApplication } from '@/lib/sign-in-experience';
|
||||
|
||||
import type { AnonymousRouter } from './types';
|
||||
|
||||
|
@ -21,19 +14,10 @@ export default function wellKnownRoutes<T extends AnonymousRouter>(router: T, pr
|
|||
router.get(
|
||||
'/.well-known/sign-in-exp',
|
||||
async (ctx, next) => {
|
||||
const interaction = await provider
|
||||
.interactionDetails(ctx.req, ctx.res)
|
||||
.catch((error: unknown) => {
|
||||
// Should not block if interaction is not found
|
||||
if (error instanceof errors.SessionNotFound) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw error;
|
||||
});
|
||||
const applicationId = await getApplicationIdFromInteraction(ctx, provider);
|
||||
|
||||
const [signInExperience, logtoConnectors] = await Promise.all([
|
||||
findDefaultSignInExperience(),
|
||||
getSignInExperienceForApplication(applicationId),
|
||||
getLogtoConnectors(),
|
||||
]);
|
||||
|
||||
|
@ -46,56 +30,22 @@ export default function wellKnownRoutes<T extends AnonymousRouter>(router: T, pr
|
|||
),
|
||||
};
|
||||
|
||||
// Hard code AdminConsole sign-in methods settings.
|
||||
if (interaction?.params.client_id === adminConsoleApplicationId) {
|
||||
ctx.body = {
|
||||
...adminConsoleSignInExperience,
|
||||
branding: {
|
||||
...adminConsoleSignInExperience.branding,
|
||||
slogan: i18next.t('admin_console.welcome.title'),
|
||||
},
|
||||
languageInfo: signInExperience.languageInfo,
|
||||
signInMode: (await hasActiveUsers()) ? SignInMode.SignIn : SignInMode.Register,
|
||||
socialConnectors: [],
|
||||
forgotPassword,
|
||||
};
|
||||
const socialConnectors =
|
||||
applicationId === adminConsoleApplicationId
|
||||
? []
|
||||
: signInExperience.socialSignInConnectorTargets.reduce<
|
||||
Array<ConnectorMetadata & { id: string }>
|
||||
>((previous, connectorTarget) => {
|
||||
const connectors = logtoConnectors.filter(
|
||||
({ metadata: { target }, dbEntry: { enabled } }) =>
|
||||
target === connectorTarget && enabled
|
||||
);
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
// Custom Applications
|
||||
|
||||
const socialConnectors = signInExperience.socialSignInConnectorTargets.reduce<
|
||||
Array<ConnectorMetadata & { id: string }>
|
||||
>((previous, connectorTarget) => {
|
||||
const connectors = logtoConnectors.filter(
|
||||
({ metadata: { target }, dbEntry: { enabled } }) => target === connectorTarget && enabled
|
||||
);
|
||||
|
||||
return [
|
||||
...previous,
|
||||
...connectors.map(({ metadata, dbEntry: { id } }) => ({ ...metadata, id })),
|
||||
];
|
||||
}, []);
|
||||
|
||||
// Insert Demo App Notification
|
||||
if (interaction?.params.client_id === demoAppApplicationId) {
|
||||
const {
|
||||
languageInfo: { autoDetect, fallbackLanguage },
|
||||
} = signInExperience;
|
||||
|
||||
ctx.body = {
|
||||
...signInExperience,
|
||||
socialConnectors,
|
||||
notification: i18next.t(
|
||||
'demo_app.notification',
|
||||
autoDetect ? undefined : { lng: fallbackLanguage }
|
||||
),
|
||||
forgotPassword,
|
||||
};
|
||||
|
||||
return next();
|
||||
}
|
||||
return [
|
||||
...previous,
|
||||
...connectors.map(({ metadata, dbEntry: { id } }) => ({ ...metadata, id })),
|
||||
];
|
||||
}, []);
|
||||
|
||||
ctx.body = {
|
||||
...signInExperience,
|
||||
|
|
Loading…
Add table
Reference in a new issue