mirror of
https://github.com/outline/outline.git
synced 2026-06-13 19:35:02 +03:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 099d0c8018 | |||
| 6334de29cc | |||
| 8e7c0284a4 | |||
| 590a02b124 | |||
| 6fcd9f6ac2 | |||
| 79b2886852 | |||
| 57ac5f54bf |
@@ -3,7 +3,7 @@ Business Source License 1.1
|
||||
Parameters
|
||||
|
||||
Licensor: General Outline, Inc.
|
||||
Licensed Work: Outline 0.85.0
|
||||
Licensed Work: Outline 0.85.1
|
||||
The Licensed Work is (c) 2025 General Outline, Inc.
|
||||
Additional Use Grant: You may make use of the Licensed Work, provided that
|
||||
you may not use the Licensed Work for a Document
|
||||
@@ -15,7 +15,7 @@ Additional Use Grant: You may make use of the Licensed Work, provided that
|
||||
Licensed Work by creating teams and documents
|
||||
controlled by such third parties.
|
||||
|
||||
Change Date: 2029-07-03
|
||||
Change Date: 2029-07-11
|
||||
|
||||
Change License: Apache License, Version 2.0
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ export const openCollection = createAction({
|
||||
name: collection.name,
|
||||
icon: <ColorCollectionIcon collection={collection} />,
|
||||
section: CollectionSection,
|
||||
perform: () => history.push(collection.path),
|
||||
to: collection.path,
|
||||
}));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -98,7 +98,7 @@ export const openDocument = createAction({
|
||||
<DocumentIcon />
|
||||
),
|
||||
section: DocumentSection,
|
||||
perform: () => history.push(item.url),
|
||||
to: item.url,
|
||||
}));
|
||||
},
|
||||
});
|
||||
@@ -840,7 +840,7 @@ export const searchDocumentsForQuery = (query: string) =>
|
||||
analyticsName: "Search documents",
|
||||
section: DocumentSection,
|
||||
icon: <SearchIcon />,
|
||||
perform: () => history.push(searchPath({ query })),
|
||||
to: searchPath({ query }),
|
||||
visible: ({ location }) => location.pathname !== searchPath(),
|
||||
});
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import KeyboardShortcuts from "~/scenes/KeyboardShortcuts";
|
||||
import { createAction } from "~/actions";
|
||||
import { NavigationSection, RecentSearchesSection } from "~/actions/sections";
|
||||
import Desktop from "~/utils/Desktop";
|
||||
import history from "~/utils/history";
|
||||
import isCloudHosted from "~/utils/isCloudHosted";
|
||||
import {
|
||||
homePath,
|
||||
@@ -38,7 +37,7 @@ export const navigateToHome = createAction({
|
||||
section: NavigationSection,
|
||||
shortcut: ["d"],
|
||||
icon: <HomeIcon />,
|
||||
perform: () => history.push(homePath()),
|
||||
to: homePath(),
|
||||
visible: ({ location }) => location.pathname !== homePath(),
|
||||
});
|
||||
|
||||
@@ -48,7 +47,7 @@ export const navigateToRecentSearchQuery = (searchQuery: SearchQuery) =>
|
||||
name: searchQuery.query,
|
||||
analyticsName: "Navigate to recent search query",
|
||||
icon: <SearchIcon />,
|
||||
perform: () => history.push(searchPath({ query: searchQuery.query })),
|
||||
to: searchPath({ query: searchQuery.query }),
|
||||
});
|
||||
|
||||
export const navigateToDrafts = createAction({
|
||||
@@ -56,7 +55,7 @@ export const navigateToDrafts = createAction({
|
||||
analyticsName: "Navigate to drafts",
|
||||
section: NavigationSection,
|
||||
icon: <DraftsIcon />,
|
||||
perform: () => history.push(draftsPath()),
|
||||
to: draftsPath(),
|
||||
visible: ({ location }) => location.pathname !== draftsPath(),
|
||||
});
|
||||
|
||||
@@ -65,7 +64,7 @@ export const navigateToSearch = createAction({
|
||||
analyticsName: "Navigate to search",
|
||||
section: NavigationSection,
|
||||
icon: <SearchIcon />,
|
||||
perform: () => history.push(searchPath()),
|
||||
to: searchPath(),
|
||||
visible: ({ location }) => location.pathname !== searchPath(),
|
||||
});
|
||||
|
||||
@@ -75,7 +74,7 @@ export const navigateToArchive = createAction({
|
||||
section: NavigationSection,
|
||||
shortcut: ["g", "a"],
|
||||
icon: <ArchiveIcon />,
|
||||
perform: () => history.push(archivePath()),
|
||||
to: archivePath(),
|
||||
visible: ({ location }) => location.pathname !== archivePath(),
|
||||
});
|
||||
|
||||
@@ -84,7 +83,7 @@ export const navigateToTrash = createAction({
|
||||
analyticsName: "Navigate to trash",
|
||||
section: NavigationSection,
|
||||
icon: <TrashIcon />,
|
||||
perform: () => history.push(trashPath()),
|
||||
to: trashPath(),
|
||||
visible: ({ location }) => location.pathname !== trashPath(),
|
||||
});
|
||||
|
||||
@@ -95,7 +94,7 @@ export const navigateToSettings = createAction({
|
||||
shortcut: ["g", "s"],
|
||||
icon: <SettingsIcon />,
|
||||
visible: () => stores.policies.abilities(stores.auth.team?.id || "").update,
|
||||
perform: () => history.push(settingsPath()),
|
||||
to: settingsPath(),
|
||||
});
|
||||
|
||||
export const navigateToWorkspaceSettings = createAction({
|
||||
@@ -104,7 +103,7 @@ export const navigateToWorkspaceSettings = createAction({
|
||||
section: NavigationSection,
|
||||
icon: <SettingsIcon />,
|
||||
visible: () => stores.policies.abilities(stores.auth.team?.id || "").update,
|
||||
perform: () => history.push(settingsPath("details")),
|
||||
to: settingsPath("details"),
|
||||
});
|
||||
|
||||
export const navigateToProfileSettings = createAction({
|
||||
@@ -113,7 +112,7 @@ export const navigateToProfileSettings = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <ProfileIcon />,
|
||||
perform: () => history.push(settingsPath()),
|
||||
to: settingsPath(),
|
||||
});
|
||||
|
||||
export const navigateToTemplateSettings = createAction({
|
||||
@@ -122,7 +121,7 @@ export const navigateToTemplateSettings = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <ShapesIcon />,
|
||||
perform: () => history.push(settingsPath("templates")),
|
||||
to: settingsPath("templates"),
|
||||
});
|
||||
|
||||
export const navigateToNotificationSettings = createAction({
|
||||
@@ -131,7 +130,7 @@ export const navigateToNotificationSettings = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <EmailIcon />,
|
||||
perform: () => history.push(settingsPath("notifications")),
|
||||
to: settingsPath("notifications"),
|
||||
});
|
||||
|
||||
export const navigateToAccountPreferences = createAction({
|
||||
@@ -140,7 +139,7 @@ export const navigateToAccountPreferences = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <SettingsIcon />,
|
||||
perform: () => history.push(settingsPath("preferences")),
|
||||
to: settingsPath("preferences"),
|
||||
});
|
||||
|
||||
export const openDocumentation = createAction({
|
||||
@@ -149,7 +148,10 @@ export const openDocumentation = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <OpenIcon />,
|
||||
perform: () => window.open(UrlHelper.guide),
|
||||
to: {
|
||||
url: UrlHelper.guide,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openAPIDocumentation = createAction({
|
||||
@@ -158,7 +160,10 @@ export const openAPIDocumentation = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <OpenIcon />,
|
||||
perform: () => window.open(UrlHelper.developers),
|
||||
to: {
|
||||
url: UrlHelper.developers,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const toggleSidebar = createAction({
|
||||
@@ -175,14 +180,20 @@ export const openFeedbackUrl = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <EmailIcon />,
|
||||
perform: () => window.open(UrlHelper.contact),
|
||||
to: {
|
||||
url: UrlHelper.contact,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openBugReportUrl = createAction({
|
||||
name: ({ t }) => t("Report a bug"),
|
||||
analyticsName: "Open bug report",
|
||||
section: NavigationSection,
|
||||
perform: () => window.open(UrlHelper.github),
|
||||
to: {
|
||||
url: UrlHelper.github,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openChangelog = createAction({
|
||||
@@ -191,7 +202,10 @@ export const openChangelog = createAction({
|
||||
section: NavigationSection,
|
||||
iconInContextMenu: false,
|
||||
icon: <OpenIcon />,
|
||||
perform: () => window.open(UrlHelper.changelog),
|
||||
to: {
|
||||
url: UrlHelper.changelog,
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
export const openKeyboardShortcuts = createAction({
|
||||
@@ -219,8 +233,9 @@ export const downloadApp = createAction({
|
||||
iconInContextMenu: false,
|
||||
icon: <BrowserIcon />,
|
||||
visible: () => !Desktop.isElectron() && isMac() && isCloudHosted,
|
||||
perform: () => {
|
||||
window.open("https://desktop.getoutline.com");
|
||||
to: {
|
||||
url: "https://desktop.getoutline.com",
|
||||
target: "_blank",
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -32,7 +32,10 @@ export const switchTeamsList = ({ stores }: { stores: RootStore }) =>
|
||||
);
|
||||
},
|
||||
visible: ({ currentTeamId }: ActionContext) => currentTeamId !== session.id,
|
||||
perform: () => (window.location.href = session.url),
|
||||
to: {
|
||||
url: session.url,
|
||||
target: "_self",
|
||||
},
|
||||
})) ?? [];
|
||||
|
||||
export const switchTeam = createAction({
|
||||
|
||||
+35
-6
@@ -6,10 +6,13 @@ import {
|
||||
Action,
|
||||
ActionContext,
|
||||
CommandBarAction,
|
||||
MenuExternalLink,
|
||||
MenuInternalLink,
|
||||
MenuItemButton,
|
||||
MenuItemWithChildren,
|
||||
} from "~/types";
|
||||
import Analytics from "~/utils/Analytics";
|
||||
import history from "~/utils/history";
|
||||
|
||||
function resolve<T>(value: any, context: ActionContext): T {
|
||||
return typeof value === "function" ? value(context) : value;
|
||||
@@ -31,7 +34,6 @@ export function createAction(definition: Optional<Action, "id">): Action {
|
||||
: "contextmenu",
|
||||
});
|
||||
}
|
||||
|
||||
return definition.perform?.(context);
|
||||
}
|
||||
: undefined,
|
||||
@@ -42,7 +44,7 @@ export function createAction(definition: Optional<Action, "id">): Action {
|
||||
export function actionToMenuItem(
|
||||
action: Action,
|
||||
context: ActionContext
|
||||
): MenuItemButton | MenuItemWithChildren {
|
||||
): MenuItemButton | MenuExternalLink | MenuInternalLink | MenuItemWithChildren {
|
||||
const resolvedIcon = resolve<React.ReactElement<any>>(action.icon, context);
|
||||
const resolvedChildren = resolve<Action[]>(action.children, context);
|
||||
const visible = action.visible ? action.visible(context) : true;
|
||||
@@ -67,6 +69,26 @@ export function actionToMenuItem(
|
||||
};
|
||||
}
|
||||
|
||||
if (action.to) {
|
||||
return typeof action.to === "string"
|
||||
? {
|
||||
type: "route",
|
||||
title,
|
||||
icon,
|
||||
visible,
|
||||
to: action.to,
|
||||
selected: action.selected?.(context),
|
||||
}
|
||||
: {
|
||||
type: "link",
|
||||
title,
|
||||
icon,
|
||||
visible,
|
||||
href: action.to,
|
||||
selected: action.selected?.(context),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: "button",
|
||||
title,
|
||||
@@ -113,9 +135,10 @@ export function actionToKBar(
|
||||
shortcut: action.shortcut || [],
|
||||
icon: resolvedIcon,
|
||||
priority: (1 + (action.priority ?? 0)) * (1 + (sectionPriority ?? 0)),
|
||||
perform: action.perform
|
||||
? () => performAction(action, context)
|
||||
: undefined,
|
||||
perform:
|
||||
action.perform || action.to
|
||||
? () => performAction(action, context)
|
||||
: undefined,
|
||||
},
|
||||
].concat(
|
||||
// @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call.
|
||||
@@ -124,7 +147,13 @@ export function actionToKBar(
|
||||
}
|
||||
|
||||
export async function performAction(action: Action, context: ActionContext) {
|
||||
const result = action.perform?.(context);
|
||||
const result = action.perform
|
||||
? action.perform(context)
|
||||
: action.to
|
||||
? typeof action.to === "string"
|
||||
? history.push(action.to)
|
||||
: window.open(action.to.url, action.to.target)
|
||||
: undefined;
|
||||
|
||||
if (result instanceof Promise) {
|
||||
return result.catch((err: Error) => {
|
||||
|
||||
@@ -59,7 +59,7 @@ const ActionButton = React.forwardRef<HTMLButtonElement, Props>(
|
||||
disabled={disabled || executing}
|
||||
ref={ref}
|
||||
onClick={
|
||||
action?.perform && actionContext
|
||||
actionContext
|
||||
? (ev) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
|
||||
@@ -4,7 +4,6 @@ import Icon from "@shared/components/Icon";
|
||||
import { createAction } from "~/actions";
|
||||
import { RecentSection } from "~/actions/sections";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import history from "~/utils/history";
|
||||
import { documentPath } from "~/utils/routeHelpers";
|
||||
|
||||
const useRecentDocumentActions = (count = 6) => {
|
||||
@@ -25,7 +24,7 @@ const useRecentDocumentActions = (count = 6) => {
|
||||
) : (
|
||||
<DocumentIcon />
|
||||
),
|
||||
perform: () => history.push(documentPath(item)),
|
||||
to: documentPath(item),
|
||||
})
|
||||
),
|
||||
[count, ui.activeDocumentId, documents.recentlyViewed]
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useMemo } from "react";
|
||||
import { createAction } from "~/actions";
|
||||
import { NavigationSection } from "~/actions/sections";
|
||||
import useSettingsConfig from "~/hooks/useSettingsConfig";
|
||||
import history from "~/utils/history";
|
||||
|
||||
const useSettingsAction = () => {
|
||||
const config = useSettingsConfig();
|
||||
@@ -16,7 +15,7 @@ const useSettingsAction = () => {
|
||||
name: item.name,
|
||||
icon: <Icon />,
|
||||
section: NavigationSection,
|
||||
perform: () => history.push(item.path),
|
||||
to: item.path,
|
||||
};
|
||||
}),
|
||||
[config]
|
||||
|
||||
@@ -20,7 +20,7 @@ type Props = {
|
||||
dangerous?: boolean;
|
||||
to?: LocationDescriptor;
|
||||
href?: string;
|
||||
target?: "_blank";
|
||||
target?: string;
|
||||
as?: string | React.ComponentType<any>;
|
||||
hide?: () => void;
|
||||
level?: number;
|
||||
|
||||
@@ -155,12 +155,14 @@ function Template({ items, actions, context, showIcons, ...menu }: Props) {
|
||||
return (
|
||||
<MenuItem
|
||||
id={`${item.title}-${index}`}
|
||||
href={item.href}
|
||||
href={typeof item.href === "string" ? item.href : item.href.url}
|
||||
key={`${item.type}-${item.title}-${index}`}
|
||||
disabled={item.disabled}
|
||||
selected={item.selected}
|
||||
level={item.level}
|
||||
target={item.href.startsWith("#") ? undefined : "_blank"}
|
||||
target={
|
||||
typeof item.href === "string" ? undefined : item.href.target
|
||||
}
|
||||
icon={showIcons !== false ? item.icon : undefined}
|
||||
{...menu}
|
||||
>
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import { depths, s } from "@shared/styles";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import { fadeAndSlideUp } from "~/styles/animations";
|
||||
import Notifications from "./Notifications";
|
||||
|
||||
@@ -14,9 +15,14 @@ type Props = {
|
||||
|
||||
const NotificationsPopover: React.FC = ({ children }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { notifications } = useStores();
|
||||
const scrollableRef = React.useRef<HTMLDivElement>(null);
|
||||
const closeRef = React.useRef<HTMLButtonElement>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
void notifications.fetchPage({});
|
||||
}, [notifications]);
|
||||
|
||||
const handleRequestClose = React.useCallback(() => {
|
||||
if (closeRef.current) {
|
||||
closeRef.current.click();
|
||||
|
||||
@@ -25,7 +25,7 @@ const Error404 = () => {
|
||||
</Trans>
|
||||
</Empty>
|
||||
<Flex gap={8}>
|
||||
<Button action={navigateToHome} context={context} hideIcon>
|
||||
<Button action={navigateToHome} context={context} neutral hideIcon>
|
||||
{t("Home")}
|
||||
</Button>
|
||||
<Button action={navigateToSearch} context={context} neutral>
|
||||
|
||||
+2
-1
@@ -65,7 +65,7 @@ export type MenuInternalLink = {
|
||||
export type MenuExternalLink = {
|
||||
type: "link";
|
||||
title: React.ReactNode;
|
||||
href: string;
|
||||
href: string | { url: string; target?: string };
|
||||
visible?: boolean;
|
||||
selected?: boolean;
|
||||
disabled?: boolean;
|
||||
@@ -117,6 +117,7 @@ export type Action = {
|
||||
* instead. Errors will be caught and displayed to the user as a toast message.
|
||||
*/
|
||||
perform?: (context: ActionContext) => any;
|
||||
to?: string | { url: string; target?: string };
|
||||
children?: ((context: ActionContext) => Action[]) | Action[];
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -384,6 +384,6 @@
|
||||
"qs": "6.9.7",
|
||||
"prismjs": "1.30.0"
|
||||
},
|
||||
"version": "0.85.0",
|
||||
"version": "0.85.1",
|
||||
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||
}
|
||||
|
||||
@@ -97,4 +97,84 @@ describe("fetchOIDCConfiguration", () => {
|
||||
"Missing authorization_endpoint in OIDC configuration"
|
||||
);
|
||||
});
|
||||
|
||||
it("should handle issuer URL with subdirectory path", async () => {
|
||||
const mockConfig = {
|
||||
issuer: "https://auth.example.com/application/o/outline/",
|
||||
authorization_endpoint:
|
||||
"https://auth.example.com/application/o/outline/auth",
|
||||
token_endpoint: "https://auth.example.com/application/o/outline/token",
|
||||
userinfo_endpoint:
|
||||
"https://auth.example.com/application/o/outline/userinfo",
|
||||
};
|
||||
|
||||
fetchMock.mockResponseOnce(JSON.stringify(mockConfig));
|
||||
|
||||
const result = await fetchOIDCConfiguration(
|
||||
"https://auth.example.com/application/o/outline/"
|
||||
);
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
"https://auth.example.com/application/o/outline/.well-known/openid-configuration",
|
||||
expect.objectContaining({
|
||||
method: "GET",
|
||||
headers: expect.objectContaining({
|
||||
Accept: "application/json",
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
expect(result).toEqual(mockConfig);
|
||||
});
|
||||
|
||||
it("should handle issuer URL with subdirectory path without trailing slash", async () => {
|
||||
const mockConfig = {
|
||||
issuer: "https://auth.example.com/application/o/outline",
|
||||
authorization_endpoint:
|
||||
"https://auth.example.com/application/o/outline/auth",
|
||||
token_endpoint: "https://auth.example.com/application/o/outline/token",
|
||||
userinfo_endpoint:
|
||||
"https://auth.example.com/application/o/outline/userinfo",
|
||||
};
|
||||
|
||||
fetchMock.mockResponseOnce(JSON.stringify(mockConfig));
|
||||
|
||||
const result = await fetchOIDCConfiguration(
|
||||
"https://auth.example.com/application/o/outline"
|
||||
);
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
"https://auth.example.com/application/o/outline/.well-known/openid-configuration",
|
||||
expect.objectContaining({
|
||||
method: "GET",
|
||||
headers: expect.objectContaining({
|
||||
Accept: "application/json",
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
expect(result).toEqual(mockConfig);
|
||||
});
|
||||
|
||||
it("should handle issuer URL that already contains well-known path", async () => {
|
||||
const mockConfig = {
|
||||
issuer: "https://example.com",
|
||||
authorization_endpoint: "https://example.com/auth",
|
||||
token_endpoint: "https://example.com/token",
|
||||
userinfo_endpoint: "https://example.com/userinfo",
|
||||
};
|
||||
|
||||
fetchMock.mockResponseOnce(JSON.stringify(mockConfig));
|
||||
|
||||
const result = await fetchOIDCConfiguration(
|
||||
"https://example.com/.well-known/openid-configuration"
|
||||
);
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
"https://example.com/.well-known/openid-configuration",
|
||||
expect.any(Object)
|
||||
);
|
||||
|
||||
expect(result).toEqual(mockConfig);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,9 +25,24 @@ export async function fetchOIDCConfiguration(
|
||||
): Promise<OIDCConfiguration> {
|
||||
try {
|
||||
const wellKnownPath = "/.well-known/openid-configuration";
|
||||
const wellKnownUrl = issuerUrl.includes(wellKnownPath)
|
||||
? issuerUrl
|
||||
: new URL(wellKnownPath, issuerUrl).toString();
|
||||
|
||||
let wellKnownUrl: string;
|
||||
|
||||
// If the issuer URL already includes the well-known path, use it as-is
|
||||
if (issuerUrl.includes(wellKnownPath)) {
|
||||
wellKnownUrl = issuerUrl;
|
||||
} else {
|
||||
// Properly append well-known path to the issuer URL path
|
||||
const url = new URL(issuerUrl);
|
||||
// If pathname doesn't end with slash, append the full wellKnownPath (with leading slash)
|
||||
if (!url.pathname.endsWith("/")) {
|
||||
url.pathname += wellKnownPath;
|
||||
} else {
|
||||
// If pathname ends with slash, append wellKnownPath without leading slash
|
||||
url.pathname += wellKnownPath.substring(1);
|
||||
}
|
||||
wellKnownUrl = url.toString();
|
||||
}
|
||||
|
||||
Logger.info("plugins", `Fetching OIDC configuration from ${wellKnownUrl}`);
|
||||
|
||||
|
||||
@@ -19,6 +19,6 @@ export const TooManyConnections = {
|
||||
};
|
||||
|
||||
export const EditorUpdateError = {
|
||||
code: 5000,
|
||||
code: 4999,
|
||||
reason: "Editor Update Required",
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
const EDITOR_VERSION = "14.0.0";
|
||||
const EDITOR_VERSION = "15.0.0";
|
||||
|
||||
export default EDITOR_VERSION;
|
||||
|
||||
Reference in New Issue
Block a user