fix: passkey headers

This commit is contained in:
Bereket Engida
2024-09-16 10:55:39 +03:00
parent df5ec2a2d6
commit 68f5328a91
6 changed files with 60 additions and 23 deletions

View File

@@ -1,13 +1,10 @@
import { Navbar } from "@/components/nav-bar"; import { Navbar } from "@/components/nav-bar";
import "./global.css"; import "./global.css";
import { RootProvider } from "fumadocs-ui/provider"; import { RootProvider } from "fumadocs-ui/provider";
import { Inter } from "next/font/google";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import { NavbarProvider } from "@/components/nav-mobile"; import { NavbarProvider } from "@/components/nav-mobile";
import { GeistMono } from "geist/font/mono"; import { GeistMono } from "geist/font/mono";
import { GeistSans } from "geist/font/sans"; import { GeistSans } from "geist/font/sans";
import { ENV } from "@/lib/constants";
import { Metadata } from "next";
import { baseUrl, createMetadata } from "@/lib/metadata"; import { baseUrl, createMetadata } from "@/lib/metadata";
export const metadata = createMetadata({ export const metadata = createMetadata({

View File

@@ -10,7 +10,6 @@ export default function HomePage() {
crossesOffset="lg:translate-y-[5.25rem]" crossesOffset="lg:translate-y-[5.25rem]"
customPaddings customPaddings
id="hero" id="hero"
> >
<Hero /> <Hero />
<Features /> <Features />

View File

@@ -1,4 +1,4 @@
import type { BetterFetch } from "@better-fetch/fetch"; import type { BetterFetch, BetterFetchOption } from "@better-fetch/fetch";
import { import {
WebAuthnError, WebAuthnError,
startAuthentication, startAuthentication,
@@ -53,11 +53,14 @@ export const getPasskeyActions = ($fetch: BetterFetch) => {
} }
}; };
const registerPasskey = async () => { const registerPasskey = async (opts?: {
options?: BetterFetchOption;
}) => {
const options = await $fetch<PublicKeyCredentialCreationOptionsJSON>( const options = await $fetch<PublicKeyCredentialCreationOptionsJSON>(
"/passkey/generate-register-options", "/passkey/generate-register-options",
{ {
method: "GET", method: "GET",
...opts?.options,
}, },
); );
if (!options.data) { if (!options.data) {
@@ -72,6 +75,7 @@ export const getPasskeyActions = ($fetch: BetterFetch) => {
response: res, response: res,
type: "register", type: "register",
}, },
...opts?.options,
}); });
if (!verified.data) { if (!verified.data) {
return verified; return verified;

View File

@@ -53,7 +53,7 @@ export interface PasskeyOptions {
export type WebAuthnCookieType = { export type WebAuthnCookieType = {
expectedChallenge: string; expectedChallenge: string;
userData: { id: string; email: string }; userData: { id: string };
callbackURL?: string; callbackURL?: string;
}; };
@@ -71,10 +71,7 @@ export type Passkey = {
export const passkey = (options?: PasskeyOptions) => { export const passkey = (options?: PasskeyOptions) => {
const baseURL = process.env.BETTER_AUTH_URL; const baseURL = process.env.BETTER_AUTH_URL;
const rpID = const rpID = options?.rpID || baseURL || "localhost";
process.env.NODE_ENV === "development"
? "localhost"
: options?.rpID || baseURL;
if (!rpID) { if (!rpID) {
throw new BetterAuthError( throw new BetterAuthError(
"passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.", "passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.",
@@ -141,8 +138,7 @@ export const passkey = (options?: PasskeyOptions) => {
const data: WebAuthnCookieType = { const data: WebAuthnCookieType = {
expectedChallenge: options.challenge, expectedChallenge: options.challenge,
userData: { userData: {
...session.user, id: session.user.id,
email: session.user.email || session.user.id,
}, },
}; };
@@ -207,7 +203,6 @@ export const passkey = (options?: PasskeyOptions) => {
const data: WebAuthnCookieType = { const data: WebAuthnCookieType = {
expectedChallenge: options.challenge, expectedChallenge: options.challenge,
userData: { userData: {
email: session?.user.email || session?.user.id || "",
id: session?.user.id || "", id: session?.user.id || "",
}, },
callbackURL: ctx.body?.callbackURL, callbackURL: ctx.body?.callbackURL,

View File

@@ -0,0 +1,42 @@
import { describe, expect, it } from "vitest";
import { getTestInstance } from "../../test-utils/test-instance";
import { passkey, passkeyClient } from ".";
import { createAuthClient } from "../../client";
//TODO: add tests for register and authenticate
describe("passkey", async () => {
const { auth, signInWithTestUser, customFetchImpl } = await getTestInstance({
plugins: [passkey()],
});
it("should generate register options", async () => {
const { res, headers } = await signInWithTestUser();
const options = await auth.api.generatePasskeyRegistrationOptions({
headers: headers,
});
expect(options).toBeDefined();
const client = createAuthClient({
plugins: [passkeyClient()],
baseURL: "http://localhost:3000/api/auth",
fetchOptions: {
headers: headers,
customFetchImpl,
},
});
await client.$fetch("/passkey/generate-register-options", {
headers: headers,
method: "GET",
onResponse(context) {
const setCookie = context.response.headers.get("Set-Cookie");
expect(setCookie).toBeDefined();
},
});
});
it("should generate authenticate options", async () => {
const { headers } = await signInWithTestUser();
const options = await auth.api.generatePasskeyAuthenticationOptions({
headers: headers,
});
expect(options).toBeDefined();
});
});

18
pnpm-lock.yaml generated
View File

@@ -796,6 +796,15 @@ importers:
better-sqlite3: better-sqlite3:
specifier: ^11.1.2 specifier: ^11.1.2
version: 11.1.2 version: 11.1.2
c12:
specifier: ^1.11.2
version: 1.11.2(magicast@0.3.5)
chalk:
specifier: ^5.3.0
version: 5.3.0
commander:
specifier: ^12.1.0
version: 12.1.0
consola: consola:
specifier: ^3.2.3 specifier: ^3.2.3
version: 3.2.3 version: 3.2.3
@@ -866,15 +875,6 @@ importers:
'@types/react': '@types/react':
specifier: ^18.3.3 specifier: ^18.3.3
version: 18.3.3 version: 18.3.3
c12:
specifier: ^1.11.2
version: 1.11.2(magicast@0.3.5)
chalk:
specifier: ^5.3.0
version: 5.3.0
commander:
specifier: ^12.1.0
version: 12.1.0
h3: h3:
specifier: ^1.12.0 specifier: ^1.12.0
version: 1.12.0 version: 1.12.0