Skip to content

Commit

Permalink
chore(next-example): add webauthn support w/ unstorage adapter (#9963)
Browse files Browse the repository at this point in the history
Co-authored-by: Balázs Orbán <info@balazsorban.com>
  • Loading branch information
ndom91 and balazsorban44 committed May 11, 2024
1 parent a4d62c7 commit 90c5738
Show file tree
Hide file tree
Showing 9 changed files with 1,683 additions and 1,323 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Expand Up @@ -95,11 +95,11 @@ jobs:
if: ${{ github.repository == 'nextauthjs/next-auth' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
- name: Build
run: pnpm build
- name: Run unit tests
run: pnpm test
- name: Lint
run: pnpm lint
timeout-minutes: 15
- name: Run unit tests
run: pnpm test
- name: Get installed Playwright version
id: playwright-version
run: echo "PLAYWRIGHT_VERSION=$(pnpx playwright -V | awk '{ print $2 }')" >> $GITHUB_ENV
Expand Down
4 changes: 2 additions & 2 deletions apps/examples/nextjs/app/api-example/page.tsx
Expand Up @@ -25,8 +25,8 @@ export default function Page() {
</CustomLink>{" "}
method.
</p>
<div className="flex flex-col rounded-md bg-neutral-100">
<div className="p-4 font-bold rounded-t-md bg-neutral-200">
<div className="flex flex-col bg-gray-100 rounded-md">
<div className="p-4 font-bold bg-gray-200 rounded-t-md">
Data from API Route
</div>
<pre className="py-6 px-4 whitespace-pre-wrap break-all">
Expand Down
9 changes: 7 additions & 2 deletions apps/examples/nextjs/app/page.tsx
Expand Up @@ -20,8 +20,13 @@ export default async function Index() {
</CustomLink>{" "}
examples to see how to secure pages and get session data.
</div>
<div className="flex flex-col rounded-md bg-neutral-100">
<div className="p-4 font-bold rounded-t-md bg-neutral-200">
<div>
WebAuthn users are reset on every deploy, don't expect your test user(s)
to still be available after a few days. It is designed to only
demonstrate registration, login, and logout briefly.
</div>
<div className="flex flex-col bg-gray-100 rounded-md">
<div className="p-4 font-bold bg-gray-200 rounded-t-md">
Current Session
</div>
<pre className="py-6 px-4 whitespace-pre-wrap break-all">
Expand Down
18 changes: 15 additions & 3 deletions apps/examples/nextjs/auth.ts
Expand Up @@ -19,6 +19,7 @@ import LinkedIn from "next-auth/providers/linkedin"
import Netlify from "next-auth/providers/netlify"
import Okta from "next-auth/providers/okta"
import Passage from "next-auth/providers/passage"
import Passkey from "next-auth/providers/passkey"
import Pinterest from "next-auth/providers/pinterest"
import Reddit from "next-auth/providers/reddit"
import Slack from "next-auth/providers/slack"
Expand All @@ -27,11 +28,15 @@ import Twitch from "next-auth/providers/twitch"
import Twitter from "next-auth/providers/twitter"
import WorkOS from "next-auth/providers/workos"
import Zoom from "next-auth/providers/zoom"

import { createStorage } from "unstorage"
import { UnstorageAdapter } from "@auth/unstorage-adapter"
import type { NextAuthConfig } from "next-auth"

export const config = {
const storage = createStorage()

const config = {
theme: { logo: "https://authjs.dev/img/logo-sm.png" },
adapter: UnstorageAdapter(storage),
providers: [
Apple,
Auth0,
Expand All @@ -58,6 +63,7 @@ export const config = {
LinkedIn,
Netlify,
Okta,
Passkey,
Passage,
Pinterest,
Reddit,
Expand Down Expand Up @@ -85,10 +91,16 @@ export const config = {
return token
},
async session({ session, token }) {
session.accessToken = token.accessToken
if (token?.accessToken) {
session.accessToken = token.accessToken
}
return session
},
},
experimental: {
enableWebAuthn: true,
},
debug: process.env.NODE_ENV !== "production" ? true : false,
} satisfies NextAuthConfig

export const { handlers, auth, signIn, signOut } = NextAuth(config)
Expand Down
43 changes: 16 additions & 27 deletions apps/examples/nextjs/components/client-example.tsx
Expand Up @@ -14,19 +14,8 @@ const UpdateForm = () => {
if (!session?.user) return null
return (
<>
<h2 className="text-xl font-bold">Updating the session</h2>
<form
onSubmit={async () => {
if (session) {
const newSession = await update({
...session,
user: { ...session.user, name },
})
console.log({ newSession })
}
}}
className="flex items-center space-x-2 w-full max-w-sm"
>
<h2 className="text-xl font-bold">Updating the session client-side</h2>
<div className="flex items-center space-x-2 w-full max-w-sm">
<Input
type="text"
placeholder="New name"
Expand All @@ -35,8 +24,10 @@ const UpdateForm = () => {
setName(e.target.value)
}}
/>
<Button type="submit">Update</Button>
</form>
<Button onClick={() => update({ user: { name } })} type="submit">
Update
</Button>
</div>
</>
)
}
Expand Down Expand Up @@ -82,32 +73,30 @@ export default function ClientExample() {
to provide the session data.
</p>

<div>
<div className="flex flex-col gap-4 p-4 bg-gray-100 rounded-md">
<h2 className="text-xl font-bold">Third-party backend integration</h2>
<p>
Press the button below to send a request to our{" "}
Press the button to send a request to our{" "}
<CustomLink href="https://github.com/nextauthjs/authjs-third-party-backend">
<code>example backend</code>
</CustomLink>
.
. Read more{" "}
<CustomLink href="https://authjs.dev/guides/integrating-third-party-backends">
<code>here</code>
</CustomLink>
</p>
<div className="flex flex-col ">
<p>Note: This example only works when using the Keycloak provider.</p>
<div className="flex flex-col">
<Button
disabled={!session?.accessToken}
className="mt-4 mb-4"
onClick={makeRequestWithToken}
>
Make API Request
</Button>
</div>
<p>
Read more{" "}
<CustomLink href="https://authjs.dev/guides/integrating-third-party-backends">
<code>here</code>
</CustomLink>
</p>
<pre>{apiResponse}</pre>
<p className="italic">
Note: This example only works when using the Keycloak provider.
</p>
</div>

{status === "loading" ? (
Expand Down
4 changes: 2 additions & 2 deletions apps/examples/nextjs/components/session-data.tsx
Expand Up @@ -3,7 +3,7 @@ import type { Session } from "next-auth"
export default function SessionData({ session }: { session: Session | null }) {
if (session?.user) {
return (
<div className="flex flex-col gap-4 w-full">
<div className="flex flex-col gap-4 p-4 w-full bg-gray-100 rounded-md">
<h2 className="text-xl font-bold">Current Session Data</h2>
{Object.keys(session.user).length > 3 ? (
<p>
Expand Down Expand Up @@ -31,7 +31,7 @@ export default function SessionData({ session }: { session: Session | null }) {
}

return (
<p>
<p className="p-4 w-full bg-gray-100 rounded-md">
No session data, please <em>Sign In</em> first.
</p>
)
Expand Down
17 changes: 7 additions & 10 deletions apps/examples/nextjs/components/user-button.tsx
Expand Up @@ -22,16 +22,13 @@ export default async function UserButton() {
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative w-8 h-8 rounded-full">
<Avatar className="w-8 h-8">
{session.user.image && (
<AvatarImage
src={
session.user.image ??
"https://source.boringavatars.com/beam/120"
}
alt={session.user.name ?? ""}
/>
)}
<AvatarFallback>{session.user.email}</AvatarFallback>
<AvatarImage
src={
session.user.image ??
"https://source.boringavatars.com/marble/120"
}
alt={session.user.name ?? ""}
/>
</Avatar>
</Button>
</DropdownMenuTrigger>
Expand Down
10 changes: 8 additions & 2 deletions apps/examples/nextjs/package.json
Expand Up @@ -19,11 +19,13 @@
"Thang Huu Vu <hi@thvu.dev>"
],
"dependencies": {
"@auth/unstorage-adapter": "^2.0.0",
"@radix-ui/react-avatar": "^1.0.3",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-navigation-menu": "^1.1.3",
"@radix-ui/react-slot": "^1.0.2",
"@simplewebauthn/server": "^9.0.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"lucide-react": "^0.274.0",
Expand All @@ -32,15 +34,19 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.7"
"tailwindcss-animate": "^1.0.7",
"unstorage": "^1.10.1"
},
"devDependencies": {
"@types/node": "^18",
"@types/node": "^20.12.8",
"@types/react": "^18.2.23",
"@types/react-dom": "^18.2.8",
"autoprefixer": "^10.4.15",
"postcss": "^8.4.29",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2"
},
"engines": {
"node": ">=20.0.0"
}
}

0 comments on commit 90c5738

Please sign in to comment.