add: GitHub authentication
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@payloadcms/admin-bar": "latest",
|
||||
"@payloadcms/db-sqlite": "latest",
|
||||
"@payloadcms/live-preview-react": "latest",
|
||||
"@payloadcms/next": "latest",
|
||||
"@payloadcms/payload-cloud": "latest",
|
||||
@@ -34,6 +35,7 @@
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-select": "^2.0.0",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"auth": "^1.2.3",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
@@ -41,16 +43,17 @@
|
||||
"graphql": "^16.8.2",
|
||||
"lucide-react": "^0.378.0",
|
||||
"next": "15.2.3",
|
||||
"next-auth": "5.0.0-beta.25",
|
||||
"next-sitemap": "^4.2.3",
|
||||
"payload": "latest",
|
||||
"payload-authjs": "^0.7.1",
|
||||
"prism-react-renderer": "^2.3.1",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-hook-form": "7.45.4",
|
||||
"sharp": "0.32.6",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"@payloadcms/db-sqlite": "latest"
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
10222
pnpm-lock.yaml
generated
10222
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
9
src/_middleware.ts
Normal file
9
src/_middleware.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import NextAuth from "next-auth";
|
||||
import { authConfig } from "./auth.config";
|
||||
|
||||
const { auth: middleware } = NextAuth(authConfig);
|
||||
export default middleware;
|
||||
|
||||
export const config = {
|
||||
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
|
||||
};
|
||||
14
src/app/(frontend)/login/page.tsx
Normal file
14
src/app/(frontend)/login/page.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { signIn } from "@/auth";
|
||||
|
||||
export default function SignInButton() {
|
||||
return (
|
||||
<form
|
||||
action={async () => {
|
||||
"use server";
|
||||
await signIn("github");
|
||||
}}
|
||||
>
|
||||
<button type="submit">Sign In</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import { LinkToDoc as LinkToDoc_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloa
|
||||
import { ReindexButton as ReindexButton_aead06e4cbf6b2620c5c51c9ab283634 } from '@payloadcms/plugin-search/client'
|
||||
import { RowLabel as RowLabel_ec255a65fa6fa8d1faeb09cf35284224 } from '@/Header/RowLabel'
|
||||
import { RowLabel as RowLabel_1f6ff6ff633e3695d348f4f3c58f1466 } from '@/Footer/RowLabel'
|
||||
import { SignInWithAuthjsButton as SignInWithAuthjsButton_06d0cb594d8f6ba2ac35015f930c882e } from 'payload-authjs/components'
|
||||
import { default as default_1a7510af427896d367a49dbf838d2de6 } from '@/components/BeforeDashboard'
|
||||
import { default as default_8a7ab0eb7ab5c511aba12e68480bfe5e } from '@/components/BeforeLogin'
|
||||
|
||||
@@ -46,6 +47,7 @@ export const importMap = {
|
||||
"@payloadcms/plugin-search/client#ReindexButton": ReindexButton_aead06e4cbf6b2620c5c51c9ab283634,
|
||||
"@/Header/RowLabel#RowLabel": RowLabel_ec255a65fa6fa8d1faeb09cf35284224,
|
||||
"@/Footer/RowLabel#RowLabel": RowLabel_1f6ff6ff633e3695d348f4f3c58f1466,
|
||||
"payload-authjs/components#SignInWithAuthjsButton": SignInWithAuthjsButton_06d0cb594d8f6ba2ac35015f930c882e,
|
||||
"@/components/BeforeDashboard#default": default_1a7510af427896d367a49dbf838d2de6,
|
||||
"@/components/BeforeLogin#default": default_8a7ab0eb7ab5c511aba12e68480bfe5e
|
||||
}
|
||||
|
||||
2
src/app/(payload)/api/auth/[...nextauth]/route.ts
Normal file
2
src/app/(payload)/api/auth/[...nextauth]/route.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { handlers } from "@/auth" // Referring to the auth.ts we just created
|
||||
export const { GET, POST } = handlers
|
||||
9
src/auth.config.ts
Normal file
9
src/auth.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { NextAuthConfig } from "next-auth";
|
||||
import github from "next-auth/providers/github";
|
||||
|
||||
export const authConfig: NextAuthConfig = {
|
||||
providers: [github],
|
||||
callbacks: {
|
||||
authorized: ({ auth }) => !!auth,
|
||||
},
|
||||
};
|
||||
10
src/auth.ts
Normal file
10
src/auth.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import payloadConfig from "@payload-config";
|
||||
import NextAuth from "next-auth";
|
||||
import { withPayload } from "payload-authjs";
|
||||
import { authConfig } from "./auth.config";
|
||||
|
||||
export const { handlers, signIn, signOut, auth } = NextAuth(
|
||||
withPayload(authConfig, {
|
||||
payloadConfig,
|
||||
}),
|
||||
);
|
||||
@@ -1,26 +0,0 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { authenticated } from '../../access/authenticated'
|
||||
|
||||
export const Users: CollectionConfig = {
|
||||
slug: 'users',
|
||||
access: {
|
||||
admin: authenticated,
|
||||
create: authenticated,
|
||||
delete: authenticated,
|
||||
read: authenticated,
|
||||
update: authenticated,
|
||||
},
|
||||
admin: {
|
||||
defaultColumns: ['name', 'email'],
|
||||
useAsTitle: 'name',
|
||||
},
|
||||
auth: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'name',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
timestamps: true,
|
||||
}
|
||||
7
src/collections/users.ts
Normal file
7
src/collections/users.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
// users.ts
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
const Users: CollectionConfig = {
|
||||
slug: "users",
|
||||
fields: [],
|
||||
};
|
||||
@@ -167,7 +167,7 @@ export interface Paper {
|
||||
};
|
||||
authors: {
|
||||
profilePicture: number | Media;
|
||||
user: number | User;
|
||||
user: string | User;
|
||||
position: 'leader' | 'member';
|
||||
description: string;
|
||||
id?: string | null;
|
||||
@@ -286,18 +286,21 @@ export interface Media {
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: number;
|
||||
id: string;
|
||||
email: string;
|
||||
emailVerified?: string | null;
|
||||
name?: string | null;
|
||||
image?: string | null;
|
||||
accounts?:
|
||||
| {
|
||||
id?: string | null;
|
||||
provider: string;
|
||||
providerAccountId: string;
|
||||
type: string;
|
||||
}[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
resetPasswordToken?: string | null;
|
||||
resetPasswordExpiration?: string | null;
|
||||
salt?: string | null;
|
||||
hash?: string | null;
|
||||
loginAttempts?: number | null;
|
||||
lockUntil?: string | null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
@@ -399,7 +402,7 @@ export interface Post {
|
||||
description?: string | null;
|
||||
};
|
||||
publishedAt?: string | null;
|
||||
authors?: (number | User)[] | null;
|
||||
authors?: (string | User)[] | null;
|
||||
populatedAuthors?:
|
||||
| {
|
||||
id?: string | null;
|
||||
@@ -973,7 +976,7 @@ export interface PayloadLockedDocument {
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
value: string | User;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'redirects';
|
||||
@@ -998,7 +1001,7 @@ export interface PayloadLockedDocument {
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
value: string | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
@@ -1011,7 +1014,7 @@ export interface PayloadPreference {
|
||||
id: number;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
value: string | User;
|
||||
};
|
||||
key?: string | null;
|
||||
value?:
|
||||
@@ -1367,16 +1370,21 @@ export interface CategoriesSelect<T extends boolean = true> {
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
id?: T;
|
||||
email?: T;
|
||||
emailVerified?: T;
|
||||
name?: T;
|
||||
image?: T;
|
||||
accounts?:
|
||||
| T
|
||||
| {
|
||||
id?: T;
|
||||
provider?: T;
|
||||
providerAccountId?: T;
|
||||
type?: 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
|
||||
@@ -1754,7 +1762,7 @@ export interface TaskSchedulePublish {
|
||||
value: number | Post;
|
||||
} | null);
|
||||
global?: string | null;
|
||||
user?: (number | null) | User;
|
||||
user?: (string | null) | User;
|
||||
};
|
||||
output?: unknown;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import { Categories } from './collections/Categories'
|
||||
import { Media } from './collections/Media'
|
||||
import { Pages } from './collections/Pages'
|
||||
import { Posts } from './collections/Posts'
|
||||
import { Users } from './collections/Users'
|
||||
import { Footer } from './Footer/config'
|
||||
import { Header } from './Header/config'
|
||||
import { plugins } from './plugins'
|
||||
@@ -18,12 +17,15 @@ import { defaultLexical } from '@/fields/defaultLexical'
|
||||
import { getServerSideURL } from './utilities/getURL'
|
||||
import { Papers } from '@/collections/Papers'
|
||||
import { Technologies } from '@/collections/Technologies'
|
||||
import { authjsPlugin } from 'payload-authjs'
|
||||
import { authConfig } from '@/auth.config'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
export default buildConfig({
|
||||
admin: {
|
||||
user: "users",
|
||||
components: {
|
||||
// The `BeforeLogin` component renders a message that you see while logging into your admin panel.
|
||||
// Feel free to delete this at any time. Simply remove the line below and the import `BeforeLogin` statement on line 15.
|
||||
@@ -35,7 +37,7 @@ export default buildConfig({
|
||||
importMap: {
|
||||
baseDir: path.resolve(dirname),
|
||||
},
|
||||
user: Users.slug,
|
||||
|
||||
livePreview: {
|
||||
breakpoints: [
|
||||
{
|
||||
@@ -66,10 +68,13 @@ export default buildConfig({
|
||||
url: process.env.DATABASE_URI || '',
|
||||
},
|
||||
}),
|
||||
collections: [Papers, Technologies, Pages, Posts, Media, Categories, Users],
|
||||
collections: [Papers, Technologies, Pages, Posts, Media, Categories],
|
||||
cors: [getServerSideURL()].filter(Boolean),
|
||||
globals: [Header, Footer],
|
||||
plugins: [
|
||||
authjsPlugin({
|
||||
authjsConfig: authConfig,
|
||||
}),
|
||||
...plugins,
|
||||
// storage-adapter-placeholder
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user