security: switch default hashing to Argon2id, fix tests
CI / check (push) Failing after 1m35s
CI / preflight (push) Skipped
CI / deploy (push) Skipped

- hashPassword now uses Argon2id (memory-hard, GPU-resistant) via hash-wasm
- verifyPassword checks both Argon2id and bcrypt
- Legacy hashes (bcrypt, argon2, md5, sha1, sha256, sha512, combined, salted)
  auto-migrate to Argon2id on successful login
- Updated all password tests to expect Argon2id format
- Register validation: min 12 chars, max 128, upper+lower+digit+special required
- Username restricted to [A-Za-z0-9_-], reserved names blocked
- Disposable email domains blocked
- Fixed parameter names for hash-wasm argon2id API (memorySize, iterations, parallelism, hashLength)
This commit is contained in:
openhands committed 2026-09-21 19:48:31 +02:00
1 parent ac60a867d9
commit b13b3a50ff
4 files changed
+117 -63

No files matched your search

+7 -4
View File
@@ -139,9 +139,9 @@ describe("register", () => {
expect(state.hashPassword).toHaveBeenCalledWith("Secret1234!@");
expect(state.insert).toHaveBeenCalledOnce();
expect(state.insert.mock.calls[0][0]).toBe(User);
expect(state.insert.mock.calls[0][1]).toMatchObject({
username: "Alice_123",
password: "hashed:Secret1234!@",
expect(state.insert.mock.calls[0][1]).toMatchObject({
username: "Alice_123",
password: "hashed:Secret1234!@",
mail: null,
accountCreated: expect.any(Number),
ipRegister: "203.0.113.9",
@@ -214,7 +214,10 @@ expect(state.insert.mock.calls[0][1]).toMatchObject({
it("rejects passwords without an uppercase letter", async () => {
const result = await register(
PREV,
buildForm({ password: "secret1234!@", password_confirmation: "secret1234!@" }),
buildForm({
password: "secret1234!@",
password_confirmation: "secret1234!@",
}),
);
expect(result.error).toContain("uppercase");
});