feat: require current password when changing password, add zxcvbn strength check
Use PasswordChange model (requires current password) for users with existing passwords and PasswordSet for first-time setup. Add zxcvbn strength validation and current password field to credentials template. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
72a93984f2
commit
a65af90320
3 changed files with 137 additions and 6 deletions
|
|
@ -46,7 +46,7 @@ async def test_set_password_mismatch_returns_error(client: AsyncClient) -> None:
|
|||
token = await get_csrf_token(client)
|
||||
res = await client.post(
|
||||
"/manage/credentials/password",
|
||||
data={"password": "newpassword", "confirm": "different"},
|
||||
data={"current_password": "old", "password": "newpassword", "confirm": "different"},
|
||||
headers={"HX-Request": "true", "X-CSRF-Token": token},
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
|
@ -59,7 +59,7 @@ async def test_set_password_too_short_returns_error(client: AsyncClient) -> None
|
|||
token = await get_csrf_token(client)
|
||||
res = await client.post(
|
||||
"/manage/credentials/password",
|
||||
data={"password": "short", "confirm": "short"},
|
||||
data={"current_password": "old", "password": "short", "confirm": "short"},
|
||||
headers={"HX-Request": "true", "X-CSRF-Token": token},
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
|
@ -74,7 +74,7 @@ async def test_set_password_creates_or_replaces_password(client: AsyncClient) ->
|
|||
token = await get_csrf_token(client)
|
||||
res = await client.post(
|
||||
"/manage/credentials/password",
|
||||
data={"password": "newpassword123", "confirm": "newpassword123"},
|
||||
data={"current_password": "old", "password": "NewStr0ng!Pass99", "confirm": "NewStr0ng!Pass99"},
|
||||
headers={"HX-Request": "true", "X-CSRF-Token": token},
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
|
@ -83,7 +83,7 @@ async def test_set_password_creates_or_replaces_password(client: AsyncClient) ->
|
|||
updated = await cred_repo.get_password_by_user(userid)
|
||||
assert updated is not None
|
||||
svc = PasswordService(hasher=PasswordHasher(time_cost=1, memory_cost=8192))
|
||||
assert svc.verify(updated.password_hash, "newpassword123") is True
|
||||
assert svc.verify(updated.password_hash, "NewStr0ng!Pass99") is True
|
||||
|
||||
|
||||
async def test_delete_password_requires_session(client: AsyncClient) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue