mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-20 22:22:57 +03:00
Remove duplicate lowercase db-apikeys-crud.test.ts from tracking (#3125)
* remove duplicate lowercase db-apikeys-crud.test.ts from tracking * Changed redirecURI for google OAuth * revert: keep Google OAuth redirect on 127.0.0.1 (out-of-scope change) This hotfix's purpose is removing the duplicate lowercase db-apikeys-crud.test.ts. The 127.0.0.1 -> localhost OAuth redirect change is unrelated and reverses a documented decision (Google native-app handoff prefers loopback IP; localhost can resolve to ::1 and hit firewall/name-resolution edge cases). Keeping only the test-file removal. --------- Co-authored-by: juandisay <juandisay@example.com> Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
This commit is contained in:
@@ -1,188 +0,0 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-db-apikeys-"));
|
||||
process.env.DATA_DIR = TEST_DATA_DIR;
|
||||
process.env.API_KEY_SECRET = process.env.API_KEY_SECRET || "task-303-api-key-secret";
|
||||
|
||||
const core = await import("../../src/lib/db/core.ts");
|
||||
const apiKeysDb = await import("../../src/lib/db/apiKeys.ts");
|
||||
|
||||
async function resetStorage() {
|
||||
core.resetDbInstance();
|
||||
apiKeysDb.resetApiKeyState();
|
||||
|
||||
for (let attempt = 0; attempt < 10; attempt++) {
|
||||
try {
|
||||
if (fs.existsSync(TEST_DATA_DIR)) {
|
||||
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
|
||||
}
|
||||
break;
|
||||
} catch (error: any) {
|
||||
if ((error?.code === "EBUSY" || error?.code === "EPERM") && attempt < 9) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 50 * (attempt + 1)));
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
test.beforeEach(async () => {
|
||||
await resetStorage();
|
||||
});
|
||||
|
||||
test.after(async () => {
|
||||
core.resetDbInstance();
|
||||
apiKeysDb.resetApiKeyState();
|
||||
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test("createApiKey requires machineId and returns a persisted key with defaults", async () => {
|
||||
await assert.rejects(
|
||||
() => apiKeysDb.createApiKey("missing-machine", ""),
|
||||
/machineId is required/
|
||||
);
|
||||
|
||||
const created = await apiKeysDb.createApiKey("Primary Key", "machine-303");
|
||||
const allKeys = await apiKeysDb.getApiKeys();
|
||||
const byId = await apiKeysDb.getApiKeyById(created.id);
|
||||
|
||||
assert.match(created.key, /^sk-machine-303-/);
|
||||
assert.equal(allKeys.length, 1);
|
||||
assert.equal(allKeys[0].name, "Primary Key");
|
||||
assert.deepEqual(allKeys[0].allowedModels, []);
|
||||
assert.deepEqual(byId.allowedConnections, []);
|
||||
assert.equal(byId.noLog, false);
|
||||
assert.equal(byId.autoResolve, false);
|
||||
assert.equal(byId.isActive, true);
|
||||
assert.equal(byId.maxSessions, 0);
|
||||
assert.equal(byId.streamDefaultMode, "legacy");
|
||||
});
|
||||
|
||||
test("updateApiKeyPermissions persists settings, schedule and rate limits", async () => {
|
||||
const created = await apiKeysDb.createApiKey("Scoped Key", "machine-303");
|
||||
const schedule = {
|
||||
enabled: true,
|
||||
from: "09:00",
|
||||
until: "18:00",
|
||||
days: [1, 2, 3, 4, 5],
|
||||
tz: "America/Sao_Paulo",
|
||||
};
|
||||
|
||||
const updated = await apiKeysDb.updateApiKeyPermissions(created.id, {
|
||||
name: "Scoped Key v2",
|
||||
allowedModels: ["openai/*", "anthropic/claude-*"],
|
||||
allowedCombos: ["fast-chat", "combo/reasoning"],
|
||||
allowedConnections: ["550e8400-e29b-41d4-a716-446655440000"],
|
||||
noLog: true,
|
||||
autoResolve: true,
|
||||
isActive: false,
|
||||
accessSchedule: schedule,
|
||||
maxRequestsPerDay: 1000,
|
||||
maxRequestsPerMinute: 15,
|
||||
throttleDelayMs: 250,
|
||||
maxSessions: -3,
|
||||
streamDefaultMode: "json",
|
||||
});
|
||||
const row = await apiKeysDb.getApiKeyById(created.id);
|
||||
const metadata = await apiKeysDb.getApiKeyMetadata(created.key);
|
||||
|
||||
assert.equal(updated, true);
|
||||
assert.equal(row.name, "Scoped Key v2");
|
||||
assert.deepEqual(row.allowedModels, ["openai/*", "anthropic/claude-*"]);
|
||||
assert.deepEqual(row.allowedCombos, ["fast-chat", "combo/reasoning"]);
|
||||
assert.deepEqual(row.allowedConnections, ["550e8400-e29b-41d4-a716-446655440000"]);
|
||||
assert.equal(row.noLog, true);
|
||||
assert.equal(row.autoResolve, true);
|
||||
assert.equal(row.isActive, false);
|
||||
assert.deepEqual(row.accessSchedule, schedule);
|
||||
assert.equal(metadata.maxRequestsPerDay, 1000);
|
||||
assert.equal(metadata.maxRequestsPerMinute, 15);
|
||||
assert.equal(metadata.throttleDelayMs, 250);
|
||||
assert.equal(metadata.maxSessions, 0);
|
||||
assert.equal(row.streamDefaultMode, "json");
|
||||
assert.equal(metadata.streamDefaultMode, "json");
|
||||
});
|
||||
|
||||
test("validateApiKey and deleteApiKey stay consistent after cache invalidation", async () => {
|
||||
const created = await apiKeysDb.createApiKey("Delete Me", "machine-303");
|
||||
|
||||
assert.equal(await apiKeysDb.validateApiKey(created.key), true);
|
||||
assert.equal(await apiKeysDb.deleteApiKey("missing-id"), false);
|
||||
assert.equal(await apiKeysDb.deleteApiKey(created.id), true);
|
||||
assert.equal(await apiKeysDb.validateApiKey(created.key), false);
|
||||
assert.equal(await apiKeysDb.getApiKeyById(created.id), null);
|
||||
assert.equal(await apiKeysDb.getApiKeyMetadata(created.key), null);
|
||||
});
|
||||
|
||||
test("isModelAllowedForKey supports exact, prefix and wildcard rules", async () => {
|
||||
const unrestricted = await apiKeysDb.createApiKey("Unrestricted", "machine-303");
|
||||
const restricted = await apiKeysDb.createApiKey("Restricted", "machine-303");
|
||||
|
||||
await apiKeysDb.updateApiKeyPermissions(restricted.id, {
|
||||
allowedModels: ["openai/*", "anthropic/claude-*", "o*-mini"],
|
||||
});
|
||||
|
||||
assert.equal(await apiKeysDb.isModelAllowedForKey(null, "any/model"), true);
|
||||
assert.equal(await apiKeysDb.isModelAllowedForKey(restricted.key, null), false);
|
||||
assert.equal(await apiKeysDb.isModelAllowedForKey("sk-invalid", "openai/gpt-4.1"), false);
|
||||
assert.equal(await apiKeysDb.isModelAllowedForKey(unrestricted.key, "provider/any-model"), true);
|
||||
assert.equal(await apiKeysDb.isModelAllowedForKey(restricted.key, "openai/gpt-4.1"), true);
|
||||
assert.equal(
|
||||
await apiKeysDb.isModelAllowedForKey(restricted.key, "anthropic/claude-3-7-sonnet"),
|
||||
true
|
||||
);
|
||||
assert.equal(await apiKeysDb.isModelAllowedForKey(restricted.key, "o3-mini"), true);
|
||||
assert.equal(
|
||||
await apiKeysDb.isModelAllowedForKey(restricted.key, "gemini/gemini-2.5-pro"),
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
test("getApiKeyMetadata ignores malformed stored schedule payloads", async () => {
|
||||
const created = await apiKeysDb.createApiKey("Malformed Schedule", "machine-303");
|
||||
const db = core.getDbInstance();
|
||||
|
||||
db.prepare("UPDATE api_keys SET access_schedule = ? WHERE id = ?").run("not-json", created.id);
|
||||
apiKeysDb.clearApiKeyCaches();
|
||||
|
||||
const metadata = await apiKeysDb.getApiKeyMetadata(created.key);
|
||||
|
||||
assert.equal(metadata.accessSchedule, null);
|
||||
});
|
||||
|
||||
test("createApiKey persists scopes and getApiKeyMetadata reads them back", async () => {
|
||||
const key = await apiKeysDb.createApiKey("Manage Key", "machine-303", ["manage"]);
|
||||
const metadata = await apiKeysDb.getApiKeyMetadata(key.key);
|
||||
|
||||
assert.ok(metadata);
|
||||
assert.deepEqual(metadata.scopes, ["manage"]);
|
||||
assert.deepEqual(key.scopes, ["manage"]);
|
||||
});
|
||||
|
||||
test("updateApiKeyPermissions persists scopes and getApiKeyMetadata reads them back", async () => {
|
||||
const key = await apiKeysDb.createApiKey("Plain Key", "machine-303");
|
||||
const metaBefore = await apiKeysDb.getApiKeyMetadata(key.key);
|
||||
assert.deepEqual(metaBefore.scopes, []);
|
||||
|
||||
await apiKeysDb.updateApiKeyPermissions(key.id, { scopes: ["manage"] });
|
||||
apiKeysDb.clearApiKeyCaches();
|
||||
|
||||
const metaAfter = await apiKeysDb.getApiKeyMetadata(key.key);
|
||||
assert.deepEqual(metaAfter.scopes, ["manage"]);
|
||||
});
|
||||
|
||||
test("updateApiKeyPermissions can clear scopes back to empty", async () => {
|
||||
const key = await apiKeysDb.createApiKey("Admin Key", "machine-303", ["manage"]);
|
||||
await apiKeysDb.updateApiKeyPermissions(key.id, { scopes: [] });
|
||||
apiKeysDb.clearApiKeyCaches();
|
||||
|
||||
const metadata = await apiKeysDb.getApiKeyMetadata(key.key);
|
||||
assert.deepEqual(metadata.scopes, []);
|
||||
});
|
||||
Reference in New Issue
Block a user