feat : big update
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { safeAuthReturnPath } from "./return-path";
|
||||
|
||||
describe("public auth return path", () => {
|
||||
it("keeps site-local destinations", () => {
|
||||
expect(safeAuthReturnPath("/commission/tickets?from=login")).toBe("/commission/tickets?from=login");
|
||||
});
|
||||
|
||||
it("rejects external destinations and auth loops", () => {
|
||||
for (const value of ["https://example.com", "//example.com", "/\\example.com", "/login", "/lo%67in", "/register", 4])
|
||||
expect(safeAuthReturnPath(value)).toBe("/");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
export function safeAuthReturnPath(value: unknown): string {
|
||||
if (typeof value !== "string" || !value.startsWith("/")) return "/";
|
||||
try {
|
||||
const url = new URL(value, "https://auth.local");
|
||||
const path = decodeURIComponent(url.pathname);
|
||||
if (url.origin !== "https://auth.local" || ["/login", "/register", "/commission/login"].includes(path))
|
||||
return "/";
|
||||
return `${url.pathname}${url.search}${url.hash}`;
|
||||
} catch {
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ describe("actual administrator session boundary", () => {
|
||||
it("defaults accounts to user and requires strong new passwords", async () => {
|
||||
(await import("./server")).getAuth();
|
||||
const options = mocks.auth.mock.calls.at(-1)![0];
|
||||
expect(options.emailAndPassword).toMatchObject({ disableSignUp: true, minPasswordLength: 12 });
|
||||
expect(options.emailAndPassword).toMatchObject({ disableSignUp: false, minPasswordLength: 12 });
|
||||
expect(options.plugins).toContainEqual({ defaultRole: "user" });
|
||||
expect(options.rateLimit.customStorage.consume).toBeTypeOf("function");
|
||||
expect(options.databaseHooks).toBeUndefined();
|
||||
|
||||
+9
-2
@@ -52,7 +52,7 @@ function createAuth() {
|
||||
secret: required("BETTER_AUTH_SECRET"),
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
disableSignUp: true,
|
||||
disableSignUp: false,
|
||||
minPasswordLength: 12,
|
||||
maxPasswordLength: 128,
|
||||
},
|
||||
@@ -72,7 +72,7 @@ function createAuth() {
|
||||
captcha({
|
||||
provider: "cloudflare-turnstile",
|
||||
secretKey: required("TURNSTILE_SECRET_KEY"),
|
||||
endpoints: ["/sign-in/email"],
|
||||
endpoints: ["/sign-in/email", "/sign-up/email"],
|
||||
}),
|
||||
]),
|
||||
admin({ defaultRole: "user" }),
|
||||
@@ -125,3 +125,10 @@ export async function requireAdmin(): Promise<AdminSession> {
|
||||
if (!session) throw new AdminAuthorizationError();
|
||||
return session;
|
||||
}
|
||||
|
||||
export const getCustomerSession = cache(async () => {
|
||||
if (!hasAuthConfiguration()) return null;
|
||||
const session = await getAuth().api.getSession({ headers: await headers() });
|
||||
if (!session?.session) return null;
|
||||
return { user: session.user, session: { id: session.session.id } };
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user