forked from baron/baron-sso
ci: add code check badges and coverage reports
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
createBrowserRouter,
|
||||
Navigate,
|
||||
type RouteObject,
|
||||
createBrowserRouter,
|
||||
} from "react-router-dom";
|
||||
import AuthCallbackPage from "../features/auth/AuthCallbackPage";
|
||||
import AuthGuard from "../features/auth/AuthGuard";
|
||||
|
||||
@@ -13,12 +13,12 @@ import { useEffect, useRef, useState } from "react";
|
||||
import { useAuth } from "react-oidc-context";
|
||||
import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||
import {
|
||||
type ShellTranslator,
|
||||
applyShellTheme,
|
||||
buildShellProfileSummary,
|
||||
buildShellSessionStatus,
|
||||
readShellSessionExpiryEnabled,
|
||||
readShellTheme,
|
||||
type ShellTranslator,
|
||||
shellLayoutClasses,
|
||||
writeShellSessionExpiryEnabled,
|
||||
} from "../../../../common/shell";
|
||||
@@ -136,9 +136,12 @@ function AppLayout() {
|
||||
window.addEventListener(LOCALE_CHANGED_EVENT, rerenderDevelopmentShell);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener(LOCALE_CHANGED_EVENT, rerenderDevelopmentShell);
|
||||
window.removeEventListener(
|
||||
LOCALE_CHANGED_EVENT,
|
||||
rerenderDevelopmentShell,
|
||||
);
|
||||
};
|
||||
}, [isDevelopmentRuntime]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
@@ -251,7 +254,6 @@ function AppLayout() {
|
||||
auth.isAuthenticated,
|
||||
auth.isLoading,
|
||||
auth.user?.expires_at,
|
||||
isDevelopmentRuntime,
|
||||
isSessionExpiryEnabled,
|
||||
]);
|
||||
|
||||
|
||||
@@ -44,4 +44,4 @@ const AvatarFallback = React.forwardRef<
|
||||
));
|
||||
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
||||
|
||||
export { Avatar, AvatarImage, AvatarFallback };
|
||||
export { Avatar, AvatarFallback, AvatarImage };
|
||||
|
||||
@@ -50,9 +50,9 @@ function CardFooter({
|
||||
|
||||
export {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
CardDescription,
|
||||
CardContent,
|
||||
CardFooter,
|
||||
};
|
||||
|
||||
@@ -92,11 +92,11 @@ TableCaption.displayName = "TableCaption";
|
||||
|
||||
export {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableCaption,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { act } from "react";
|
||||
import { type Root, createRoot } from "react-dom/client";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
import { MemoryRouter, Route, Routes, useLocation } from "react-router-dom";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import AuthGuard from "./AuthGuard";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { act } from "react";
|
||||
import { type Root, createRoot } from "react-dom/client";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
import { MemoryRouter } from "react-router-dom";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import LoginPage from "./LoginPage";
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { ExternalLink, LogIn, ShieldHalf } from "lucide-react";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useAuth } from "react-oidc-context";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
|
||||
@@ -27,6 +27,11 @@ import { Label } from "../../components/ui/label";
|
||||
import { Switch } from "../../components/ui/switch";
|
||||
import { Textarea } from "../../components/ui/textarea";
|
||||
import { toast } from "../../components/ui/use-toast";
|
||||
import type {
|
||||
ClientStatus,
|
||||
ClientType,
|
||||
ClientUpsertRequest,
|
||||
} from "../../lib/devApi";
|
||||
import {
|
||||
createClient,
|
||||
deleteClient,
|
||||
@@ -36,11 +41,6 @@ import {
|
||||
updateClient,
|
||||
updateClientStatus,
|
||||
} from "../../lib/devApi";
|
||||
import type {
|
||||
ClientStatus,
|
||||
ClientType,
|
||||
ClientUpsertRequest,
|
||||
} from "../../lib/devApi";
|
||||
import { t } from "../../lib/i18n";
|
||||
import { cn } from "../../lib/utils";
|
||||
|
||||
@@ -1118,7 +1118,7 @@ function ClientGeneralPage() {
|
||||
</span>
|
||||
|
||||
{securityProfile === "pkce" && (
|
||||
<div
|
||||
<fieldset
|
||||
className="mt-4 pt-4 border-t border-primary/20 flex items-center justify-between"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onKeyDown={(e) => e.stopPropagation()}
|
||||
@@ -1145,7 +1145,7 @@ function ClientGeneralPage() {
|
||||
checked={headlessLoginEnabled}
|
||||
onCheckedChange={handleHeadlessToggle}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
)}
|
||||
</label>
|
||||
</div>
|
||||
@@ -1454,104 +1454,102 @@ function ClientGeneralPage() {
|
||||
</div>
|
||||
{currentHeadlessJwksCache.parsedKeys?.length ? (
|
||||
<div className="space-y-3">
|
||||
{currentHeadlessJwksCache.parsedKeys.map(
|
||||
(key, index) => {
|
||||
const normalizedAlgorithm = key.alg?.trim() ?? "";
|
||||
const isMissingAlgorithm =
|
||||
normalizedAlgorithm === "";
|
||||
const isUnsupportedAlgorithm =
|
||||
!isMissingAlgorithm &&
|
||||
!HEADLESS_LOGIN_ALLOWED_ALGORITHM_SET.has(
|
||||
normalizedAlgorithm,
|
||||
);
|
||||
{currentHeadlessJwksCache.parsedKeys.map((key) => {
|
||||
const normalizedAlgorithm = key.alg?.trim() ?? "";
|
||||
const isMissingAlgorithm =
|
||||
normalizedAlgorithm === "";
|
||||
const isUnsupportedAlgorithm =
|
||||
!isMissingAlgorithm &&
|
||||
!HEADLESS_LOGIN_ALLOWED_ALGORITHM_SET.has(
|
||||
normalizedAlgorithm,
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`${key.kid || "key"}-${index}`}
|
||||
className={cn(
|
||||
"rounded-xl border bg-muted/30 p-3",
|
||||
isUnsupportedAlgorithm || isMissingAlgorithm
|
||||
? "border-destructive/50 bg-destructive/5"
|
||||
: "border-border",
|
||||
)}
|
||||
>
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
KID
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.kid || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
KTY
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.kty || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
USE
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.use || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
ALG
|
||||
</p>
|
||||
<p
|
||||
className={cn(
|
||||
"break-all rounded-lg border bg-background px-3 py-2 font-mono text-[11px]",
|
||||
isUnsupportedAlgorithm ||
|
||||
isMissingAlgorithm
|
||||
? "border-destructive/50 text-destructive"
|
||||
: "border-border",
|
||||
)}
|
||||
>
|
||||
{key.alg ||
|
||||
t(
|
||||
"msg.dev.clients.general.public_key.cache.missing_algorithm_badge",
|
||||
"알고리즘 미선언",
|
||||
)}
|
||||
</p>
|
||||
{isMissingAlgorithm && (
|
||||
<p className="text-[11px] text-destructive">
|
||||
{t(
|
||||
"msg.dev.clients.general.public_key.cache.missing_algorithm_reason",
|
||||
"이 키는 `alg`가 비어 있어서 저장할 수 없습니다.",
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
{isUnsupportedAlgorithm && (
|
||||
<p className="text-[11px] text-destructive">
|
||||
{t(
|
||||
"msg.dev.clients.general.public_key.cache.unsupported_algorithm_reason",
|
||||
"이 알고리즘은 Headless Login에서 지원되지 않습니다.",
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 space-y-1">
|
||||
return (
|
||||
<div
|
||||
key={`${key.kid ?? "missing-kid"}-${key.kty ?? ""}-${key.alg ?? ""}-${key.n ?? ""}`}
|
||||
className={cn(
|
||||
"rounded-xl border bg-muted/30 p-3",
|
||||
isUnsupportedAlgorithm || isMissingAlgorithm
|
||||
? "border-destructive/50 bg-destructive/5"
|
||||
: "border-border",
|
||||
)}
|
||||
>
|
||||
<div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
{t(
|
||||
"ui.dev.clients.general.public_key.cache.parsed_key_n",
|
||||
"N",
|
||||
KID
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.kid || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
KTY
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.kty || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
USE
|
||||
</p>
|
||||
<p className="break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px]">
|
||||
{key.use || "-"}
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
ALG
|
||||
</p>
|
||||
<p
|
||||
className={cn(
|
||||
"break-all rounded-lg border bg-background px-3 py-2 font-mono text-[11px]",
|
||||
isUnsupportedAlgorithm ||
|
||||
isMissingAlgorithm
|
||||
? "border-destructive/50 text-destructive"
|
||||
: "border-border",
|
||||
)}
|
||||
>
|
||||
{key.alg ||
|
||||
t(
|
||||
"msg.dev.clients.general.public_key.cache.missing_algorithm_badge",
|
||||
"알고리즘 미선언",
|
||||
)}
|
||||
</p>
|
||||
<p className="min-h-16 break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px] leading-5">
|
||||
{key.n || "-"}
|
||||
</p>
|
||||
{isMissingAlgorithm && (
|
||||
<p className="text-[11px] text-destructive">
|
||||
{t(
|
||||
"msg.dev.clients.general.public_key.cache.missing_algorithm_reason",
|
||||
"이 키는 `alg`가 비어 있어서 저장할 수 없습니다.",
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
{isUnsupportedAlgorithm && (
|
||||
<p className="text-[11px] text-destructive">
|
||||
{t(
|
||||
"msg.dev.clients.general.public_key.cache.unsupported_algorithm_reason",
|
||||
"이 알고리즘은 Headless Login에서 지원되지 않습니다.",
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
)}
|
||||
<div className="mt-3 space-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase text-muted-foreground">
|
||||
{t(
|
||||
"ui.dev.clients.general.public_key.cache.parsed_key_n",
|
||||
"N",
|
||||
)}
|
||||
</p>
|
||||
<p className="min-h-16 break-all rounded-lg border border-border bg-background px-3 py-2 font-mono text-[11px] leading-5">
|
||||
{key.n || "-"}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
) : (
|
||||
<div className="rounded-lg border border-dashed border-border px-4 py-5 text-sm text-muted-foreground">
|
||||
|
||||
@@ -19,11 +19,11 @@ import {
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "../../../components/ui/table";
|
||||
import type { IdpConfig, IdpConfigCreateRequest } from "../../../lib/devApi";
|
||||
import {
|
||||
createIdpConfigForClient,
|
||||
listIdpConfigsForClient,
|
||||
} from "../../../lib/devApi";
|
||||
import type { IdpConfig, IdpConfigCreateRequest } from "../../../lib/devApi";
|
||||
import { t } from "../../../lib/i18n";
|
||||
|
||||
// Proper Modal Component with Form
|
||||
@@ -177,9 +177,16 @@ const CreateIdpModal = ({
|
||||
};
|
||||
|
||||
export function ClientFederationPage() {
|
||||
const { id: clientId } = useParams<{ id: string }>();
|
||||
const { id: clientIdParam } = useParams<{ id: string }>();
|
||||
const clientId = clientIdParam ?? "";
|
||||
const [isCreateModalOpen, setCreateModalOpen] = useState(false);
|
||||
|
||||
const { data, isLoading, error } = useQuery({
|
||||
queryKey: ["idpConfigs", clientId],
|
||||
queryFn: () => listIdpConfigsForClient(clientId),
|
||||
enabled: clientId.length > 0,
|
||||
});
|
||||
|
||||
if (!clientId) {
|
||||
return (
|
||||
<div className="p-8 text-center text-destructive">
|
||||
@@ -188,11 +195,6 @@ export function ClientFederationPage() {
|
||||
);
|
||||
}
|
||||
|
||||
const { data, isLoading, error } = useQuery({
|
||||
queryKey: ["idpConfigs", clientId],
|
||||
queryFn: () => listIdpConfigsForClient(clientId),
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="space-y-6 p-1">
|
||||
<header className="flex flex-wrap items-center justify-between gap-4">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { TenantSummary, UserSummary } from "../../lib/adminApi";
|
||||
import { type TenantNode, buildTenantFullTree } from "../../lib/tenantTree";
|
||||
import { buildTenantFullTree, type TenantNode } from "../../lib/tenantTree";
|
||||
import { orderHanmacFamilyChildren } from "./hanmacFamilyOrder";
|
||||
import type { OrgPickerTreeNode } from "./pickerTypes";
|
||||
import { filterTenantsByVisibility } from "./tenantVisibility";
|
||||
|
||||
@@ -16,9 +16,7 @@ describe("org chart rank priority", () => {
|
||||
|
||||
it("orders executive and research ranks with shared priority weights", () => {
|
||||
expect(getOrgRankWeight("사장")).toBeLessThan(getOrgRankWeight("부사장"));
|
||||
expect(getOrgRankWeight("전무이사")).toBeLessThan(
|
||||
getOrgRankWeight("상무"),
|
||||
);
|
||||
expect(getOrgRankWeight("전무이사")).toBeLessThan(getOrgRankWeight("상무"));
|
||||
expect(getOrgRankWeight("수석연구원")).toBeLessThan(
|
||||
getOrgRankWeight("책임"),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
type OrgNode,
|
||||
buildOrgSelectionOptions,
|
||||
buildUsersMap,
|
||||
clampScale,
|
||||
@@ -9,6 +8,7 @@ import {
|
||||
getOrgNodeHeaderFill,
|
||||
getSemanticZoomMode,
|
||||
layoutForest,
|
||||
type OrgNode,
|
||||
} from "./OrgChartPage";
|
||||
|
||||
function orgNode(id: string, children: OrgNode[] = [], level = 0): OrgNode {
|
||||
@@ -137,7 +137,9 @@ describe("org chart layout", () => {
|
||||
],
|
||||
new Set(),
|
||||
);
|
||||
const shortNode = shortLayout.nodes.find((item) => item.node.id === "short");
|
||||
const shortNode = shortLayout.nodes.find(
|
||||
(item) => item.node.id === "short",
|
||||
);
|
||||
const longNode = longLayout.nodes.find((item) => item.node.id === "long");
|
||||
|
||||
expect(shortNode?.width).toBeLessThan(320);
|
||||
@@ -472,16 +474,31 @@ describe("org chart layout", () => {
|
||||
"visible-parent",
|
||||
);
|
||||
const internalOrg = {
|
||||
...tenantNode("internal-org", "ORGANIZATION", "내부 조직", "internal-org"),
|
||||
...tenantNode(
|
||||
"internal-org",
|
||||
"ORGANIZATION",
|
||||
"내부 조직",
|
||||
"internal-org",
|
||||
),
|
||||
parentId: "visible-parent",
|
||||
config: { visibility: "internal" },
|
||||
};
|
||||
const internalChild = {
|
||||
...tenantNode("internal-child", "ORGANIZATION", "내부 하위", "internal-child"),
|
||||
...tenantNode(
|
||||
"internal-child",
|
||||
"ORGANIZATION",
|
||||
"내부 하위",
|
||||
"internal-child",
|
||||
),
|
||||
parentId: "internal-org",
|
||||
};
|
||||
const privateOrg = {
|
||||
...tenantNode("private-org", "ORGANIZATION", "비공개 조직", "private-org"),
|
||||
...tenantNode(
|
||||
"private-org",
|
||||
"ORGANIZATION",
|
||||
"비공개 조직",
|
||||
"private-org",
|
||||
),
|
||||
parentId: "visible-parent",
|
||||
config: { visibility: "private" },
|
||||
};
|
||||
|
||||
@@ -3,19 +3,19 @@ import type { Node as ReactFlowNode } from "@xyflow/react";
|
||||
import * as React from "react";
|
||||
import { useLocation, useParams } from "react-router-dom";
|
||||
import {
|
||||
type TenantSummary,
|
||||
type UserSummary,
|
||||
fetchAllTenants,
|
||||
fetchPublicOrgChart,
|
||||
fetchUsers,
|
||||
type TenantSummary,
|
||||
type UserSummary,
|
||||
} from "../../../lib/adminApi";
|
||||
import { type TenantNode, buildTenantFullTree } from "../../../lib/tenantTree";
|
||||
import { buildTenantFullTree, type TenantNode } from "../../../lib/tenantTree";
|
||||
import {
|
||||
orderHanmacFamilyChildren,
|
||||
orderHanmacFamilyTenants,
|
||||
} from "../hanmacFamilyOrder";
|
||||
import { filterTenantsByVisibility, getOrgUnitType } from "../tenantVisibility";
|
||||
import { getOrgRankWeight } from "../rankPriority";
|
||||
import { filterTenantsByVisibility, getOrgUnitType } from "../tenantVisibility";
|
||||
import { getOrgChartUserDisplayName, getUserOrgProfile } from "../userDisplay";
|
||||
|
||||
export type OrgNode = {
|
||||
@@ -160,7 +160,7 @@ function getComplementaryColor(hexColor: string) {
|
||||
function getDisplayTextWidthUnit(value: string) {
|
||||
return Array.from(value).reduce((sum, char) => {
|
||||
if (char === " ") return sum + 0.4;
|
||||
if (/^[\x00-\x7f]$/.test(char)) return sum + 0.55;
|
||||
if (char.charCodeAt(0) <= 0x7f) return sum + 0.55;
|
||||
return sum + 1;
|
||||
}, 0);
|
||||
}
|
||||
@@ -206,7 +206,7 @@ export function getMemberGridMetrics(
|
||||
? NODE_WIDTH
|
||||
: Math.max(
|
||||
NODE_WIDTH,
|
||||
NODE_PADDING_Y * 2 +
|
||||
NODE_PADDING_Y * 2 +
|
||||
columnCount * memberColumnWidth +
|
||||
(columnCount - 1) * MEMBER_COLUMN_GAP,
|
||||
);
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as React from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import {
|
||||
buildOrgPickerEmbedSrc,
|
||||
type OrgPickerEmbedOptions,
|
||||
type OrgPickerMode,
|
||||
type OrgPickerSelectableType,
|
||||
buildOrgPickerEmbedSrc,
|
||||
parseOrgPickerEmbedOptions,
|
||||
} from "../pickerTypes";
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ import { Button } from "../../../components/ui/button";
|
||||
import { fetchAllTenants, fetchUsers } from "../../../lib/adminApi";
|
||||
import { buildOrgPickerTree, flattenDescendants } from "../pickerTree";
|
||||
import {
|
||||
buildOrgPickerEmbedSrc,
|
||||
nodeKey,
|
||||
type OrgPickerEmbedOptions,
|
||||
type OrgPickerMode,
|
||||
type OrgPickerResult,
|
||||
type OrgPickerSelectableType,
|
||||
type OrgPickerSelection,
|
||||
type OrgPickerTreeNode,
|
||||
buildOrgPickerEmbedSrc,
|
||||
nodeKey,
|
||||
parseOrgPickerEmbedOptions,
|
||||
parseOrgPickerMode,
|
||||
parseOrgPickerSelectableType,
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { UserSummary } from "../../lib/adminApi";
|
||||
import {
|
||||
getOrgChartUserDisplayName,
|
||||
getUserOrgProfile,
|
||||
} from "./userDisplay";
|
||||
import { getOrgChartUserDisplayName, getUserOrgProfile } from "./userDisplay";
|
||||
|
||||
function user(overrides: Partial<UserSummary>): UserSummary {
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import axios from "axios";
|
||||
import { shouldStartLoginRedirect } from "../../../common/core/auth";
|
||||
import {
|
||||
shouldSuppressDevelopmentSessionRedirect,
|
||||
} from "../../../common/core/session";
|
||||
import { shouldSuppressDevelopmentSessionRedirect } from "../../../common/core/session";
|
||||
import { userManager } from "./auth";
|
||||
|
||||
let isRedirectingToLogin = false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
ORGFRONT_AUTH_CALLBACK_PATH,
|
||||
buildOrgFrontAuthRedirectUris,
|
||||
ORGFRONT_AUTH_CALLBACK_PATH,
|
||||
resolveOrgFrontPublicOrigin,
|
||||
} from "./authConfig";
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
type OrgContextResponse,
|
||||
buildOrgChartModel,
|
||||
createOrgContextClient,
|
||||
type OrgContextResponse,
|
||||
renderOrgChart,
|
||||
renderOrgPicker,
|
||||
} from "./index";
|
||||
|
||||
Reference in New Issue
Block a user