0
Fork 0
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:
simeng-li 2022-07-03 15:50:29 +08:00 committed by GitHub
parent f4e0a4c7d7
commit 8c4fea093d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 86 additions and 65 deletions

View file

@ -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,
})

View file

@ -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();
},

View file

@ -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. Lets first create an account. With this account, you can manage Logto by yourself or on behalf of your company.',
create_account: 'Create Account',

View file

@ -479,7 +479,7 @@ const translation = {
button: '重新登录',
},
welcome: {
title: '欢迎使用管理控制台',
title: '欢迎来到管理控制台',
description:
'管理控制台是一个无需代码操作的应用。你可以用它来管理登录体验。让我们首先创建一个帐号。你可以用它以个人或公司的身份管理 Logto。',
create_account: '创建帐号',

View file

@ -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: '',
},
};

View file

@ -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);
}

View file

@ -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} />}
</>
);
};