chore(examples): updates auth example to latest (#10090)
The auth example was still on `v3.0.0-beta.24`, was missing its users collection config, and was not yet using the component paths pattern established here: #7246. This updates to latest and fixes these issues. This example can still use further improvements and housekeeping which will come in future PRs.
This commit is contained in:
@@ -3,6 +3,7 @@ import Link from 'next/link'
|
||||
import React from 'react'
|
||||
|
||||
import { Gutter } from '../Gutter'
|
||||
import { HeaderNav } from './Nav'
|
||||
import classes from './index.module.scss'
|
||||
|
||||
export const Header = () => {
|
||||
@@ -23,6 +24,7 @@ export const Header = () => {
|
||||
/>
|
||||
</picture>
|
||||
</Link>
|
||||
<HeaderNav />
|
||||
</Gutter>
|
||||
</header>
|
||||
)
|
||||
|
||||
@@ -5,18 +5,21 @@ import type { Metadata } from 'next'
|
||||
import config from '@payload-config'
|
||||
import { generatePageMetadata, NotFoundPage } from '@payloadcms/next/views'
|
||||
|
||||
import { importMap } from '../importMap.js'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const NotFound = ({ params, searchParams }: Args) => NotFoundPage({ config, params, searchParams })
|
||||
const NotFound = ({ params, searchParams }: Args) =>
|
||||
NotFoundPage({ config, importMap, params, searchParams })
|
||||
|
||||
export default NotFound
|
||||
|
||||
@@ -5,18 +5,20 @@ import type { Metadata } from 'next'
|
||||
import config from '@payload-config'
|
||||
import { generatePageMetadata, RootPage } from '@payloadcms/next/views'
|
||||
|
||||
type Args = {
|
||||
params: {
|
||||
segments: string[]
|
||||
}
|
||||
searchParams: {
|
||||
[key: string]: string | string[]
|
||||
}
|
||||
}
|
||||
import { importMap } from '../importMap.js'
|
||||
|
||||
type Args = {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}>
|
||||
}
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const Page = ({ params, searchParams }: Args) => RootPage({ config, params, searchParams })
|
||||
const Page = ({ params, searchParams }: Args) =>
|
||||
RootPage({ config, importMap, params, searchParams })
|
||||
|
||||
export default Page
|
||||
|
||||
5
examples/auth/src/app/(payload)/admin/importMap.js
Normal file
5
examples/auth/src/app/(payload)/admin/importMap.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { BeforeLogin as BeforeLogin_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin'
|
||||
|
||||
export const importMap = {
|
||||
'@/components/BeforeLogin#BeforeLogin': BeforeLogin_8a7ab0eb7ab5c511aba12e68480bfe5e,
|
||||
}
|
||||
@@ -1,16 +1,32 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import configPromise from '@payload-config'
|
||||
import type { ServerFunctionClient } from 'payload'
|
||||
|
||||
import '@payloadcms/next/css'
|
||||
import { RootLayout } from '@payloadcms/next/layouts'
|
||||
import config from '@payload-config'
|
||||
import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
|
||||
import React from 'react'
|
||||
|
||||
import { importMap } from './admin/importMap.js'
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => <RootLayout config={configPromise}>{children}</RootLayout>
|
||||
const serverFunction: ServerFunctionClient = async function (args) {
|
||||
'use server'
|
||||
return handleServerFunctions({
|
||||
...args,
|
||||
config,
|
||||
importMap,
|
||||
})
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => (
|
||||
<RootLayout config={config} importMap={importMap} serverFunction={serverFunction}>
|
||||
{children}
|
||||
</RootLayout>
|
||||
)
|
||||
|
||||
export default Layout
|
||||
|
||||
@@ -1,13 +1,62 @@
|
||||
import type { CollectionConfig } from 'payload/types'
|
||||
|
||||
import { admins } from './access/admins'
|
||||
import adminsAndUser from './access/adminsAndUser'
|
||||
import { anyone } from './access/anyone'
|
||||
import { checkRole } from './access/checkRole'
|
||||
import { loginAfterCreate } from './hooks/loginAfterCreate'
|
||||
import { protectRoles } from './hooks/protectRoles'
|
||||
|
||||
export const Users: CollectionConfig = {
|
||||
slug: 'users',
|
||||
auth: {
|
||||
tokenExpiration: 28800, // 8 hours
|
||||
cookies: {
|
||||
sameSite: 'none',
|
||||
secure: true,
|
||||
domain: process.env.COOKIE_DOMAIN,
|
||||
},
|
||||
},
|
||||
admin: {
|
||||
useAsTitle: 'email',
|
||||
},
|
||||
auth: true,
|
||||
access: {
|
||||
read: adminsAndUser,
|
||||
create: anyone,
|
||||
update: adminsAndUser,
|
||||
delete: admins,
|
||||
admin: ({ req: { user } }) => checkRole(['admin'], user),
|
||||
},
|
||||
hooks: {
|
||||
afterChange: [loginAfterCreate],
|
||||
},
|
||||
fields: [
|
||||
// Email added by default
|
||||
// Add more fields as needed
|
||||
{
|
||||
name: 'firstName',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'lastName',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'roles',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
saveToJWT: true,
|
||||
hooks: {
|
||||
beforeChange: [protectRoles],
|
||||
},
|
||||
options: [
|
||||
{
|
||||
label: 'Admin',
|
||||
value: 'admin',
|
||||
},
|
||||
{
|
||||
label: 'User',
|
||||
value: 'user',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
|
||||
const BeforeLogin: React.FC = () => {
|
||||
export const BeforeLogin: React.FC = () => {
|
||||
if (process.env.PAYLOAD_PUBLIC_SEED === 'true') {
|
||||
return (
|
||||
<p>
|
||||
@@ -13,5 +13,3 @@ const BeforeLogin: React.FC = () => {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export default BeforeLogin
|
||||
|
||||
@@ -7,16 +7,53 @@
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
auth: {
|
||||
users: UserAuthOperations;
|
||||
};
|
||||
collections: {
|
||||
users: User;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: string;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: null;
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
jobs: {
|
||||
tasks: unknown;
|
||||
workflows: unknown;
|
||||
};
|
||||
}
|
||||
export interface UserAuthOperations {
|
||||
forgotPassword: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
login: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
registerFirstUser: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
unlock: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
@@ -38,6 +75,24 @@ export interface User {
|
||||
lockUntil?: string | null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: string;
|
||||
document?: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
} | null;
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: string | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
@@ -72,6 +127,63 @@ export interface PayloadMigration {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
firstName?: T;
|
||||
lastName?: T;
|
||||
roles?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
resetPasswordToken?: T;
|
||||
resetPasswordExpiration?: T;
|
||||
salt?: T;
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
*/
|
||||
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||
document?: T;
|
||||
globalSlug?: T;
|
||||
user?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences_select".
|
||||
*/
|
||||
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
key?: T;
|
||||
value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations_select".
|
||||
*/
|
||||
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
batch?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
*/
|
||||
export interface Auth {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
|
||||
declare module 'payload' {
|
||||
|
||||
@@ -2,28 +2,21 @@ import { mongooseAdapter } from '@payloadcms/db-mongodb'
|
||||
import { slateEditor } from '@payloadcms/richtext-slate'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'path'
|
||||
import { buildConfig } from 'payload/config'
|
||||
import { buildConfig } from 'payload'
|
||||
|
||||
import { Users } from './collections/Users'
|
||||
import BeforeLogin from './components/BeforeLogin'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
export default buildConfig({
|
||||
admin: {
|
||||
components: {
|
||||
beforeLogin: [BeforeLogin],
|
||||
beforeLogin: ['@/components/BeforeLogin#BeforeLogin'],
|
||||
},
|
||||
},
|
||||
collections: [Users],
|
||||
cors: [
|
||||
process.env.PAYLOAD_PUBLIC_SERVER_URL || '',
|
||||
process.env.PAYLOAD_PUBLIC_SITE_URL || '',
|
||||
].filter(Boolean),
|
||||
csrf: [
|
||||
process.env.PAYLOAD_PUBLIC_SERVER_URL || '',
|
||||
process.env.PAYLOAD_PUBLIC_SITE_URL || '',
|
||||
].filter(Boolean),
|
||||
cors: [process.env.NEXT_PUBLIC_SERVER_URL || ''].filter(Boolean),
|
||||
csrf: [process.env.NEXT_PUBLIC_SERVER_URL || ''].filter(Boolean),
|
||||
db: mongooseAdapter({
|
||||
url: process.env.DATABASE_URI || '',
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user