Add user authentication and role management
This commit is contained in:
@@ -8,8 +8,9 @@ test("builds the KOC LOOP product shell", async () => {
|
||||
readFile(new URL("../app/admin-app.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/layout.tsx", import.meta.url), "utf8"),
|
||||
]);
|
||||
assert.match(page, /requireChatGPTUser/);
|
||||
assert.match(page, /isAdminEmail/);
|
||||
assert.match(page, /getUserFromCookieHeader/);
|
||||
assert.match(page, /redirect\("\/login"\)/);
|
||||
assert.match(page, /currentUser=\{user\}/);
|
||||
assert.match(adminApp, /KOC LOOP/);
|
||||
assert.match(adminApp, /内容分发闭环/);
|
||||
assert.match(adminApp, /分发工作台/);
|
||||
@@ -250,6 +251,63 @@ test("exports complete task recovery data to Excel with embedded images", async
|
||||
assert.match(workbook, /oneCellAnchor/);
|
||||
});
|
||||
|
||||
test("provides simple username-password login and three server-enforced roles", async () => {
|
||||
const [
|
||||
adminApp,
|
||||
usersPage,
|
||||
loginPage,
|
||||
loginRoute,
|
||||
logoutRoute,
|
||||
usersRoute,
|
||||
auth,
|
||||
bootstrapRoute,
|
||||
resourceExportRoute,
|
||||
schema,
|
||||
runtimeSchema,
|
||||
migration,
|
||||
] = await Promise.all([
|
||||
readFile(new URL("../app/admin-app.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/users-page.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/login/page.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/api/auth/login/route.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/api/auth/logout/route.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/api/users/route.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../lib/user-auth.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/api/bootstrap/route.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/api/resources-export/route.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../db/schema.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../lib/mvp-db.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../drizzle/0007_fantastic_sentinels.sql", import.meta.url), "utf8"),
|
||||
]);
|
||||
|
||||
assert.match(loginPage, /登录账号/);
|
||||
assert.match(loginPage, /当前|管理员分配|账号和密码/);
|
||||
assert.match(loginRoute, /ensureInitialSuperAdmin/);
|
||||
assert.match(loginRoute, /verifyPassword/);
|
||||
assert.match(loginRoute, /Set-Cookie/);
|
||||
assert.match(logoutRoute, /deleteSession/);
|
||||
assert.match(logoutRoute, /clearSessionCookie/);
|
||||
assert.match(auth, /PBKDF2/);
|
||||
assert.match(auth, /HttpOnly/);
|
||||
assert.match(auth, /SameSite=Lax/);
|
||||
assert.match(auth, /SELECT id FROM users WHERE role = 'super_admin' LIMIT 1/);
|
||||
assert.match(usersRoute, /currentUser\.role !== "super_admin" && role !== "user"/);
|
||||
assert.match(usersRoute, /DELETE FROM auth_sessions WHERE user_id =/);
|
||||
assert.match(usersPage, /不开放注册和个人改密/);
|
||||
assert.match(usersPage, /普通用户/);
|
||||
assert.match(usersPage, /管理员/);
|
||||
assert.match(adminApp, /item\.key === "resources" && currentUser\.role === "user"/);
|
||||
assert.match(adminApp, /item\.key === "users" && !isManager/);
|
||||
assert.match(bootstrapRoute, /principal\.user\.role === "user"/);
|
||||
assert.match(bootstrapRoute, /accounts: \[\]/);
|
||||
assert.match(resourceExportRoute, /isManagerRequest/);
|
||||
assert.match(schema, /authSessions/);
|
||||
assert.match(schema, /users_single_super_admin_idx/);
|
||||
assert.match(runtimeSchema, /CREATE TABLE IF NOT EXISTS auth_sessions/);
|
||||
assert.match(migration, /CREATE TABLE `users`/);
|
||||
assert.match(migration, /users_single_super_admin_idx/);
|
||||
});
|
||||
|
||||
test("filters and exports the current KOC resource result set", async () => {
|
||||
const [adminApp, exportRoute, workbook] = await Promise.all([
|
||||
readFile(new URL("../app/admin-app.tsx", import.meta.url), "utf8"),
|
||||
@@ -267,7 +325,7 @@ test("filters and exports the current KOC resource result set", async () => {
|
||||
assert.match(exportRoute, /小红书号\/抖音号/);
|
||||
assert.match(exportRoute, /历史合作来源/);
|
||||
assert.match(exportRoute, /合作社资源 · 不可直联/);
|
||||
assert.match(exportRoute, /isAdminRequest/);
|
||||
assert.match(exportRoute, /isManagerRequest/);
|
||||
assert.match(workbook, /relationships\/hyperlink/);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user