feat: add admin accounts and image templates

This commit is contained in:
inman
2026-07-03 11:25:25 +08:00
parent d98e58adfa
commit c3ea9f0eb1
61 changed files with 7016 additions and 199 deletions

View File

@@ -1,6 +1,13 @@
import { createSign, generateKeyPairSync, type KeyObject } from "node:crypto";
import { afterEach, describe, expect, it, vi } from "vitest";
import { createSessionCookieValue, parseSessionCookieValue, type AuthSession } from "@/lib/auth/session";
import {
chunkCookieValue,
chunkedCookieName,
createSessionCookieValue,
parseSessionCookieValue,
readChunkedCookieValue,
type AuthSession
} from "@/lib/auth/session";
import { type AuthRuntimeConfig } from "@/lib/auth/config";
import { clearJwksCacheForTests, userFromClaims, verifyAuthJwt } from "@/lib/server/auth/jwt";
@@ -38,6 +45,8 @@ describe("SSO auth helpers", () => {
version: 1,
issuedAt: 100,
expiresAt: 200,
accessToken: "access-token-1",
tokenType: "bearer",
user: {
id: "auth:customPC:1",
subject: "zhangsan",
@@ -51,12 +60,44 @@ describe("SSO auth helpers", () => {
const cookie = await createSessionCookieValue(session, authConfig.sessionSecret || "");
expect(await parseSessionCookieValue(cookie, authConfig.sessionSecret || "", 150)).toMatchObject({
accessToken: "access-token-1",
tokenType: "bearer",
user: { id: "auth:customPC:1", displayName: "张三" }
});
expect(await parseSessionCookieValue(`${cookie.slice(0, -1)}x`, authConfig.sessionSecret || "", 150)).toBeNull();
expect(await parseSessionCookieValue(cookie, authConfig.sessionSecret || "", 201)).toBeNull();
});
it("reassembles chunked session cookies for large auth payloads", async () => {
const session: AuthSession = {
version: 1,
issuedAt: 100,
expiresAt: 200,
accessToken: "token.".repeat(1200),
tokenType: "bearer",
user: {
id: "auth:customPC:big-user",
subject: "big-user",
username: "big-user",
displayName: "大权限账号",
clientId: "customPC",
authorities: Array.from({ length: 200 }, (_, index) => `sys_permission_${index}`),
scope: ["server"]
}
};
const cookie = await createSessionCookieValue(session, authConfig.sessionSecret || "");
const chunks = chunkCookieValue(cookie, 1000);
const chunkMap = new Map(chunks.map((chunk, index) => [chunkedCookieName("zhinian_session", index), chunk]));
const reassembled = readChunkedCookieValue("zhinian_session", (name) => chunkMap.get(name));
expect(chunks.length).toBeGreaterThan(1);
expect(reassembled).toBe(cookie);
expect(await parseSessionCookieValue(reassembled, authConfig.sessionSecret || "", 150)).toMatchObject({
accessToken: session.accessToken,
user: { username: "big-user" }
});
});
it("verifies RS256 JWTs from JWKS and maps stable owner ids", async () => {
const { publicKey, privateKey } = generateKeyPairSync("rsa", { modulusLength: 2048 });
const jwk = publicKey.export({ format: "jwk" }) as TestJwk;