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:
Jacob Fletcher
2024-12-19 23:54:24 -05:00
committed by GitHub
parent dd3c2eb42b
commit 7292220109
20 changed files with 4796 additions and 6465 deletions

View File

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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,5 @@
import { BeforeLogin as BeforeLogin_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin'
export const importMap = {
'@/components/BeforeLogin#BeforeLogin': BeforeLogin_8a7ab0eb7ab5c511aba12e68480bfe5e,
}

View File

@@ -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

View File

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

View File

@@ -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

View File

@@ -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' {

View File

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