mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-09 12:27:43 +00:00
fix: passkey headers
This commit is contained in:
@@ -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({
|
||||||
|
|||||||
@@ -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 />
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
42
packages/better-auth/src/plugins/passkey/passkey.test.ts
Normal file
42
packages/better-auth/src/plugins/passkey/passkey.test.ts
Normal 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
18
pnpm-lock.yaml
generated
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user