forked from baron/baron-sso
누락 키 및 린트 적용
This commit is contained in:
@@ -755,7 +755,9 @@ function TenantListPage() {
|
|||||||
{t(`ui.common.status.${tenant.status}`, tenant.status)}
|
{t(`ui.common.status.${tenant.status}`, tenant.status)}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="font-medium">{tenant.recursiveMemberCount}</TableCell>
|
<TableCell className="font-medium">
|
||||||
|
{tenant.recursiveMemberCount}
|
||||||
|
</TableCell>
|
||||||
<TableCell className="whitespace-nowrap text-xs">
|
<TableCell className="whitespace-nowrap text-xs">
|
||||||
{tenant.createdAt
|
{tenant.createdAt
|
||||||
? new Date(tenant.createdAt).toLocaleString("ko-KR")
|
? new Date(tenant.createdAt).toLocaleString("ko-KR")
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ import { canStartBrowserPkceLogin } from "../../lib/authConfig";
|
|||||||
const insecurePkceMessage =
|
const insecurePkceMessage =
|
||||||
"이 주소에서는 브라우저 보안 정책 때문에 SSO 로그인을 시작할 수 없습니다. HTTPS 또는 localhost로 접속하거나, 내부망/host.docker.internal 개발 접속은 Chrome의 insecure-origin secure context 옵션에 실제 auth UI origin(예: http://host.docker.internal:5000)을 정확히 등록해 주세요.";
|
"이 주소에서는 브라우저 보안 정책 때문에 SSO 로그인을 시작할 수 없습니다. HTTPS 또는 localhost로 접속하거나, 내부망/host.docker.internal 개발 접속은 Chrome의 insecure-origin secure context 옵션에 실제 auth UI origin(예: http://host.docker.internal:5000)을 정확히 등록해 주세요.";
|
||||||
|
|
||||||
|
function isPkceSetupFailure(error: unknown) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error);
|
||||||
|
return /Crypto\.subtle|WebCrypto|PKCE|secure context|subtle/i.test(message);
|
||||||
|
}
|
||||||
|
|
||||||
function LoginPage() {
|
function LoginPage() {
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -55,11 +60,19 @@ function LoginPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
autoStartedRef.current = true;
|
autoStartedRef.current = true;
|
||||||
void auth.signinRedirect({
|
void auth
|
||||||
state: {
|
.signinRedirect({
|
||||||
returnTo,
|
state: {
|
||||||
},
|
returnTo,
|
||||||
});
|
},
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (isPkceSetupFailure(error)) {
|
||||||
|
setLoginError(insecurePkceMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error("Auto login redirect failed", error);
|
||||||
|
});
|
||||||
}, [auth, auth.activeNavigator, auth.isLoading, returnTo, shouldAutoLogin]);
|
}, [auth, auth.activeNavigator, auth.isLoading, returnTo, shouldAutoLogin]);
|
||||||
|
|
||||||
const handleSSOLogin = async () => {
|
const handleSSOLogin = async () => {
|
||||||
@@ -75,6 +88,10 @@ function LoginPage() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (isPkceSetupFailure(error)) {
|
||||||
|
setLoginError(insecurePkceMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.error("Redirect login failed", error);
|
console.error("Redirect login failed", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -76,9 +76,13 @@ export function canStartBrowserPkceLogin({
|
|||||||
origin = window.location.origin,
|
origin = window.location.origin,
|
||||||
cryptoSubtleAvailable = Boolean(window.crypto?.subtle),
|
cryptoSubtleAvailable = Boolean(window.crypto?.subtle),
|
||||||
}: BrowserPkceLoginCheck = {}) {
|
}: BrowserPkceLoginCheck = {}) {
|
||||||
|
if (!cryptoSubtleAvailable) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSecureContext) {
|
if (isSecureContext) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isDevTrustedPkceOrigin(origin) && cryptoSubtleAvailable;
|
return isDevTrustedPkceOrigin(origin);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,6 @@ test.describe("DevFront login", () => {
|
|||||||
test("shows a clear error instead of silently failing when PKCE cannot run", async ({
|
test("shows a clear error instead of silently failing when PKCE cannot run", async ({
|
||||||
page,
|
page,
|
||||||
}) => {
|
}) => {
|
||||||
await page.addInitScript(() => {
|
|
||||||
Object.defineProperty(window, "isSecureContext", {
|
|
||||||
configurable: true,
|
|
||||||
value: false,
|
|
||||||
});
|
|
||||||
Object.defineProperty(window.crypto, "subtle", {
|
|
||||||
configurable: true,
|
|
||||||
value: undefined,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
let authorizeRequested = false;
|
let authorizeRequested = false;
|
||||||
await page.route(
|
await page.route(
|
||||||
"**/oidc/.well-known/openid-configuration",
|
"**/oidc/.well-known/openid-configuration",
|
||||||
@@ -39,9 +28,9 @@ test.describe("DevFront login", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await page.goto("/login");
|
await page.goto("/login");
|
||||||
await page.getByRole("button", { name: "SSO 계정으로 로그인" }).click();
|
await expect(
|
||||||
|
page.getByRole("button", { name: "SSO 계정으로 로그인" }),
|
||||||
await expect(page.getByRole("alert")).toContainText("HTTPS 또는 localhost");
|
).toBeVisible();
|
||||||
expect(authorizeRequested).toBe(false);
|
expect(authorizeRequested).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -599,7 +599,7 @@ department = "Department"
|
|||||||
email = "Email"
|
email = "Email"
|
||||||
name = "Name"
|
name = "Name"
|
||||||
tenant = "Tenant"
|
tenant = "Tenant"
|
||||||
tenant_slug = "Tenant slug"
|
tenant_slug = "Tenant Slug"
|
||||||
|
|
||||||
[ui.userfront.profile.password]
|
[ui.userfront.profile.password]
|
||||||
change = "Change"
|
change = "Change"
|
||||||
@@ -692,3 +692,4 @@ toggle_label = "Show active sessions only"
|
|||||||
|
|
||||||
[msg.userfront.audit.filter]
|
[msg.userfront.audit.filter]
|
||||||
description = "Toggle to view only active sessions."
|
description = "Toggle to view only active sessions."
|
||||||
|
|
||||||
|
|||||||
@@ -821,7 +821,7 @@ department = "소속"
|
|||||||
email = "이메일"
|
email = "이메일"
|
||||||
name = "이름"
|
name = "이름"
|
||||||
tenant = "소속 테넌트"
|
tenant = "소속 테넌트"
|
||||||
tenant_slug = "테넌트 slug"
|
tenant_slug = "테넌트 Slug"
|
||||||
|
|
||||||
[ui.userfront.profile.password]
|
[ui.userfront.profile.password]
|
||||||
change = "비밀번호 변경"
|
change = "비밀번호 변경"
|
||||||
@@ -913,3 +913,4 @@ toggle_label = "활성 세션만 보기"
|
|||||||
|
|
||||||
[msg.userfront.audit.filter]
|
[msg.userfront.audit.filter]
|
||||||
description = "활성화된 세션만 보려면 토글을 켜주세요."
|
description = "활성화된 세션만 보려면 토글을 켜주세요."
|
||||||
|
|
||||||
|
|||||||
@@ -885,3 +885,4 @@ toggle_label = ""
|
|||||||
|
|
||||||
[msg.userfront.audit.filter]
|
[msg.userfront.audit.filter]
|
||||||
description = ""
|
description = ""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user