43 lines
1.5 KiB
TypeScript
43 lines
1.5 KiB
TypeScript
|
|
import assert from "node:assert/strict";
|
||
|
|
import { mkdtempSync } from "node:fs";
|
||
|
|
import { readFile } from "node:fs/promises";
|
||
|
|
import { tmpdir } from "node:os";
|
||
|
|
import { join } from "node:path";
|
||
|
|
import { test } from "node:test";
|
||
|
|
|
||
|
|
import { TokenStore } from "../src/tokens.ts";
|
||
|
|
|
||
|
|
test("pairing code round-trip mints a working device token", async () => {
|
||
|
|
const dir = mkdtempSync(join(tmpdir(), "tokens-"));
|
||
|
|
const store = new TokenStore(dir, 60_000);
|
||
|
|
|
||
|
|
const pairing = store.issuePairingCode("michal");
|
||
|
|
assert.match(pairing.code, /^[0-9a-f]{64}$/);
|
||
|
|
|
||
|
|
const redeemed = store.redeemPairingCode(pairing.code);
|
||
|
|
assert.ok(redeemed);
|
||
|
|
assert.equal(redeemed.username, "michal");
|
||
|
|
|
||
|
|
// Single use.
|
||
|
|
assert.equal(store.redeemPairingCode(pairing.code), undefined);
|
||
|
|
|
||
|
|
// The token authenticates, wrong tokens do not.
|
||
|
|
assert.equal(store.authenticate(redeemed.token), "michal");
|
||
|
|
assert.equal(store.authenticate("not-a-token"), undefined);
|
||
|
|
|
||
|
|
// Nothing on disk contains the plaintext token.
|
||
|
|
const persisted = await readFile(join(dir, "devices.json"), "utf8");
|
||
|
|
assert.ok(!persisted.includes(redeemed.token));
|
||
|
|
|
||
|
|
// A fresh store reads the same devices back.
|
||
|
|
const reloaded = new TokenStore(dir, 60_000);
|
||
|
|
assert.equal(reloaded.authenticate(redeemed.token), "michal");
|
||
|
|
});
|
||
|
|
|
||
|
|
test("expired pairing codes are refused", () => {
|
||
|
|
const dir = mkdtempSync(join(tmpdir(), "tokens-"));
|
||
|
|
const store = new TokenStore(dir, -1); // already expired at issue time
|
||
|
|
const pairing = store.issuePairingCode("michal");
|
||
|
|
assert.equal(store.redeemPairingCode(pairing.code), undefined);
|
||
|
|
});
|