修改登录逻辑

This commit is contained in:
2026-07-06 15:54:27 +08:00
parent fe66794168
commit 53b1842de8
12 changed files with 198 additions and 28 deletions

View File

@@ -11,4 +11,16 @@ describe("AuthLoginPanel", () => {
expect(source).not.toContain("/api/auth/captcha");
expect(source).not.toContain("randomStr");
});
it("supports switching between normal and admin login pages", async () => {
const panelSource = await readFile(join(process.cwd(), "components", "auth-login-panel.tsx"), "utf8");
const loginPageSource = await readFile(join(process.cwd(), "app", "auth", "login", "page.tsx"), "utf8");
const adminPageSource = await readFile(join(process.cwd(), "app", "auth", "admin-login", "page.tsx"), "utf8").catch(() => "");
expect(panelSource).toContain("authMode");
expect(panelSource).toContain("alternateHref");
expect(loginPageSource).toContain("/auth/admin-login");
expect(adminPageSource).toContain('authMode="admin"');
expect(adminPageSource).toContain("/auth/login");
});
});

View File

@@ -79,6 +79,59 @@ describe("password auth route AgentBus compatibility", () => {
expect(seenBodies[0].has("code")).toBe(false);
expect(seenBodies[0].has("randomStr")).toBe(false);
});
it("uses the admin OAuth client for admin password login", async () => {
for (const [key, value] of Object.entries(baseEnv)) vi.stubEnv(key, value);
vi.stubEnv("ZHINIAN_ADMIN_AUTH_CLIENT_ID", "app");
vi.stubEnv("ZHINIAN_ADMIN_AUTH_CLIENT_SECRET", "app");
const { publicKey, privateKey } = generateKeyPairSync("rsa", { modulusLength: 2048 });
const jwk = publicKey.export({ format: "jwk" }) as TestJwk;
jwk.kid = "admin-key";
const accessToken = signJwt({
iss: baseEnv.ZHINIAN_AUTH_ISSUER,
sub: "admin",
user_id: "admin",
username: "admin",
client_id: "app",
scope: baseEnv.ZHINIAN_AUTH_SCOPE,
exp: Math.floor(Date.now() / 1000) + 600,
iat: Math.floor(Date.now() / 1000) - 10,
nbf: Math.floor(Date.now() / 1000) - 10
}, privateKey, "admin-key");
const seenAuthorizations: string[] = [];
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
const url = String(input);
if (url.endsWith("/oauth2/jwks")) {
return new Response(JSON.stringify({ keys: [jwk] }), { status: 200 });
}
if (url.endsWith("/oauth2/token")) {
const headers = init?.headers as Record<string, string> | undefined;
seenAuthorizations.push(headers?.Authorization || headers?.authorization || "");
return new Response(JSON.stringify({
access_token: accessToken,
token_type: "bearer",
expires_in: "3600"
}), { status: 200 });
}
return new Response("not found", { status: 404 });
});
const response = await POST(new Request("https://app.example.com/api/auth/password", {
method: "POST",
body: JSON.stringify({
username: "admin",
password: "123456",
authMode: "admin",
next: "/accounts"
})
}));
expect(response.status).toBe(200);
expect(seenAuthorizations).toEqual([
`Basic ${Buffer.from("app:app").toString("base64")}`
]);
});
});
function signJwt(payload: Record<string, unknown>, privateKey: KeyObject, kid: string): string {