mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Fix dashboard loading bug
This commit is contained in:
parent
71e6562e6f
commit
ea62e70f44
@ -8,7 +8,7 @@ import { useMemo } from 'react';
|
||||
import { SignIn, SignUp, StackServerApp } from "..";
|
||||
import { useStackApp } from "../lib/hooks";
|
||||
import { HandlerUrls, StackClientApp, stackAppInternalsSymbol } from "../lib/stack-app";
|
||||
import { resolveUnknownHandlerPathFallbackUrl } from "../lib/stack-app/url-targets";
|
||||
import { isLocalHandlerUrlTarget, resolveUnknownHandlerPathFallbackUrl } from "../lib/stack-app/url-targets";
|
||||
import { AccountSettings } from "./account-settings";
|
||||
import { CliAuthConfirmation } from "./cli-auth-confirm";
|
||||
import { EmailVerification } from "./email-verification";
|
||||
@ -260,11 +260,11 @@ export function StackHandlerClient(props: BaseHandlerProps & Partial<RouteProps>
|
||||
if (isCrossDomainLocalOauthCallback) {
|
||||
return;
|
||||
}
|
||||
const urlObject = new URL(url, placeholderOrigin);
|
||||
const isHandlerPathTarget = urlObject.pathname === handlerPath || urlObject.pathname.startsWith(`${handlerPath}/`);
|
||||
const isLocalHandlerTarget = typeof window === "undefined"
|
||||
? isHandlerPathTarget
|
||||
: urlObject.origin === window.location.origin && isHandlerPathTarget;
|
||||
const isLocalHandlerTarget = isLocalHandlerUrlTarget({
|
||||
targetUrl: url,
|
||||
handlerPath,
|
||||
currentOrigin: typeof window === "undefined" ? undefined : window.location.origin,
|
||||
});
|
||||
if (isLocalHandlerTarget) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveHandlerUrls, resolveUnknownHandlerPathFallbackUrl } from "./url-targets";
|
||||
import { isLocalHandlerUrlTarget, resolveHandlerUrls, resolveUnknownHandlerPathFallbackUrl } from "./url-targets";
|
||||
|
||||
describe("handler URL targets", () => {
|
||||
afterEach(() => {
|
||||
@ -112,3 +112,37 @@ describe("handler URL targets", () => {
|
||||
})).toThrowError(/\{projectId\} and \{hostedPath\}/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isLocalHandlerUrlTarget", () => {
|
||||
it("treats relative handler URLs as local targets", () => {
|
||||
expect(isLocalHandlerUrlTarget({
|
||||
targetUrl: "/handler/sign-in",
|
||||
handlerPath: "/handler",
|
||||
currentOrigin: "http://p91.localhost:9101",
|
||||
})).toBe(true);
|
||||
});
|
||||
|
||||
it("treats same-origin absolute handler URLs as local targets", () => {
|
||||
expect(isLocalHandlerUrlTarget({
|
||||
targetUrl: "http://p91.localhost:9101/handler/sign-in",
|
||||
handlerPath: "/handler",
|
||||
currentOrigin: "http://p91.localhost:9101",
|
||||
})).toBe(true);
|
||||
});
|
||||
|
||||
it("treats cross-origin absolute handler URLs as non-local targets", () => {
|
||||
expect(isLocalHandlerUrlTarget({
|
||||
targetUrl: "https://project-id.built-with-stack-auth.com/handler/sign-in",
|
||||
handlerPath: "/handler",
|
||||
currentOrigin: "http://p91.localhost:9101",
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
it("treats non-handler paths as non-local targets", () => {
|
||||
expect(isLocalHandlerUrlTarget({
|
||||
targetUrl: "/projects",
|
||||
handlerPath: "/handler",
|
||||
currentOrigin: "http://p91.localhost:9101",
|
||||
})).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -6,6 +6,8 @@ import { DefaultHandlerUrlTarget, HandlerPageUrls, HandlerUrlOptions, HandlerUrl
|
||||
const defaultHostedHandlerDomainSuffix = ".built-with-stack-auth.com";
|
||||
const hostedHandlerProjectIdPlaceholder = "{projectId}";
|
||||
const hostedHandlerPathPlaceholder = "{hostedPath}";
|
||||
const localUrlPlaceholderOrigin = "http://example.com";
|
||||
const schemePrefixRegex = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
|
||||
|
||||
type CustomPagePrompt = {
|
||||
title: string,
|
||||
@ -216,6 +218,33 @@ export const getHostedHandlerUrl = (options: { projectId: string, pagePath: stri
|
||||
return new URL(templateFilled).toString();
|
||||
};
|
||||
|
||||
const isRelativeUrlString = (url: string): boolean => {
|
||||
if (url.startsWith("//")) {
|
||||
return false;
|
||||
}
|
||||
return !schemePrefixRegex.test(url);
|
||||
};
|
||||
|
||||
export const isLocalHandlerUrlTarget = (options: {
|
||||
targetUrl: string,
|
||||
handlerPath: string,
|
||||
currentOrigin?: string,
|
||||
}): boolean => {
|
||||
const urlObject = new URL(options.targetUrl, localUrlPlaceholderOrigin);
|
||||
const isHandlerPathTarget = urlObject.pathname === options.handlerPath
|
||||
|| urlObject.pathname.startsWith(`${options.handlerPath}/`);
|
||||
if (!isHandlerPathTarget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// On server we only have path information, so treat matching handler paths as local.
|
||||
if (options.currentOrigin == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isRelativeUrlString(options.targetUrl) || urlObject.origin === options.currentOrigin;
|
||||
};
|
||||
|
||||
const resolveUrlTarget = (options: {
|
||||
target: HandlerUrlTarget,
|
||||
fallbackPath: string,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user