63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
import { createUser, db, get, test } from "../helpers.ts";
|
|
import { assertEquals } from "@std/assert";
|
|
import { authenticate, authenticateMedia } from "../../lib/auth.ts";
|
|
|
|
test("authenticate: the role comes from the database, not the token", async () => {
|
|
const user = await createUser({ role: "user" });
|
|
db.prepare(`UPDATE users SET role = 'admin' WHERE id = ?;`).run(user.id);
|
|
assertEquals((await authenticate(user.token))?.role, "admin");
|
|
});
|
|
|
|
test("authenticate: a deleted user's token is refused", async () => {
|
|
const user = await createUser();
|
|
db.prepare(`DELETE FROM users WHERE id = ?;`).run(user.id);
|
|
assertEquals(await authenticate(user.token), null);
|
|
assertEquals((await get("/api/me", { auth: user.auth })).status, 401);
|
|
});
|
|
|
|
test("authenticate: tokens issued before tokens_valid_after are revoked", async () => {
|
|
const user = await createUser();
|
|
const future = new Date(Date.now() + 60_000).toISOString();
|
|
db.prepare(`UPDATE users SET tokens_valid_after = ? WHERE id = ?;`).run(
|
|
future,
|
|
user.id,
|
|
);
|
|
assertEquals(await authenticate(user.token), null);
|
|
assertEquals(await authenticateMedia(user.mediaToken), null);
|
|
// A token issued at the cutoff second or later passes.
|
|
const past = new Date(Date.now() - 60_000).toISOString();
|
|
db.prepare(`UPDATE users SET tokens_valid_after = ? WHERE id = ?;`).run(
|
|
past,
|
|
user.id,
|
|
);
|
|
assertEquals((await authenticate(user.token))?.userId, user.id);
|
|
});
|
|
|
|
test("authenticateMedia: takes a media token or a legacy session token", async () => {
|
|
const user = await createUser();
|
|
assertEquals(await authenticateMedia(user.mediaToken), user.id);
|
|
assertEquals(await authenticateMedia(user.token), user.id);
|
|
assertEquals(await authenticateMedia("garbage"), null);
|
|
});
|
|
|
|
test("optional auth: a missing or placeholder token is anonymous, a bad one is 401", async () => {
|
|
const owner = await createUser();
|
|
// A public listing that reads optional auth.
|
|
const path = `/api/users/@${owner.username}/dumps`;
|
|
assertEquals((await get(path)).status, 200);
|
|
for (const placeholder of ["Bearer undefined", "Bearer null", "Bearer "]) {
|
|
assertEquals(
|
|
(await get(path, { headers: { Authorization: placeholder } })).status,
|
|
200,
|
|
placeholder,
|
|
);
|
|
}
|
|
assertEquals(
|
|
(await get(path, { headers: { Authorization: "Basic abc" } })).status,
|
|
200,
|
|
);
|
|
const bad = await get(path, { headers: { Authorization: "Bearer nope" } });
|
|
assertEquals(bad.status, 401);
|
|
assertEquals(bad.error.code, "UNAUTHORIZED");
|
|
});
|