fix(api): honor EXTRA_TRUSTED_ORIGINS in CORS and requestWebOrigin
This commit is contained in:
parent
ac0384e49c
commit
75423579b7
@ -361,7 +361,7 @@ export async function createApp(
|
||||
"https://172.*:*",
|
||||
"http://*.local:*",
|
||||
"https://*.local:*",
|
||||
...(process.env.EXTRA_TRUSTED_ORIGINS?.split(",").map((s) => s.trim()) ?? []),
|
||||
...(env.extraTrustedOrigins ?? []),
|
||||
],
|
||||
beforeDeleteUser: async (userId) => {
|
||||
const bots = await prisma.bot.findMany({
|
||||
@ -617,7 +617,11 @@ export async function createApp(
|
||||
actor,
|
||||
signal: c.req.raw.signal,
|
||||
userAgent: c.req.header("user-agent"),
|
||||
webOrigin: requestWebOrigin(c.req.header("origin"), env.webOrigin),
|
||||
webOrigin: requestWebOrigin(
|
||||
c.req.header("origin"),
|
||||
env.webOrigin,
|
||||
env.extraTrustedOrigins,
|
||||
),
|
||||
},
|
||||
});
|
||||
if (matched) return c.newResponse(response.body, response);
|
||||
@ -1027,6 +1031,7 @@ export async function createApp(
|
||||
function isTrustedOrigin(origin: string, env: AppEnv) {
|
||||
if (!origin) return true;
|
||||
if (origin === env.webOrigin || origin === env.apiUrl || origin === env.authUrl) return true;
|
||||
if (env.extraTrustedOrigins?.includes(origin)) return true;
|
||||
if (origin.startsWith("rakazo://") || origin.startsWith("exp://")) return true;
|
||||
try {
|
||||
const host = new URL(origin).hostname;
|
||||
|
||||
@ -20,6 +20,7 @@ export interface AppEnv {
|
||||
authSecret: string;
|
||||
authUrl: string;
|
||||
webOrigin: string;
|
||||
extraTrustedOrigins: string[];
|
||||
privacyPolicyUrl?: string;
|
||||
apiUrl: string;
|
||||
apiHost: string;
|
||||
@ -109,6 +110,10 @@ export function loadEnv(source: NodeJS.ProcessEnv = process.env): AppEnv {
|
||||
authSecret,
|
||||
authUrl: source.BETTER_AUTH_URL ?? source.WEB_ORIGIN ?? "http://127.0.0.1:5173",
|
||||
webOrigin: source.WEB_ORIGIN ?? "http://127.0.0.1:5173",
|
||||
extraTrustedOrigins: (source.EXTRA_TRUSTED_ORIGINS ?? "")
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean),
|
||||
privacyPolicyUrl: optional(source.PRIVACY_POLICY_URL),
|
||||
apiUrl: source.API_URL ?? "http://127.0.0.1:3100",
|
||||
apiHost: source.API_HOST ?? "127.0.0.1",
|
||||
|
||||
@ -25,4 +25,12 @@ describe("requestWebOrigin", () => {
|
||||
"https://evoo.example",
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts origins listed in extraTrustedOrigins", () => {
|
||||
expect(
|
||||
requestWebOrigin("https://host.example.ts.net:8443", configured, [
|
||||
"https://host.example.ts.net:8443",
|
||||
]),
|
||||
).toBe("https://host.example.ts.net:8443");
|
||||
});
|
||||
});
|
||||
|
||||
@ -14,15 +14,20 @@ export function isLoopbackHost(host: string): boolean {
|
||||
}
|
||||
|
||||
/** The web origin that browser-facing URLs (OAuth returns, screen links) should
|
||||
* point at for this request. A browser opened over a loopback or private-network
|
||||
* address gets its own origin back so a phone on the LAN is not sent to
|
||||
* 127.0.0.1; any other caller gets the configured WEB_ORIGIN. */
|
||||
export function requestWebOrigin(origin: string | undefined, webOrigin: string): string {
|
||||
* point at for this request. A browser opened over a loopback, private-network,
|
||||
* or explicitly trusted origin gets its own origin back so a phone on the LAN
|
||||
* or Tailscale is not sent to 127.0.0.1; any other caller gets WEB_ORIGIN. */
|
||||
export function requestWebOrigin(
|
||||
origin: string | undefined,
|
||||
webOrigin: string,
|
||||
extraTrustedOrigins: readonly string[] = [],
|
||||
): string {
|
||||
if (!origin) return webOrigin;
|
||||
try {
|
||||
const url = new URL(origin);
|
||||
if (url.protocol !== "http:" && url.protocol !== "https:") return webOrigin;
|
||||
if (url.origin === new URL(webOrigin).origin) return url.origin;
|
||||
if (extraTrustedOrigins.includes(url.origin)) return url.origin;
|
||||
return isPrivateOrLocalHost(url.hostname) ? url.origin : webOrigin;
|
||||
} catch {
|
||||
return webOrigin;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user