Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"@payloadcms/next": "3.54.0",
"@payloadcms/translations": "3.54.0",
"@payloadcms/ui": "3.54.0",
"@simplewebauthn/browser": "^9.0.1",
"@simplewebauthn/server": "^9.0.3",
"@tailwindcss/postcss": "^4.1.12",
"clsx": "^2.1.1",
"graphql": "^16.11.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getPayloadSession } from "payload-authjs";
import { AuthjsRegisterPasskeyButtonClient } from "./authjs/AuthjsRegisterPasskeyButtonClient";
import { AuthjsSignInButtonClient } from "./authjs/AuthjsSignInButtonClient";
import { AuthjsSignInButtonServerAction } from "./authjs/AuthjsSignInButtonServerAction";
import { AuthjsSignInPasskeyButtonClient } from "./authjs/AuthjsSignInPasskeyButtonClient";
import { AuthjsSignOutButtonClient } from "./authjs/AuthjsSignOutButtonClient";
import { AuthjsSignOutButtonServerAction } from "./authjs/AuthjsSignOutButtonServerAction";
import { PayloadSignInButtonClient } from "./payload/PayloadSignInButtonClient";
Expand All @@ -18,11 +20,13 @@ export const SignInOrOutButtons = async () => {
<PayloadSignOutButtonClient />
<AuthjsSignOutButtonServerAction />
<AuthjsSignOutButtonClient />
<AuthjsRegisterPasskeyButtonClient />
</>
) : (
<>
<AuthjsSignInButtonServerAction />
<AuthjsSignInButtonClient />
<AuthjsSignInPasskeyButtonClient />
<PayloadSignInButtonClient />
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use client";

import { Button } from "@/components/general/Button";
import { AuthjsLogo } from "@/components/img/AuthjsLogo";
import { signIn } from "next-auth/webauthn";

/**
* Register a new passkey using Auth.js on the client
*
* @see https://authjs.dev/getting-started/authentication/webauthn
*/
export function AuthjsRegisterPasskeyButtonClient() {
return (
<Button onClick={() => signIn("passkey", { action: "register" })}>
<AuthjsLogo />
Register a Passkey (client)
</Button>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use client";

import { Button } from "@/components/general/Button";
import { AuthjsLogo } from "@/components/img/AuthjsLogo";
import { signIn } from "next-auth/webauthn";

/**
* Sign in with a passkey using Auth.js on the client
*
* @see https://authjs.dev/getting-started/authentication/webauthn
*/
export function AuthjsSignInPasskeyButtonClient() {
return (
<Button onClick={() => signIn("passkey")}>
<AuthjsLogo />
Sign In with Passkey (client)
</Button>
);
}
2 changes: 2 additions & 0 deletions packages/dev/src/app/(payload)/admin/importMap.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { AccountRowLabel as AccountRowLabel_06d0cb594d8f6ba2ac35015f930c882e } from 'payload-authjs/components'
import { AddAuthenticatorButton as AddAuthenticatorButton_06d0cb594d8f6ba2ac35015f930c882e } from 'payload-authjs/components'
import { SignInButton as SignInButton_06d0cb594d8f6ba2ac35015f930c882e } from 'payload-authjs/components'
import { default as default_2c1e1c35da30a80d88551f9fcc61be66 } from '../../../payload/components/Greeting'

export const importMap = {
"payload-authjs/components#AccountRowLabel": AccountRowLabel_06d0cb594d8f6ba2ac35015f930c882e,
"payload-authjs/components#AddAuthenticatorButton": AddAuthenticatorButton_06d0cb594d8f6ba2ac35015f930c882e,
"payload-authjs/components#SignInButton": SignInButton_06d0cb594d8f6ba2ac35015f930c882e,
"/Greeting#default": default_2c1e1c35da30a80d88551f9fcc61be66
}
3 changes: 3 additions & 0 deletions packages/dev/src/auth/base.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,4 +189,7 @@ export const authConfig: NextAuthConfig = {
return true;
},
},
experimental: {
enableWebAuthn: true,
},
};
9 changes: 8 additions & 1 deletion packages/dev/src/auth/node.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ import { discordProvider } from "./providers/discord";
import { githubProvider } from "./providers/github";
import { keycloakProvider } from "./providers/keycloak";
import { nodemailerProvider } from "./providers/nodemailer";
import { passkeysProvider } from "./providers/passkeys";

export const nodeAuthConfig: NextAuthConfig = {
...authConfig,
providers: [githubProvider, keycloakProvider, discordProvider, nodemailerProvider],
providers: [
githubProvider,
keycloakProvider,
discordProvider,
nodemailerProvider,
passkeysProvider,
],
};
3 changes: 3 additions & 0 deletions packages/dev/src/auth/providers/passkeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import passkey from "next-auth/providers/passkey";

export const passkeysProvider = passkey({});
22 changes: 22 additions & 0 deletions packages/dev/src/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ export interface User {
id?: string | null;
}[]
| null;
authenticators?:
| {
credentialID: string;
credentialPublicKey: string;
credentialBackedUp: boolean;
counter: number;
transports?: string | null;
credentialDeviceType: string;
id?: string | null;
}[]
| null;
updatedAt: string;
createdAt: string;
enableAPIKey?: boolean | null;
Expand Down Expand Up @@ -288,6 +299,17 @@ export interface UsersSelect<T extends boolean = true> {
createdAt?: T;
id?: T;
};
authenticators?:
| T
| {
credentialID?: T;
credentialPublicKey?: T;
credentialBackedUp?: T;
counter?: T;
transports?: T;
credentialDeviceType?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
enableAPIKey?: T;
Expand Down
1 change: 1 addition & 0 deletions packages/dev/src/payload/collections/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const Users: CollectionConfig<"users"> = {
name: "additionalAccountDatabaseField",
type: "text",
required: true,
defaultValue: () => `Default value at ${new Date().toISOString()}`,
},
createdAtField,
],
Expand Down
Loading