feat: improve API keys and build workflows

This commit is contained in:
2026-10-04 20:05:13 +00:00 Unverified
parent 62f2362a2e
commit e4623efe86
27 changed files with 2080 additions and 235 deletions
+24 -8
View File
@@ -191,15 +191,22 @@ function parseApiKey(secret: SecretObject): ApiKeyRecord | undefined {
"username",
"capabilities",
"workspace",
"expiresAt",
"disabled",
];
if (!secret.data || !hasOnlyKeys(secret.data, keys)) return;
if (
!secret.data ||
!hasOnlyKeys(
secret.data,
secret.data.expiresAt === undefined ? keys : [...keys, "expiresAt"],
)
)
return;
const id = decode(secret.data.id);
const tokenHash = decode(secret.data.tokenHash);
const username = decode(secret.data.username);
const capabilities = parseCapabilities(secret.data.capabilities);
const workspace = decode(secret.data.workspace);
const workspace =
secret.data.workspace === "" ? "" : decode(secret.data.workspace);
const expiresAt = decode(secret.data.expiresAt);
const disabled = decode(secret.data.disabled);
if (
@@ -207,7 +214,7 @@ function parseApiKey(secret: SecretObject): ApiKeyRecord | undefined {
!tokenHash ||
!username ||
!capabilities ||
!expiresAt ||
(secret.data.expiresAt !== undefined && !expiresAt) ||
(workspace !== "" && workspace === undefined) ||
(disabled !== "true" && disabled !== "false") ||
secret.metadata?.name !== objectName("api-key", tokenHash)
@@ -220,7 +227,7 @@ function parseApiKey(secret: SecretObject): ApiKeyRecord | undefined {
username,
capabilities,
...(workspace && { workspace }),
expiresAt,
...(expiresAt !== undefined && { expiresAt }),
disabled: disabled === "true",
});
} catch {
@@ -459,7 +466,12 @@ export class KubernetesAuthStore implements AuthStore {
const key = (await this.listSecrets("api-key"))
.map(parseApiKey)
.find((item): item is ApiKeyRecord => item?.tokenHash === tokenHash);
if (!key || key.disabled || Date.parse(key.expiresAt) <= Date.now()) return;
if (
!key ||
key.disabled ||
(key.expiresAt !== undefined && Date.parse(key.expiresAt) <= Date.now())
)
return;
const user = await this.getUser(key.username);
if (!user || user.disabled) return;
return key;
@@ -478,7 +490,9 @@ export class KubernetesAuthStore implements AuthStore {
username: normalized.username,
capabilities: JSON.stringify(normalized.capabilities),
workspace: normalized.workspace ?? "",
expiresAt: normalized.expiresAt,
...(normalized.expiresAt !== undefined && {
expiresAt: normalized.expiresAt,
}),
disabled: String(Boolean(normalized.disabled)),
},
);
@@ -505,7 +519,9 @@ export class KubernetesAuthStore implements AuthStore {
.map(parseApiKey)
.filter(
(key): key is ApiKeyRecord =>
key !== undefined && Date.parse(key.expiresAt) <= now,
key !== undefined &&
key.expiresAt !== undefined &&
Date.parse(key.expiresAt) <= now,
);
for (const key of expired)
await this.deleteSecret(objectName("api-key", key.tokenHash));