mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
refactor(ui): refactor ac signin exp (#1367)
* refactor(ui): refactor ac signin exp refactor ac signin exp * fix(ui): adjust style adjust style * fix(ui): cr fix cr fix
This commit is contained in:
parent
f4e0a4c7d7
commit
8c4fea093d
7 changed files with 86 additions and 65 deletions
|
@ -1,5 +1,5 @@
|
|||
import { ConnectorType, SignInMode } from '@logto/schemas';
|
||||
import { adminConsoleApplicationId, adminConsoleSignInMethods } from '@logto/schemas/lib/seeds';
|
||||
import { adminConsoleApplicationId, adminConsoleSignInExperience } from '@logto/schemas/lib/seeds';
|
||||
import { Provider } from 'oidc-provider';
|
||||
|
||||
import {
|
||||
|
@ -58,6 +58,10 @@ jest.mock('oidc-provider', () => ({
|
|||
})),
|
||||
}));
|
||||
|
||||
jest.mock('i18next', () => ({
|
||||
t: (key: string) => key,
|
||||
}));
|
||||
|
||||
describe('GET /.well-known/sign-in-exp', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
@ -112,13 +116,16 @@ describe('GET /.well-known/sign-in-exp', () => {
|
|||
it('should return admin console settings', async () => {
|
||||
interactionDetails.mockResolvedValue({ params: { client_id: adminConsoleApplicationId } });
|
||||
const response = await sessionRequest.get('/.well-known/sign-in-exp');
|
||||
expect(signInExperienceQuerySpyOn).toHaveBeenCalledTimes(1);
|
||||
expect(signInExperienceQuerySpyOn).not.toBeCalled();
|
||||
expect(response.status).toEqual(200);
|
||||
|
||||
expect(response.body).toMatchObject(
|
||||
expect.objectContaining({
|
||||
...mockSignInExperience,
|
||||
signInMethods: adminConsoleSignInMethods,
|
||||
...adminConsoleSignInExperience,
|
||||
branding: {
|
||||
...adminConsoleSignInExperience.branding,
|
||||
slogan: 'admin_console.welcome.title',
|
||||
},
|
||||
socialConnectors: [],
|
||||
signInMode: SignInMode.SignIn,
|
||||
})
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ConnectorMetadata } from '@logto/connector-types';
|
|||
import { SignInMode } from '@logto/schemas';
|
||||
import {
|
||||
adminConsoleApplicationId,
|
||||
adminConsoleSignInMethods,
|
||||
adminConsoleSignInExperience,
|
||||
demoAppApplicationId,
|
||||
} from '@logto/schemas/lib/seeds';
|
||||
import etag from 'etag';
|
||||
|
@ -19,17 +19,36 @@ export default function wellKnownRoutes<T extends AnonymousRouter>(router: T, pr
|
|||
router.get(
|
||||
'/.well-known/sign-in-exp',
|
||||
async (ctx, next) => {
|
||||
const [signInExperience, connectorInstances, interaction] = await Promise.all([
|
||||
findDefaultSignInExperience(),
|
||||
getConnectorInstances(),
|
||||
provider.interactionDetails(ctx.req, ctx.res).catch((error: unknown) => {
|
||||
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;
|
||||
}),
|
||||
});
|
||||
|
||||
// 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'),
|
||||
},
|
||||
signInMode: (await hasActiveUsers()) ? SignInMode.SignIn : SignInMode.Register,
|
||||
socialConnectors: [],
|
||||
};
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
// Custom Applications
|
||||
const [signInExperience, connectorInstances] = await Promise.all([
|
||||
findDefaultSignInExperience(),
|
||||
getConnectorInstances(),
|
||||
]);
|
||||
|
||||
const socialConnectors = signInExperience.socialSignInConnectorTargets.reduce<
|
||||
|
@ -46,30 +65,12 @@ 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 = {
|
||||
...signInExperience,
|
||||
signInMethods: adminConsoleSignInMethods,
|
||||
signInMode: (await hasActiveUsers()) ? SignInMode.SignIn : SignInMode.Register,
|
||||
socialConnectors: [],
|
||||
};
|
||||
const notification =
|
||||
interaction?.params.client_id === demoAppApplicationId
|
||||
? i18next.t('demo_app.notification')
|
||||
: undefined;
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
// Insert Notification Message to DemoApp
|
||||
if (interaction?.params.client_id === demoAppApplicationId) {
|
||||
ctx.body = {
|
||||
...signInExperience,
|
||||
socialConnectors,
|
||||
notification: i18next.t('demo_app.notification'),
|
||||
};
|
||||
|
||||
return next();
|
||||
}
|
||||
|
||||
ctx.body = { ...signInExperience, socialConnectors };
|
||||
ctx.body = { ...signInExperience, socialConnectors, notification };
|
||||
|
||||
return next();
|
||||
},
|
||||
|
|
|
@ -498,7 +498,7 @@ const translation = {
|
|||
button: 'Sign in again',
|
||||
},
|
||||
welcome: {
|
||||
title: 'Welcome to Logto Admin Console',
|
||||
title: 'Welcome to Admin Console',
|
||||
description:
|
||||
'Admin console is a web app to manage Logto without coding requirements. Let’s first create an account. With this account, you can manage Logto by yourself or on behalf of your company.',
|
||||
create_account: 'Create Account',
|
||||
|
|
|
@ -479,7 +479,7 @@ const translation = {
|
|||
button: '重新登录',
|
||||
},
|
||||
welcome: {
|
||||
title: '欢迎使用管理控制台',
|
||||
title: '欢迎来到管理控制台',
|
||||
description:
|
||||
'管理控制台是一个无需代码操作的应用。你可以用它来管理登录体验。让我们首先创建一个帐号。你可以用它以个人或公司的身份管理 Logto。',
|
||||
create_account: '创建帐号',
|
||||
|
|
|
@ -33,9 +33,11 @@ export const defaultSignInExperience: Readonly<CreateSignInExperience> = {
|
|||
signInMode: SignInMode.SignInAndRegister,
|
||||
};
|
||||
|
||||
export const adminConsoleSignInMethods = {
|
||||
username: SignInMethodState.Primary,
|
||||
email: SignInMethodState.Disabled,
|
||||
sms: SignInMethodState.Disabled,
|
||||
social: SignInMethodState.Disabled,
|
||||
export const adminConsoleSignInExperience: CreateSignInExperience = {
|
||||
...defaultSignInExperience,
|
||||
branding: {
|
||||
style: BrandingStyle.Logo_Slogan,
|
||||
logoUrl: '',
|
||||
darkLogoUrl: '',
|
||||
},
|
||||
};
|
||||
|
|
|
@ -27,6 +27,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
.placeholderTop {
|
||||
flex: 3;
|
||||
}
|
||||
|
||||
.placeholderBottom {
|
||||
flex: 5;
|
||||
}
|
||||
|
||||
:global(body.mobile) {
|
||||
.header {
|
||||
margin-top: _.unit(3);
|
||||
|
@ -48,7 +56,6 @@
|
|||
|
||||
:global(body.desktop) {
|
||||
.header {
|
||||
margin-top: _.unit(6);
|
||||
margin-bottom: _.unit(6);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import * as styles from './index.module.scss';
|
|||
import { PrimarySection, SecondarySection, CreateAccountLink } from './registry';
|
||||
|
||||
const SignIn = () => {
|
||||
const { experienceSettings, theme } = useContext(PageContext);
|
||||
const { experienceSettings, theme, platform } = useContext(PageContext);
|
||||
|
||||
if (!experienceSettings) {
|
||||
return null;
|
||||
|
@ -29,32 +29,36 @@ const SignIn = () => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.wrapper)}>
|
||||
<BrandingHeader
|
||||
className={styles.header}
|
||||
headline={style === BrandingStyle.Logo_Slogan ? slogan : undefined}
|
||||
logo={getLogto()}
|
||||
/>
|
||||
<PrimarySection
|
||||
signInMethod={experienceSettings.primarySignInMethod}
|
||||
socialConnectors={experienceSettings.socialConnectors}
|
||||
signInMode={experienceSettings.signInMode}
|
||||
/>
|
||||
|
||||
{experienceSettings.signInMode !== SignInMode.Register && (
|
||||
<SecondarySection
|
||||
primarySignInMethod={experienceSettings.primarySignInMethod}
|
||||
secondarySignInMethods={experienceSettings.secondarySignInMethods}
|
||||
socialConnectors={experienceSettings.socialConnectors}
|
||||
<>
|
||||
{platform === 'web' && <div className={styles.placeholderTop} />}
|
||||
<div className={classNames(styles.wrapper)}>
|
||||
<BrandingHeader
|
||||
className={styles.header}
|
||||
headline={style === BrandingStyle.Logo_Slogan ? slogan : undefined}
|
||||
logo={getLogto()}
|
||||
/>
|
||||
<PrimarySection
|
||||
signInMethod={experienceSettings.primarySignInMethod}
|
||||
socialConnectors={experienceSettings.socialConnectors}
|
||||
signInMode={experienceSettings.signInMode}
|
||||
/>
|
||||
)}
|
||||
|
||||
{experienceSettings.signInMode === SignInMode.SignInAndRegister && (
|
||||
<CreateAccountLink primarySignInMethod={experienceSettings.primarySignInMethod} />
|
||||
)}
|
||||
{experienceSettings.signInMode !== SignInMode.Register && (
|
||||
<SecondarySection
|
||||
primarySignInMethod={experienceSettings.primarySignInMethod}
|
||||
secondarySignInMethods={experienceSettings.secondarySignInMethods}
|
||||
socialConnectors={experienceSettings.socialConnectors}
|
||||
/>
|
||||
)}
|
||||
|
||||
<AppNotification />
|
||||
</div>
|
||||
{experienceSettings.signInMode === SignInMode.SignInAndRegister && (
|
||||
<CreateAccountLink primarySignInMethod={experienceSettings.primarySignInMethod} />
|
||||
)}
|
||||
|
||||
<AppNotification />
|
||||
</div>
|
||||
{platform === 'web' && <div className={styles.placeholderBottom} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue