mirror of
https://github.com/tale/headplane.git
synced 2026-07-27 00:08:14 +00:00
0512565f8e
Apparently I didn't use my brain cells and rely on the /version endpoint that Headscale has exposed since 0.26 (our lowest supported version). Switching to that significantly simplifies the API surface.
142 lines
5.2 KiB
TypeScript
142 lines
5.2 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
|
|
import { getBootstrapClient, getRuntimeClient, HS_VERSIONS } from "../setup/env";
|
|
|
|
describe.sequential.for(HS_VERSIONS)("Headscale %s: Pre-auth Keys", (version) => {
|
|
test("pre-auth keys can be created", async () => {
|
|
const client = await getRuntimeClient(version);
|
|
const preAuthKeyUser = await client.users.create({ name: "preauthkeyuser@" });
|
|
expect(preAuthKeyUser).toBeDefined();
|
|
expect(preAuthKeyUser.name).toBe("preauthkeyuser@");
|
|
|
|
const expiry = new Date(Date.now() + 3600 * 1000);
|
|
const preAuthKey = await client.preAuthKeys.create({
|
|
user: preAuthKeyUser.id,
|
|
ephemeral: false,
|
|
reusable: false,
|
|
expiration: expiry,
|
|
aclTags: null,
|
|
});
|
|
|
|
expect(preAuthKey).toBeDefined();
|
|
expect(preAuthKey.user?.id).toBe(preAuthKeyUser.id);
|
|
expect(preAuthKey.ephemeral).toBe(false);
|
|
expect(preAuthKey.reusable).toBe(false);
|
|
expect(preAuthKey.aclTags).toEqual([]);
|
|
expect(new Date(preAuthKey.expiration).getTime()).toBeCloseTo(expiry.getTime(), -2);
|
|
});
|
|
|
|
test("pre-auth keys can be created with ACL tags", async () => {
|
|
const client = await getRuntimeClient(version);
|
|
const [preAuthKeyUser] = await client.users.list({ name: "preauthkeyuser@" });
|
|
expect(preAuthKeyUser).toBeDefined();
|
|
expect(preAuthKeyUser.name).toBe("preauthkeyuser@");
|
|
|
|
const aclTags = ["tag:test1", "tag:test2"];
|
|
const preAuthKey = await client.preAuthKeys.create({
|
|
user: preAuthKeyUser.id,
|
|
ephemeral: true,
|
|
reusable: true,
|
|
expiration: null,
|
|
aclTags,
|
|
});
|
|
|
|
expect(preAuthKey).toBeDefined();
|
|
expect(preAuthKey.user?.id).toBe(preAuthKeyUser.id);
|
|
expect(preAuthKey.ephemeral).toBe(true);
|
|
expect(preAuthKey.reusable).toBe(true);
|
|
expect(preAuthKey.aclTags.sort()).toEqual(aclTags.sort());
|
|
});
|
|
|
|
test("tag-only pre-auth keys (0.28+)", async (context) => {
|
|
const bootstrap = await getBootstrapClient(version);
|
|
if (!bootstrap.capabilities.preAuthKeysHaveStableIds) {
|
|
context.skip();
|
|
}
|
|
|
|
const client = await getRuntimeClient(version);
|
|
const aclTags = ["tag:server", "tag:prod"];
|
|
const preAuthKey = await client.preAuthKeys.create({
|
|
user: null,
|
|
ephemeral: false,
|
|
reusable: true,
|
|
expiration: null,
|
|
aclTags,
|
|
});
|
|
|
|
expect(preAuthKey).toBeDefined();
|
|
expect(preAuthKey.user).toBeNull();
|
|
expect(preAuthKey.ephemeral).toBe(false);
|
|
expect(preAuthKey.reusable).toBe(true);
|
|
expect(preAuthKey.aclTags.sort()).toEqual(aclTags.sort());
|
|
});
|
|
|
|
test("pre-auth keys can be listed", async () => {
|
|
const client = await getRuntimeClient(version);
|
|
const [preAuthKeyUser] = await client.users.list({ name: "preauthkeyuser@" });
|
|
expect(preAuthKeyUser).toBeDefined();
|
|
expect(preAuthKeyUser.name).toBe("preauthkeyuser@");
|
|
|
|
const preAuthKeys = await client.preAuthKeys.listForUser(preAuthKeyUser.id);
|
|
expect(Array.isArray(preAuthKeys)).toBe(true);
|
|
expect(preAuthKeys.length).toBeGreaterThanOrEqual(2);
|
|
});
|
|
|
|
test("all pre-auth keys can be listed without user filter (0.28+)", async (context) => {
|
|
const bootstrap = await getBootstrapClient(version);
|
|
if (!bootstrap.capabilities.preAuthKeysHaveStableIds) {
|
|
context.skip();
|
|
}
|
|
|
|
const client = await getRuntimeClient(version);
|
|
const [preAuthKeyUser] = await client.users.list({ name: "preauthkeyuser@" });
|
|
expect(preAuthKeyUser).toBeDefined();
|
|
|
|
const allKeys = await client.preAuthKeys.listAll!();
|
|
expect(Array.isArray(allKeys)).toBe(true);
|
|
expect(allKeys.length).toBeGreaterThanOrEqual(2);
|
|
|
|
const userSpecificKeys = await client.preAuthKeys.listForUser(preAuthKeyUser.id);
|
|
for (const userKey of userSpecificKeys) {
|
|
const found = allKeys.find((k) => k.key === userKey.key);
|
|
expect(found).toBeDefined();
|
|
}
|
|
});
|
|
|
|
test("listAll returns keys with correct structure (0.28+)", async (context) => {
|
|
const bootstrap = await getBootstrapClient(version);
|
|
if (!bootstrap.capabilities.preAuthKeysHaveStableIds) {
|
|
context.skip();
|
|
}
|
|
|
|
const client = await getRuntimeClient(version);
|
|
const allKeys = await client.preAuthKeys.listAll!();
|
|
|
|
for (const key of allKeys) {
|
|
expect(key.id).toBeDefined();
|
|
expect(key.key).toBeDefined();
|
|
expect(typeof key.reusable).toBe("boolean");
|
|
expect(typeof key.ephemeral).toBe("boolean");
|
|
expect(typeof key.used).toBe("boolean");
|
|
expect(key.expiration).toBeDefined();
|
|
expect(key.createdAt).toBeDefined();
|
|
}
|
|
});
|
|
|
|
test("pre-auth keys can be expired", async () => {
|
|
const client = await getRuntimeClient(version);
|
|
const [preAuthKeyUser] = await client.users.list({ name: "preauthkeyuser@" });
|
|
expect(preAuthKeyUser).toBeDefined();
|
|
expect(preAuthKeyUser.name).toBe("preauthkeyuser@");
|
|
|
|
const preAuthKeys = await client.preAuthKeys.listForUser(preAuthKeyUser.id);
|
|
expect(preAuthKeys.length).toBeGreaterThanOrEqual(2);
|
|
const preAuthKeyToExpire = preAuthKeys[0];
|
|
await client.preAuthKeys.expire(preAuthKeyToExpire);
|
|
|
|
const preAuthKeysAfterExpire = await client.preAuthKeys.listForUser(preAuthKeyUser.id);
|
|
const expiredKey = preAuthKeysAfterExpire.find((key) => key.key === preAuthKeyToExpire.key);
|
|
expect(expiredKey).toBeDefined();
|
|
});
|
|
});
|