{
const renderId = (this.#renderId = uniqueId("render-id-"));
+ const blocked = hooks?.auth?.isBlockedPath?.(location.pathname);
resetAllComputedMarks();
clearResolveCache();
@@ -288,7 +289,9 @@ export class Router {
// const renderStartTime = performance.now();
const finishPageView = hooks?.pageView?.create();
- const storyboard = matchStoryboard(this.#storyboards, location.pathname);
+ const storyboard = blocked
+ ? undefined
+ : matchStoryboard(this.#storyboards, location.pathname);
const previousApp = this.#runtimeContext?.app;
const currentAppId = storyboard?.app?.id;
@@ -576,7 +579,13 @@ export class Router {
applyMode();
const node = await ErrorNode(
- new PageNotFoundError(currentApp ? "page not found" : "app not found"),
+ new PageError(
+ blocked
+ ? "page blocked"
+ : currentApp
+ ? "page not found"
+ : "app not found"
+ ),
renderRoot,
true
);
@@ -586,7 +595,7 @@ export class Router {
// Scroll to top after each rendering.
window.scrollTo(0, 0);
- finishPageView?.({ status: "not-found" });
+ finishPageView?.({ status: blocked ? "blocked" : "not-found" });
devtoolsHookEmit("rendered");
}
}
diff --git a/packages/runtime/src/internal/Runtime.spec.ts b/packages/runtime/src/internal/Runtime.spec.ts
index 322ef917ea..2d6663b421 100644
--- a/packages/runtime/src/internal/Runtime.spec.ts
+++ b/packages/runtime/src/internal/Runtime.spec.ts
@@ -1688,6 +1688,70 @@ describe("Runtime", () => {
expect(finishPageView).toHaveBeenNthCalledWith(2, { status: "not-found" });
});
+ test("page blocked", async () => {
+ window.NO_AUTH_GUARD = false;
+ const finishPageView = jest.fn();
+ createRuntime({
+ hooks: {
+ auth: {
+ isLoggedIn() {
+ return true;
+ },
+ getAuth() {
+ return {};
+ },
+ isBlockedPath() {
+ return true;
+ },
+ },
+ pageView: {
+ create: jest.fn(() => finishPageView),
+ },
+ },
+ }).initialize({
+ storyboards: [
+ {
+ app: {
+ id: "blocked-app",
+ homepage: "/blocked-app",
+ name: "Blocked APP",
+ },
+ routes: [
+ {
+ path: "${APP.homepage}/blocked",
+ bricks: [{ brick: "div" }],
+ },
+ ],
+ },
+ ],
+ brickPackages: [],
+ });
+ getHistory().push("/blocked-app/blocked");
+ await getRuntime().bootstrap();
+ expect(document.body.children).toMatchInlineSnapshot(`
+ HTMLCollection [
+
+
+
+ Go back to home page
+
+
+
,
+ ,
+ ]
+ `);
+ expect(finishPageView).toBeCalledTimes(1);
+ expect(finishPageView).toBeCalledWith({
+ status: "blocked",
+ });
+ });
+
test("failed to bootstrap", async () => {
consoleError.mockReturnValueOnce();
const finishPageView = jest.fn();
diff --git a/packages/runtime/src/internal/Runtime.ts b/packages/runtime/src/internal/Runtime.ts
index 06ccf1b892..598aa7549a 100644
--- a/packages/runtime/src/internal/Runtime.ts
+++ b/packages/runtime/src/internal/Runtime.ts
@@ -45,7 +45,7 @@ export interface ImagesFactory {
}
export interface PageViewInfo {
- status: "ok" | "failed" | "redirected" | "not-found";
+ status: "ok" | "failed" | "redirected" | "not-found" | "blocked";
path?: string;
pageTitle?: string;
}
@@ -56,6 +56,7 @@ export interface RuntimeHooks {
isLoggedIn(): boolean;
authenticate?(...args: unknown[]): unknown;
logout?(...args: unknown[]): unknown;
+ isBlockedPath?(pathname: string): boolean;
};
fulfilStoryboard?: (storyboard: RuntimeStoryboard) => Promise;
validatePermissions?: typeof PermissionApi_validatePermissions;
diff --git a/packages/runtime/src/internal/i18n.ts b/packages/runtime/src/internal/i18n.ts
index d11497643b..60d14a13e9 100644
--- a/packages/runtime/src/internal/i18n.ts
+++ b/packages/runtime/src/internal/i18n.ts
@@ -4,6 +4,7 @@ export enum K {
LOGIN_TIMEOUT_MESSAGE = "LOGIN_TIMEOUT_MESSAGE",
NETWORK_ERROR = "NETWORK_ERROR",
LICENSE_EXPIRED = "LICENSE_EXPIRED",
+ LICENSE_BLOCKED = "LICENSE_BLOCKED",
NO_PERMISSION = "NO_PERMISSION",
PAGE_NOT_FOUND = "PAGE_NOT_FOUND",
APP_NOT_FOUND = "APP_NOT_FOUND",
@@ -21,6 +22,8 @@ const en: Locale = {
[K.NETWORK_ERROR]: "Network error, please check your network.",
[K.LICENSE_EXPIRED]:
"The license authorization has expired, please contact the platform administrator",
+ [K.LICENSE_BLOCKED]:
+ "The page is not authorized, please contact the platform administrator",
[K.NO_PERMISSION]:
"Unauthorized access, unable to retrieve the required resources for this page",
[K.PAGE_NOT_FOUND]: "Page not found, please check the URL",
@@ -38,6 +41,7 @@ const zh: Locale = {
[K.LOGIN_TIMEOUT_MESSAGE]: "您还未登录或登录信息已过期,现在重新登录?",
[K.NETWORK_ERROR]: "网络错误,请检查您的网络连接。",
[K.LICENSE_EXPIRED]: "License 授权失效,请联系平台管理员",
+ [K.LICENSE_BLOCKED]: "该页面未授权,请联系平台管理员",
[K.NO_PERMISSION]: "没有权限,无法获取页面所需要的资源",
[K.PAGE_NOT_FOUND]: "请求的页面未找到,请确认 URL 是否正确",
[K.APP_NOT_FOUND]: "请求的微应用无法找到, 可能是 URL 错误或者无权限访问",
diff --git a/yarn.lock b/yarn.lock
index e29ff4e3e5..6871e4d5ea 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1968,12 +1968,12 @@
resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d"
integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==
-"@next-api-sdk/api-gateway-sdk@^1.1.0", "@next-api-sdk/api-gateway-sdk@^1.2.0":
- version "1.2.0"
- resolved "https://registry.npmjs.org/@next-api-sdk/api-gateway-sdk/-/api-gateway-sdk-1.2.0.tgz#68a49bf50f76c626234ce53cb3606f7dbeb2ca97"
- integrity sha512-HG6wSG2hoH+ZXEH/AUIsbhUwtzXQgWKU7usrFVVQsGmqIQscjRYMSlCqEAJixP1IG9vQ0D+kkkaeAoSnhX3nEg==
+"@next-api-sdk/api-gateway-sdk@^1.2.2":
+ version "1.2.2"
+ resolved "https://registry.npmjs.org/@next-api-sdk/api-gateway-sdk/-/api-gateway-sdk-1.2.2.tgz#867b2b93573379fcd8f2507876bc0ce83bf19858"
+ integrity sha512-q4XFL3xOAcG+qboXWKRfENiiN72dVIs0w9JBurVj5NwbgSsF3L4L1T+v1MJlBIp7hhEzWa60SwvUh0IiRneNqA==
dependencies:
- "@next-core/http" "^1.0.0"
+ "@next-core/http" "^1.2.6"
"@next-api-sdk/cmdb-sdk@^1.1.0":
version "1.1.0"