mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
chore: remove dev feature guard for first screens (#6522)
* chore: remove dev feature guard for new first screens * chore: add changeset * chore(experience): add comments for identifier sign-in and register page
This commit is contained in:
parent
652898f978
commit
3d3a220306
6 changed files with 84 additions and 41 deletions
30
.changeset/nine-vans-whisper.md
Normal file
30
.changeset/nine-vans-whisper.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
"@logto/integration-tests": minor
|
||||
"@logto/experience": minor
|
||||
"@logto/core": minor
|
||||
---
|
||||
|
||||
add support for additional first screen options
|
||||
|
||||
This feature introduces new first screen options, allowing developers to customize the initial screen presented to users. In addition to the existing `sign_in` and `register` options, the following first screen choices are now supported:
|
||||
|
||||
- `identifier:sign_in`: Only display specific identifier-based sign-in methods to users.
|
||||
- `identifier:register`: Only display specific identifier-based registration methods to users.
|
||||
- `reset_password`: Allow users to directly access the password reset page.
|
||||
- `single_sign_on`: Allow users to directly access the single sign-on (SSO) page.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
// Example usage (React project using React SDK)
|
||||
void signIn({
|
||||
redirectUri,
|
||||
firstScreen: 'identifier:sign_in',
|
||||
/**
|
||||
* Optional. Specifies which sign-in methods to display on the identifier sign-in page.
|
||||
* If not specified, the default sign-in experience configuration will be used.
|
||||
* This option is effective when the `firstScreen` value is `identifier:sign_in`, `identifier:register`, or `reset_password`.
|
||||
*/
|
||||
identifiers: ['email', 'phone'],
|
||||
});
|
||||
```
|
|
@ -12,9 +12,7 @@ import {
|
|||
import { conditional } from '@silverhand/essentials';
|
||||
import { type AllClientMetadata, type ClientAuthMethod, errors } from 'oidc-provider';
|
||||
|
||||
import { EnvSet } from '#src/env-set/index.js';
|
||||
|
||||
const { isDevFeaturesEnabled } = EnvSet.values;
|
||||
import { type EnvSet } from '#src/env-set/index.js';
|
||||
|
||||
export const getConstantClientMetadata = (
|
||||
envSet: EnvSet,
|
||||
|
@ -91,19 +89,15 @@ export const getUtcStartOfTheDay = (date: Date) => {
|
|||
const firstScreenRouteMapping: Record<FirstScreen, keyof typeof experience.routes> = {
|
||||
[FirstScreen.SignIn]: 'signIn',
|
||||
[FirstScreen.Register]: 'register',
|
||||
/**
|
||||
* Todo @xiaoyijun remove isDevFeaturesEnabled check
|
||||
* Fallback to signIn when dev feature is not ready (these three screens are not supported yet)
|
||||
*/
|
||||
[FirstScreen.ResetPassword]: isDevFeaturesEnabled ? 'resetPassword' : 'signIn',
|
||||
[FirstScreen.IdentifierSignIn]: isDevFeaturesEnabled ? 'identifierSignIn' : 'signIn',
|
||||
[FirstScreen.IdentifierRegister]: isDevFeaturesEnabled ? 'identifierRegister' : 'signIn',
|
||||
[FirstScreen.SingleSignOn]: isDevFeaturesEnabled ? 'sso' : 'signIn',
|
||||
[FirstScreen.ResetPassword]: 'resetPassword',
|
||||
[FirstScreen.IdentifierSignIn]: 'identifierSignIn',
|
||||
[FirstScreen.IdentifierRegister]: 'identifierRegister',
|
||||
[FirstScreen.SingleSignOn]: 'sso',
|
||||
[FirstScreen.SignInDeprecated]: 'signIn',
|
||||
};
|
||||
|
||||
// Note: this eslint comment can be removed once the dev feature flag is removed
|
||||
// eslint-disable-next-line complexity
|
||||
|
||||
export const buildLoginPromptUrl = (params: ExtraParamsObject, appId?: unknown): string => {
|
||||
const firstScreenKey =
|
||||
params[ExtraParamsKey.FirstScreen] ??
|
||||
|
@ -131,11 +125,8 @@ export const buildLoginPromptUrl = (params: ExtraParamsObject, appId?: unknown):
|
|||
searchParams.append(ExtraParamsKey.LoginHint, params[ExtraParamsKey.LoginHint]);
|
||||
}
|
||||
|
||||
if (isDevFeaturesEnabled) {
|
||||
// eslint-disable-next-line unicorn/no-lonely-if
|
||||
if (params[ExtraParamsKey.Identifier]) {
|
||||
searchParams.append(ExtraParamsKey.Identifier, params[ExtraParamsKey.Identifier]);
|
||||
}
|
||||
if (params[ExtraParamsKey.Identifier]) {
|
||||
searchParams.append(ExtraParamsKey.Identifier, params[ExtraParamsKey.Identifier]);
|
||||
}
|
||||
|
||||
if (directSignIn) {
|
||||
|
|
|
@ -7,7 +7,6 @@ import LoadingLayerProvider from './Providers/LoadingLayerProvider';
|
|||
import PageContextProvider from './Providers/PageContextProvider';
|
||||
import SettingsProvider from './Providers/SettingsProvider';
|
||||
import UserInteractionContextProvider from './Providers/UserInteractionContextProvider';
|
||||
import { isDevFeaturesEnabled } from './constants/env';
|
||||
import Callback from './pages/Callback';
|
||||
import Consent from './pages/Consent';
|
||||
import Continue from './pages/Continue';
|
||||
|
@ -119,7 +118,7 @@ const App = () => {
|
|||
{/* Single sign-on */}
|
||||
<Route path={experience.routes.sso}>
|
||||
{/* Single sign-on first screen landing page */}
|
||||
{isDevFeaturesEnabled && <Route index element={<SingleSignOnLanding />} />}
|
||||
<Route index element={<SingleSignOnLanding />} />
|
||||
<Route path="email" element={<SingleSignOnEmail />} />
|
||||
<Route path="connectors" element={<SingleSignOnConnectors />} />
|
||||
</Route>
|
||||
|
@ -127,27 +126,32 @@ const App = () => {
|
|||
{/* Consent */}
|
||||
<Route path="consent" element={<Consent />} />
|
||||
|
||||
{isDevFeaturesEnabled && (
|
||||
<>
|
||||
{/* Identifier sign-in */}
|
||||
<Route
|
||||
path={experience.routes.identifierSignIn}
|
||||
element={<IdentifierSignIn />}
|
||||
/>
|
||||
{/*
|
||||
* Identifier sign-in (first screen)
|
||||
* The first screen which only display specific identifier-based sign-in methods to users
|
||||
*/}
|
||||
<Route
|
||||
path={experience.routes.identifierSignIn}
|
||||
element={<IdentifierSignIn />}
|
||||
/>
|
||||
|
||||
{/* Identifier register */}
|
||||
<Route
|
||||
path={experience.routes.identifierRegister}
|
||||
element={<IdentifierRegister />}
|
||||
/>
|
||||
{/*
|
||||
* Identifier register (first screen)
|
||||
* The first screen which only display specific identifier-based registration methods to users
|
||||
*/}
|
||||
<Route
|
||||
path={experience.routes.identifierRegister}
|
||||
element={<IdentifierRegister />}
|
||||
/>
|
||||
|
||||
{/* Reset password */}
|
||||
<Route
|
||||
path={experience.routes.resetPassword}
|
||||
element={<ResetPasswordLanding />}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{/*
|
||||
* Reset password (first screen)
|
||||
* The first screen which allow users to directly access the password reset page
|
||||
*/}
|
||||
<Route
|
||||
path={experience.routes.resetPassword}
|
||||
element={<ResetPasswordLanding />}
|
||||
/>
|
||||
|
||||
<Route path="*" element={<ErrorPage />} />
|
||||
</Route>
|
||||
|
|
|
@ -10,6 +10,15 @@ import { identifierInputDescriptionMap } from '@/utils/form';
|
|||
|
||||
import useIdentifierSignUpMethods from './use-identifier-sign-up-methods';
|
||||
|
||||
/**
|
||||
* Identifier register page
|
||||
*
|
||||
* This page is used to display specific identifier-based registration methods to users.
|
||||
*
|
||||
* This page can be used as the first screen of the authentication flow,
|
||||
* and can be configured by setting the `first_screen` parameter to `identifier:register`
|
||||
* in the authentication URL.
|
||||
*/
|
||||
const IdentifierRegister = () => {
|
||||
const { t } = useTranslation();
|
||||
const signUpMethods = useIdentifierSignUpMethods();
|
||||
|
|
|
@ -11,6 +11,18 @@ import { identifierInputDescriptionMap } from '@/utils/form';
|
|||
|
||||
import useIdentifierSignInMethods from './use-identifier-sign-in-methods';
|
||||
|
||||
/**
|
||||
* Identifier sign-in page
|
||||
*
|
||||
* This page is used to display specific identifier-based sign-in methods to users.
|
||||
*
|
||||
* This page can be used as the first screen of the authentication flow,
|
||||
* and can be configured by setting the `first_screen` parameter to `identifier:sign_in`
|
||||
* in the authentication URL.
|
||||
*
|
||||
* identifiers used in this page can be configured by setting the `identifier` parameter
|
||||
* in the authentication URL, multiple identifiers can be separated by space.
|
||||
*/
|
||||
const IdentifierSignIn = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
|
|
@ -10,9 +10,6 @@ import {
|
|||
setSmsConnector,
|
||||
} from '#src/helpers/connector.js';
|
||||
import ExpectExperience from '#src/ui-helpers/expect-experience.js';
|
||||
import { devFeatureTest } from '#src/utils.js';
|
||||
|
||||
const { describe, it } = devFeatureTest;
|
||||
|
||||
describe('first screen', () => {
|
||||
beforeAll(async () => {
|
||||
|
|
Loading…
Reference in a new issue