Revert "PHP Rebuild"

This reverts commit 2ef3654841.
This commit is contained in:
Stefan Lazic committed 2026-09-05 09:32:05 +01:00
1 parent a59f998f2b
commit 2aa8405006
690 files changed
+12045 -33943

No files matched your search

@@ -0,0 +1,28 @@
import { describe, expect, it } from "vitest";
import { safeRedirectPath } from "../safe-redirect";
describe("safeRedirectPath", () => {
it("accepts a plain internal path", () => {
expect(safeRedirectPath("/book/details", "/home")).toBe("/book/details");
});
it("falls back for null/undefined/empty input", () => {
expect(safeRedirectPath(null, "/home")).toBe("/home");
expect(safeRedirectPath(undefined, "/home")).toBe("/home");
expect(safeRedirectPath("", "/home")).toBe("/home");
});
it("rejects protocol-relative URLs", () => {
expect(safeRedirectPath("//evil.com", "/home")).toBe("/home");
});
it("rejects absolute URLs to another host", () => {
expect(safeRedirectPath("https://evil.com/phish", "/home")).toBe("/home");
expect(safeRedirectPath("http://evil.com", "/home")).toBe("/home");
});
it("rejects a path not starting with a single slash", () => {
expect(safeRedirectPath("book/details", "/home")).toBe("/home");
expect(safeRedirectPath("javascript:alert(1)", "/home")).toBe("/home");
});
});
+10
View File
@@ -0,0 +1,10 @@
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
/**
* Merge Tailwind class lists safely — later classes win over earlier ones
* for the same utility group (e.g. `cn("px-4", condition && "px-6")`).
*/
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
+18
View File
@@ -0,0 +1,18 @@
/**
* Validates a caller-supplied return path (a `callbackUrl` query param,
* a booking-draft continuation target) is a safe, internal, relative
* path before it's ever used in a redirect — see the brief's "Accept
* only safe internal return paths. Prevent open redirects." Auth.js's
* own `signIn()`/`redirectTo` already restricts to same-origin
* internally, but this is checked explicitly rather than relied on
* implicitly, since it guards a value that reached this code from a URL
* query string, not from a trusted internal source.
*/
export function safeRedirectPath(path: string | null | undefined, fallback: string): string {
if (!path) return fallback;
// Must start with exactly one "/" — rejects "//evil.com" (protocol-relative),
// "https://evil.com", and "javascript:..." in one check.
if (!path.startsWith("/") || path.startsWith("//")) return fallback;
if (path.includes("://")) return fallback;
return path;
}