mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-09 20:27:44 +00:00
fix: bearer token interception for direct API calls
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { betterAuth } from "better-auth";
|
import { betterAuth } from "better-auth";
|
||||||
import {
|
import {
|
||||||
|
bearer,
|
||||||
organization,
|
organization,
|
||||||
passkey,
|
passkey,
|
||||||
phoneNumber,
|
phoneNumber,
|
||||||
@@ -12,6 +13,7 @@ import { resend } from "./email/resend";
|
|||||||
|
|
||||||
const from = process.env.BETTER_AUTH_EMAIL || "delivered@resend.dev";
|
const from = process.env.BETTER_AUTH_EMAIL || "delivered@resend.dev";
|
||||||
const to = process.env.TEST_EMAIL || "";
|
const to = process.env.TEST_EMAIL || "";
|
||||||
|
|
||||||
export const auth = betterAuth({
|
export const auth = betterAuth({
|
||||||
database: new LibsqlDialect({
|
database: new LibsqlDialect({
|
||||||
url: process.env.TURSO_DATABASE_URL || "",
|
url: process.env.TURSO_DATABASE_URL || "",
|
||||||
@@ -80,6 +82,7 @@ export const auth = betterAuth({
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
passkey(),
|
passkey(),
|
||||||
|
bearer()
|
||||||
],
|
],
|
||||||
socialProviders: {
|
socialProviders: {
|
||||||
github: {
|
github: {
|
||||||
|
|||||||
@@ -110,11 +110,33 @@ export function getEndpoints<
|
|||||||
let api: Record<string, any> = {};
|
let api: Record<string, any> = {};
|
||||||
for (const [key, value] of Object.entries(endpoints)) {
|
for (const [key, value] of Object.entries(endpoints)) {
|
||||||
api[key] = async (context: any) => {
|
api[key] = async (context: any) => {
|
||||||
/**
|
let c = await ctx;
|
||||||
* TODO: move this to respond a json response
|
for (const plugin of options.plugins || []) {
|
||||||
* instead of response object.
|
if (plugin.hooks?.before) {
|
||||||
*/
|
for (const hook of plugin.hooks.before) {
|
||||||
const c = await ctx;
|
const match = hook.matcher({
|
||||||
|
...value,
|
||||||
|
...context,
|
||||||
|
context: c,
|
||||||
|
});
|
||||||
|
if (match) {
|
||||||
|
const hookRes = await hook.handler({
|
||||||
|
...context,
|
||||||
|
context: {
|
||||||
|
...c,
|
||||||
|
...context.context,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (hookRes && "context" in hookRes) {
|
||||||
|
c = {
|
||||||
|
...c,
|
||||||
|
...hookRes.context,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const endpointRes = await value({
|
const endpointRes = await value({
|
||||||
...context,
|
...context,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ type InferAPI<API> = Omit<
|
|||||||
export const betterAuth = <O extends BetterAuthOptions>(options: O) => {
|
export const betterAuth = <O extends BetterAuthOptions>(options: O) => {
|
||||||
const authContext = init(options);
|
const authContext = init(options);
|
||||||
const { api } = getEndpoints(authContext, options);
|
const { api } = getEndpoints(authContext, options);
|
||||||
type API = typeof api;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
handler: async (request: Request) => {
|
handler: async (request: Request) => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { bearer } from ".";
|
|||||||
import { getTestInstance } from "../../test-utils/test-instance";
|
import { getTestInstance } from "../../test-utils/test-instance";
|
||||||
|
|
||||||
describe("bearer", async () => {
|
describe("bearer", async () => {
|
||||||
const { client, signInWithTestUser } = await getTestInstance({
|
const { client, signInWithTestUser, auth } = await getTestInstance({
|
||||||
plugins: [bearer()],
|
plugins: [bearer()],
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -32,4 +32,15 @@ describe("bearer", async () => {
|
|||||||
});
|
});
|
||||||
expect(sessions.data).toHaveLength(2);
|
expect(sessions.data).toHaveLength(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should work on server actions", async () => {
|
||||||
|
const { res } = await signInWithTestUser();
|
||||||
|
token = res.data?.session.id || "";
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set("authorization", `Bearer ${token}`);
|
||||||
|
const session = await auth.api.getSession({
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
expect(session?.session.id).toBe(token);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import { serializeSigned } from "better-call";
|
import { serializeSigned } from "better-call";
|
||||||
import { createAuthMiddleware } from "../../api/call";
|
|
||||||
import { BetterAuthError } from "../../error/better-auth-error";
|
|
||||||
import type { BetterAuthPlugin } from "../../types/plugins";
|
import type { BetterAuthPlugin } from "../../types/plugins";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,25 +7,49 @@ import type { BetterAuthPlugin } from "../../types/plugins";
|
|||||||
export const bearer = () => {
|
export const bearer = () => {
|
||||||
return {
|
return {
|
||||||
id: "bearer",
|
id: "bearer",
|
||||||
async onRequest(request, ctx) {
|
hooks: {
|
||||||
const token = request.headers
|
before: [
|
||||||
.get("authorization")
|
{
|
||||||
?.replace("Bearer ", "");
|
matcher(context) {
|
||||||
if (!token) {
|
return Boolean(
|
||||||
return;
|
context.request?.headers.get("authorization") ||
|
||||||
}
|
context.headers?.get("authorization"),
|
||||||
const headers = request.headers || new Headers();
|
);
|
||||||
const signedToken = await serializeSigned("", token, ctx.secret);
|
},
|
||||||
headers.set(
|
handler: async (c) => {
|
||||||
"cookie",
|
const token =
|
||||||
`${ctx.authCookies.sessionToken.name}=${signedToken.replace("=", "")}`,
|
c.request?.headers.get("authorization")?.replace("Bearer ", "") ||
|
||||||
);
|
c.headers?.get("authorization")?.replace("Bearer ", "");
|
||||||
return {
|
if (!token) {
|
||||||
request: new Request(request.url, {
|
return;
|
||||||
method: request.method,
|
}
|
||||||
headers,
|
const signedToken = await serializeSigned(
|
||||||
}),
|
"",
|
||||||
};
|
token,
|
||||||
|
c.context.secret,
|
||||||
|
);
|
||||||
|
if (c.request) {
|
||||||
|
c.request.headers.set(
|
||||||
|
"cookie",
|
||||||
|
`${
|
||||||
|
c.context.authCookies.sessionToken.name
|
||||||
|
}=${signedToken.replace("=", "")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (c.headers) {
|
||||||
|
c.headers.set(
|
||||||
|
"cookie",
|
||||||
|
`${
|
||||||
|
c.context.authCookies.sessionToken.name
|
||||||
|
}=${signedToken.replace("=", "")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
context: c,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
} satisfies BetterAuthPlugin;
|
} satisfies BetterAuthPlugin;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user