mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
test(sessions): revoke by the public handle, and prove the row id is not a key
This commit is contained in:
1 parent
fd9603a578
commit
4bee263a59
1 file changed
+23
-6
@@ -5,12 +5,17 @@
|
||||
* Covers the DB-layer contracts the unit mocks can't pin:
|
||||
* - destroyOtherSessions keeps the current session, deletes the rest, revokes
|
||||
* native refresh tokens, and leaves API tokens untouched.
|
||||
* - destroySessionById is scoped to the owning user (no cross-user delete).
|
||||
* - destroySessionById is scoped to the owning user (no cross-user delete)
|
||||
* and takes the public handle, never the row id.
|
||||
* - the (userId, deviceHash) unique index enforces the login-alert dedupe.
|
||||
*/
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { destroyOtherSessions, destroySessionById } from "@/lib/auth/session";
|
||||
import {
|
||||
destroyOtherSessions,
|
||||
destroySessionById,
|
||||
sessionHandle,
|
||||
} from "@/lib/auth/session";
|
||||
import { getPrismaClient, truncateAllTables } from "./setup";
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -85,14 +90,26 @@ describe("destroySessionById", () => {
|
||||
data: { userId: other.id, expiresAt: new Date(Date.now() + 1e6) },
|
||||
});
|
||||
|
||||
// Cross-user attempt: owner tries to delete the intruder's session.
|
||||
expect(await destroySessionById(owner.id, otherSession.id)).toBe(false);
|
||||
// Cross-user attempt: owner presents the intruder's handle.
|
||||
expect(
|
||||
await destroySessionById(owner.id, sessionHandle(otherSession.id)),
|
||||
).toBe(false);
|
||||
expect(
|
||||
await prisma.session.findUnique({ where: { id: otherSession.id } }),
|
||||
).not.toBeNull();
|
||||
|
||||
// Owned delete succeeds.
|
||||
expect(await destroySessionById(owner.id, ownerSession.id)).toBe(true);
|
||||
// The row id is not an accepted key: a caller who somehow learned it
|
||||
// still cannot revoke with it, which is what keeps the id out of the
|
||||
// client's hands from being load-bearing in both directions.
|
||||
expect(await destroySessionById(owner.id, ownerSession.id)).toBe(false);
|
||||
expect(
|
||||
await prisma.session.findUnique({ where: { id: ownerSession.id } }),
|
||||
).not.toBeNull();
|
||||
|
||||
// Owned delete succeeds on the handle.
|
||||
expect(
|
||||
await destroySessionById(owner.id, sessionHandle(ownerSession.id)),
|
||||
).toBe(true);
|
||||
expect(
|
||||
await prisma.session.findUnique({ where: { id: ownerSession.id } }),
|
||||
).toBeNull();
|
||||
|
||||
Reference in new issue
Block a user