feat: option to pre-fill login credentials automatically (#3021)

Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
Alessio Gravili
2023-08-04 19:41:08 +02:00
committed by GitHub
parent 356f174b9f
commit c5756ed4a1
7 changed files with 61 additions and 9 deletions

View File

@@ -25,7 +25,7 @@ _Screenshot of the Admin panel while editing a document from an example `AllFiel
All options for the Admin panel are defined in your base Payload config file. All options for the Admin panel are defined in your base Payload config file.
| Option | Description | | Option | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) | | `user` | The `slug` of a Collection that you want be used to log in to the Admin dashboard. [More](/docs/admin/overview#the-admin-user-collection) |
| `buildPath` | Specify an absolute path for where to store the built Admin panel bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. | | `buildPath` | Specify an absolute path for where to store the built Admin panel bundle used in production. Defaults to `path.resolve(process.cwd(), 'build')`. |
| `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. | | `meta` | Base meta data to use for the Admin panel. Included properties are `titleSuffix`, `ogImage`, and `favicon`. |
@@ -35,6 +35,7 @@ All options for the Admin panel are defined in your base Payload config file.
| `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). | | `scss` | Absolute path to a Sass variables / mixins stylesheet meant to override Payload styles to make for an easy re-skinning of the Admin panel. [More](/docs/admin/customizing-css#overriding-scss-variables). |
| `dateFormat` | Global date format that will be used for all dates in the Admin panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. | | `dateFormat` | Global date format that will be used for all dates in the Admin panel. Any valid [date-fns](https://date-fns.org/) format pattern can be used. |
| `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. | | `avatar` | Set account profile picture. Options: `gravatar`, `default` or a custom React component. |
| `autoLogin` | Used to automate admin log-in for dev and demonstration convenience. [More](/docs/authentication/config). |
| `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) | | `components` | Component overrides that affect the entirety of the Admin panel. [More](/docs/admin/components) |
| `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) | | `webpack` | Customize the Webpack config that's used to generate the Admin panel. [More](/docs/admin/webpack) |
| **`logoutRoute`** | The route for the `logout` page. | | **`logoutRoute`** | The route for the `logout` page. |

View File

@@ -249,3 +249,39 @@ If you pass a strategy to the `strategy` property directly, the `name` property
However, if you pass a function to `strategy`, `name` is a required property. However, if you pass a function to `strategy`, `name` is a required property.
In either case, Payload will prefix the strategy name with the collection `slug` that the strategy is passed to. In either case, Payload will prefix the strategy name with the collection `slug` that the strategy is passed to.
### Admin autologin
For testing and demo purposes you may want to skip forcing the admin user to login in order to access the panel.
The `admin.autologin` property is used to configure the how visitors are handled when accessing the admin panel.
The default is that all users will have to login and this should not be enabled for environments where data needs to protected.
#### autoLogin Options
| Option | Description |
| -------------------------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **`email`** | The email address of the user to login as |
| **`password`** | The password of the user to login as |
| **`prefillOnly`** | If set to true, the login credentials will be prefilled but the user will still need to click the login button. |
The recommended way to use this feature is behind an environment variable to ensure it is disabled when in production.
**Example:**
```ts
export default buildConfig({
admin: {
user: 'users',
// highlight-start
autoLogin: process.env.PAYLOAD_PUBLIC_ENABLE_AUTOLOGIN === 'true' ? {
email: 'test@example.com',
password: 'test',
prefillOnly: true,
} : false,
// highlight-end
},
collections: [ /** */],
})
```

View File

@@ -144,7 +144,7 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
setUser(json.user); setUser(json.user);
} else if (json?.token) { } else if (json?.token) {
setToken(json.token); setToken(json.token);
} else if (autoLogin) { } else if (autoLogin && autoLogin.prefillOnly !== true) {
// auto log-in with the provided autoLogin credentials. This is used in dev mode // auto log-in with the provided autoLogin credentials. This is used in dev mode
// so you don't have to log in over and over again // so you don't have to log in over and over again
const autoLoginResult = await requests.post(`${serverURL}${api}/${userSlug}/login`, { const autoLoginResult = await requests.post(`${serverURL}${api}/${userSlug}/login`, {

View File

@@ -26,6 +26,7 @@ const Login: React.FC = () => {
admin: { admin: {
user: userSlug, user: userSlug,
logoutRoute, logoutRoute,
autoLogin,
components: { components: {
beforeLogin, beforeLogin,
afterLogin, afterLogin,
@@ -103,6 +104,10 @@ const Login: React.FC = () => {
onSuccess={onSuccess} onSuccess={onSuccess}
method="post" method="post"
action={`${serverURL}${api}/${userSlug}/login`} action={`${serverURL}${api}/${userSlug}/login`}
initialData={{
email: autoLogin && autoLogin.prefillOnly ? autoLogin.email : undefined,
password: autoLogin && autoLogin.prefillOnly ? autoLogin.password : undefined,
}}
> >
<FormLoadingOverlayToggle <FormLoadingOverlayToggle
action="loading" action="loading"

View File

@@ -71,6 +71,7 @@ export default joi.object({
joi.object().keys({ joi.object().keys({
email: joi.string(), email: joi.string(),
password: joi.string(), password: joi.string(),
prefillOnly: joi.boolean(),
}), }),
joi.boolean(), joi.boolean(),
), ),

View File

@@ -10,11 +10,7 @@ import React from 'react';
import { DestinationStream, LoggerOptions } from 'pino'; import { DestinationStream, LoggerOptions } from 'pino';
import type { InitOptions as i18nInitOptions } from 'i18next'; import type { InitOptions as i18nInitOptions } from 'i18next';
import { Payload } from '../payload'; import { Payload } from '../payload';
import { import { AfterErrorHook, CollectionConfig, SanitizedCollectionConfig } from '../collections/config/types';
AfterErrorHook,
CollectionConfig,
SanitizedCollectionConfig,
} from '../collections/config/types';
import { GlobalConfig, SanitizedGlobalConfig } from '../globals/config/types'; import { GlobalConfig, SanitizedGlobalConfig } from '../globals/config/types';
import { PayloadRequest } from '../express/types'; import { PayloadRequest } from '../express/types';
import { Where } from '../types'; import { Where } from '../types';
@@ -289,10 +285,19 @@ export type Config = {
inactivityRoute?: string; inactivityRoute?: string;
/** Automatically log in as a user when visiting the admin dashboard. */ /** Automatically log in as a user when visiting the admin dashboard. */
autoLogin?: false | { autoLogin?: false | {
/** The email address of the user to login as */ /**
* The email address of the user to login as
*
*/
email: string; email: string;
/** The password of the user to login as */ /** The password of the user to login as */
password: string; password: string;
/**
* If set to true, the login credentials will be prefilled but the user will still need to click the login button.
*
* @default false
*/
prefillOnly?: boolean;
} }
/** /**
* Add extra and/or replace built-in components with custom components * Add extra and/or replace built-in components with custom components

View File

@@ -13,7 +13,11 @@ export const saveToJWTKey = 'x-custom-jwt-property-name';
export default buildConfigWithDefaults({ export default buildConfigWithDefaults({
admin: { admin: {
user: 'users', user: 'users',
autoLogin: false, autoLogin: {
email: 'test@example.com',
password: 'test',
prefillOnly: true,
},
}, },
collections: [ collections: [
{ {