feat(webui): add user-management validation helpers

This commit is contained in:
m4
2026-08-12 16:45:43 +08:00
parent 3f6730c9e5
commit 68179dd46e
2 changed files with 75 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
import { describe, expect, it } from "vitest";
import {
isValidPassword,
isValidUsername,
otherRole,
} from "./userManagement";
describe("isValidUsername", () => {
it("accepts simple names", () => {
expect(isValidUsername("alice")).toBe(true);
expect(isValidUsername("A1_b-c.d")).toBe(true);
});
it("rejects empty and overlong names", () => {
expect(isValidUsername("")).toBe(false);
expect(isValidUsername("a".repeat(65))).toBe(false);
});
it("rejects names starting with a non-alphanumeric", () => {
expect(isValidUsername("-alice")).toBe(false);
expect(isValidUsername(".alice")).toBe(false);
});
it("rejects illegal characters", () => {
expect(isValidUsername("al ice")).toBe(false);
expect(isValidUsername("alice!")).toBe(false);
expect(isValidUsername("爱丽丝")).toBe(false);
});
});
describe("isValidPassword", () => {
it("requires at least 8 characters", () => {
expect(isValidPassword("1234567")).toBe(false);
expect(isValidPassword("12345678")).toBe(true);
});
it("rejects passwords over 256 characters", () => {
expect(isValidPassword("x".repeat(256))).toBe(true);
expect(isValidPassword("x".repeat(257))).toBe(false);
});
});
describe("otherRole", () => {
it("flips admin and user", () => {
expect(otherRole("admin")).toBe("user");
expect(otherRole("user")).toBe("admin");
});
});
+27
View File
@@ -0,0 +1,27 @@
export const USERNAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
export const PASSWORD_MIN_LENGTH = 8;
export const PASSWORD_MAX_LENGTH = 256;
export type ManagedUserRole = "admin" | "user";
export interface ManagedUser {
username: string;
role: ManagedUserRole;
createdAt: string;
updatedAt: string;
}
export function isValidUsername(username: string): boolean {
return USERNAME_PATTERN.test(username);
}
export function isValidPassword(password: string): boolean {
return (
password.length >= PASSWORD_MIN_LENGTH &&
password.length <= PASSWORD_MAX_LENGTH
);
}
export function otherRole(role: ManagedUserRole): ManagedUserRole {
return role === "admin" ? "user" : "admin";
}