mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-22 06:42:19 +03:00
feat(leases): expose owner-authenticated connection display name (#11910)
Boarded with 8 other PRs in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles, check-native-deps all green; 75/75 focused tests pass. Reviewed the security fencing closely — the status query fences on lease_owner_hash + api_key_id + generation + state=ACTIVE + not-expired, gated behind the existing lease:exclusive scope check. configuredConnectionName() correctly excludes email-derived fallback labels from the response. Test coverage explicitly verifies foreign key / different owner / stale generation all fail closed with 409, and no metadata leaks for released/expired/invalidated/missing leases. Thanks for the careful privacy-safe design.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
- **feat(leases):** add an explicit owner-authenticated status action that returns only the active lease's privacy-safe configured connection and provider labels, with generation fencing and no credential or internal-id disclosure ([#11910](https://github.com/diegosouzapw/OmniRoute/pull/11910)) — thanks @KaspaPulse
|
||||
@@ -111,13 +111,15 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Session Leases
|
||||
summary: Acquire, renew, or release an exclusive managed connection lease
|
||||
summary: Acquire, inspect, renew, or release an exclusive managed connection lease
|
||||
description: |
|
||||
Requires an API key with `lease:exclusive` and an explicit non-empty
|
||||
`allowedConnections` policy. The opaque owner is bound to the authenticated API key;
|
||||
the lease owns an eligible connection, not a provider or model. Managed inference
|
||||
requests present the owner and exact generation headers. Temporary foreign occupancy
|
||||
returns 429 `WAITING_FOR_CAPACITY` with `Retry-After`.
|
||||
returns 429 `WAITING_FOR_CAPACITY` with `Retry-After`. Acquire, renew, and release retain
|
||||
their connection-free response shapes. The explicit status action is owner-, key-, and
|
||||
generation-fenced and returns only privacy-safe display metadata for an active binding.
|
||||
security:
|
||||
- BearerAuth: []
|
||||
parameters:
|
||||
@@ -138,6 +140,11 @@ paths:
|
||||
properties:
|
||||
action: { type: string, const: acquire }
|
||||
model: { type: string, minLength: 1, maxLength: 512 }
|
||||
- type: object
|
||||
required: [action, generation]
|
||||
properties:
|
||||
action: { type: string, const: status }
|
||||
generation: { type: integer, minimum: 1 }
|
||||
- type: object
|
||||
required: [action, generation]
|
||||
properties:
|
||||
@@ -153,7 +160,7 @@ paths:
|
||||
enum: [OWNER_EXIT, CLIENT_CANCELLED]
|
||||
responses:
|
||||
"200":
|
||||
description: Lease lifecycle state without connection or credential disclosure
|
||||
description: Lease lifecycle state, with privacy-safe connection display metadata only for status
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -8002,6 +8009,10 @@ components:
|
||||
schemas:
|
||||
ExclusiveConnectionLeaseLifecycle:
|
||||
type: object
|
||||
description: >-
|
||||
Shared lease lifecycle response. The optional connection object is present only for an
|
||||
explicit, successful owner-authenticated status action; acquire, renew, and release never
|
||||
include connection metadata.
|
||||
required: [state, generation, acquiredAt, renewedAt, expiresAt]
|
||||
properties:
|
||||
state: { type: string, enum: [ACTIVE, RELEASED] }
|
||||
@@ -8009,6 +8020,22 @@ components:
|
||||
acquiredAt: { type: string, format: date-time }
|
||||
renewedAt: { type: string, format: date-time }
|
||||
expiresAt: { type: string, format: date-time }
|
||||
connection:
|
||||
type: object
|
||||
description: >-
|
||||
Privacy-safe metadata for the exact active binding. Wrong-key, wrong-owner,
|
||||
stale-generation, missing, expired, released, or invalidated leases return a generic
|
||||
409 without this object. No credential, internal id, owner identity, or email fallback
|
||||
is serialized.
|
||||
required: [displayName, provider]
|
||||
properties:
|
||||
displayName:
|
||||
type: [string, "null"]
|
||||
description: Trimmed operator-configured name, or null when no privacy-safe name exists.
|
||||
provider:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Non-sensitive provider display label, never a generated compatible-provider id.
|
||||
ExclusiveConnectionLeaseCapacity:
|
||||
type: object
|
||||
required: [state, error, reason, retryAfter, eligibleCount, freeCount]
|
||||
|
||||
@@ -107,9 +107,9 @@ X-OmniRoute-Lease-Owner: vlo_<43-base64url-characters>
|
||||
{"action":"acquire","model":"glm/glm-4.6"}
|
||||
```
|
||||
|
||||
Successful lifecycle responses expose timestamps, `state`, and the exact positive `generation`,
|
||||
but never the selected connection or credentials. Renew and release supply the generation in the
|
||||
JSON body:
|
||||
Successful acquire, renew, and release responses expose timestamps, `state`, and the exact positive
|
||||
`generation`, but never the selected connection or credentials. Renew and release supply the
|
||||
generation in the JSON body:
|
||||
|
||||
```json
|
||||
{ "action": "renew", "generation": 1 }
|
||||
@@ -119,6 +119,44 @@ JSON body:
|
||||
{ "action": "release", "generation": 1, "reason": "OWNER_EXIT" }
|
||||
```
|
||||
|
||||
An active lease owner can explicitly request privacy-safe display metadata for its current binding:
|
||||
|
||||
```json
|
||||
{ "action": "status", "generation": 1 }
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"state": "ACTIVE",
|
||||
"generation": 1,
|
||||
"acquiredAt": "2026-08-28T12:00:00.000Z",
|
||||
"renewedAt": "2026-08-28T12:00:30.000Z",
|
||||
"expiresAt": "2026-08-28T12:02:30.000Z",
|
||||
"connection": {
|
||||
"displayName": "Primary Codex",
|
||||
"provider": "codex"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This opt-in status action is fenced by the opaque owner, authenticated managed API key, and exact
|
||||
active generation in one database transaction. `displayName` is only the trimmed configured
|
||||
connection name; it is `null` when no safe configured name exists. OmniRoute never substitutes an
|
||||
email or generated account identity. The provider value is a non-sensitive display label and never
|
||||
a generated compatible-provider identifier. Credentials, tokens, cookies, raw connection or API
|
||||
key ids, owner hashes, fencing secrets, and internal routing data are excluded.
|
||||
|
||||
Wrong-key, wrong-owner, stale-generation, missing, expired, released, and invalidated lookups all
|
||||
return the same `409 LEASE_FENCE_STALE` error without connection metadata. A client that received the capacity-wait response has no active binding to inspect. When routing transitions an active lease,
|
||||
the same generation remains valid and status atomically returns the new binding, never the old one.
|
||||
Existing clients remain unchanged because acquire, renew, release, and waiting responses retain
|
||||
their previous shapes.
|
||||
|
||||
This server contract does not change stock OpenAI Codex `/status`. Stock Codex currently reports its
|
||||
model provider and built-in authentication/account state but does not render arbitrary custom
|
||||
provider account metadata; a later client integration must call this action and decide how to
|
||||
display `connection.displayName`.
|
||||
|
||||
Every managed inference request then supplies both control headers:
|
||||
|
||||
```http
|
||||
|
||||
@@ -16,13 +16,15 @@ All requests require a valid Bearer token or session cookie. Obtain a token via
|
||||
|
||||
### POST /api/v1/session-leases
|
||||
|
||||
Acquire, renew, or release an exclusive managed connection lease
|
||||
Acquire, inspect, renew, or release an exclusive managed connection lease
|
||||
|
||||
Requires an API key with `lease:exclusive` and an explicit non-empty
|
||||
`allowedConnections` policy. The opaque owner is bound to the authenticated API key;
|
||||
the lease owns an eligible connection, not a provider or model. Managed inference
|
||||
requests present the owner and exact generation headers. Temporary foreign occupancy
|
||||
returns 429 `WAITING_FOR_CAPACITY` with `Retry-After`.
|
||||
returns 429 `WAITING_FOR_CAPACITY` with `Retry-After`. Acquire, renew, and release retain
|
||||
their connection-free response shapes. The explicit status action is owner-, key-, and
|
||||
generation-fenced and returns only privacy-safe display metadata for an active binding.
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
@@ -5,9 +5,11 @@ import { isCommonChatGptWebRetirementError } from "@/shared/constants/chatgptWeb
|
||||
import { enforceApiKeyPolicy } from "@/shared/utils/apiKeyPolicy";
|
||||
import { CORS_HEADERS, handleCorsOptions } from "@/shared/utils/cors";
|
||||
import {
|
||||
getExclusiveConnectionLeaseStatus,
|
||||
releaseExclusiveConnectionLease,
|
||||
renewExclusiveConnectionLease,
|
||||
} from "@/lib/db/exclusiveConnectionLeases";
|
||||
import { getProviderDisplayName } from "@/lib/display/names";
|
||||
import {
|
||||
extractApiKey,
|
||||
getProviderCredentialsWithQuotaPreflight,
|
||||
@@ -29,6 +31,7 @@ const action = <T extends string>(name: T, shape: z.ZodRawShape) =>
|
||||
const generation = z.number().int().positive().safe();
|
||||
const actionSchema = z.discriminatedUnion("action", [
|
||||
action("acquire", { model: z.string().trim().min(1).max(512) }),
|
||||
action("status", { generation }),
|
||||
action("renew", { generation }),
|
||||
z.object({
|
||||
action: z.literal("release"),
|
||||
@@ -95,6 +98,18 @@ export async function POST(request: Request): Promise<Response> {
|
||||
generation: parsed.data.generation,
|
||||
apiKeyId: policy.apiKeyInfo.id,
|
||||
};
|
||||
if (parsed.data.action === "status") {
|
||||
const status = getExclusiveConnectionLeaseStatus(input);
|
||||
return status
|
||||
? json(200, {
|
||||
...lifecycle(status.lease),
|
||||
connection: {
|
||||
displayName: status.connectionName,
|
||||
provider: getProviderDisplayName(status.provider),
|
||||
},
|
||||
})
|
||||
: error(409, "LEASE_FENCE_STALE", "The lease generation is stale");
|
||||
}
|
||||
const result =
|
||||
parsed.data.action === "renew"
|
||||
? renewExclusiveConnectionLease(input)
|
||||
|
||||
@@ -40,6 +40,13 @@ type LeaseRow = {
|
||||
state: ExclusiveLeaseState;
|
||||
expires_at: string;
|
||||
};
|
||||
type LeaseStatusRow = LeaseRow & {
|
||||
connection_provider: string;
|
||||
connection_auth_type: string | null;
|
||||
connection_name: string | null;
|
||||
connection_email: string | null;
|
||||
connection_display_name: string | null;
|
||||
};
|
||||
type LeaseSuccess = {
|
||||
kind: "ACQUIRED" | "REUSED" | "TRANSITIONED";
|
||||
lease: ExclusiveConnectionLease;
|
||||
@@ -92,6 +99,21 @@ function active(column: "lease_owner_hash" | "connection_id", value: string) {
|
||||
return database().prepare(`${ACTIVE_SQL}${column} = ?`).get(value) as LeaseRow | undefined;
|
||||
}
|
||||
|
||||
function configuredConnectionName(row: LeaseStatusRow): string | null {
|
||||
const name = row.connection_name?.trim();
|
||||
if (!name || name.includes("@")) return null;
|
||||
|
||||
if (row.connection_auth_type === "oauth" || row.connection_auth_type === "access_token") {
|
||||
const normalized = name.toLowerCase();
|
||||
const generatedFallbacks = [row.connection_email, row.connection_display_name]
|
||||
.map((value) => value?.trim().toLowerCase())
|
||||
.filter((value): value is string => Boolean(value));
|
||||
if (generatedFallbacks.includes(normalized)) return null;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function historical(ownerHash: string, generation: number) {
|
||||
return database()
|
||||
.prepare(
|
||||
@@ -192,6 +214,44 @@ export function reconcileExpiredExclusiveConnectionLeases(now?: string): number
|
||||
return immediate(() => expire(timestamp(now)));
|
||||
}
|
||||
|
||||
export function getExclusiveConnectionLeaseStatus(input: {
|
||||
leaseOwnerId: string;
|
||||
generation: number;
|
||||
apiKeyId: string;
|
||||
now?: string;
|
||||
}): {
|
||||
lease: ExclusiveConnectionLease;
|
||||
provider: string;
|
||||
connectionName: string | null;
|
||||
} | null {
|
||||
const ownerHash = hashLeaseOwnerId(input.leaseOwnerId);
|
||||
const now = timestamp(input.now);
|
||||
return immediate(() => {
|
||||
expire(now);
|
||||
const row = database()
|
||||
.prepare(
|
||||
`SELECT leases.*, connections.provider AS connection_provider,
|
||||
connections.auth_type AS connection_auth_type,
|
||||
connections.name AS connection_name,
|
||||
connections.email AS connection_email,
|
||||
connections.display_name AS connection_display_name
|
||||
FROM exclusive_connection_leases leases
|
||||
INNER JOIN provider_connections connections ON connections.id = leases.connection_id
|
||||
WHERE leases.lease_owner_hash = ? AND leases.api_key_id = ?
|
||||
AND leases.generation = ? AND leases.state = 'ACTIVE' AND leases.expires_at > ?
|
||||
LIMIT 1`
|
||||
)
|
||||
.get(ownerHash, input.apiKeyId, input.generation, now) as LeaseStatusRow | undefined;
|
||||
return row
|
||||
? {
|
||||
lease: lease(row),
|
||||
provider: row.connection_provider,
|
||||
connectionName: configuredConnectionName(row),
|
||||
}
|
||||
: null;
|
||||
});
|
||||
}
|
||||
|
||||
export function acquireExclusiveConnectionLease(input: {
|
||||
leaseOwnerId: string;
|
||||
apiKeyId: string;
|
||||
|
||||
@@ -15,6 +15,7 @@ const apiKeysDb = await import("../../src/lib/db/apiKeys.ts");
|
||||
const modelAliasesDb = await import("../../src/lib/db/models/aliases.ts");
|
||||
const settingsDb = await import("../../src/lib/db/settings.ts");
|
||||
const modelAliasResolver = await import("../../src/lib/modelAliasResolver.ts");
|
||||
const leaseDb = await import("../../src/lib/db/exclusiveConnectionLeases.ts");
|
||||
const route = await import("../../src/app/api/v1/session-leases/route.ts");
|
||||
|
||||
const OWNER_A = "vlo_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
@@ -229,6 +230,7 @@ test("acquires, reuses, renews, releases, and fences a stale lifecycle", async (
|
||||
request(managed.key, { action: "renew", generation: 1 }, OWNER_A)
|
||||
);
|
||||
assert.equal(renewed.status, 200);
|
||||
assert.equal("connection" in (await json(renewed)), false);
|
||||
|
||||
const staleRenew = await route.POST(
|
||||
request(managed.key, { action: "renew", generation: 2 }, OWNER_A)
|
||||
@@ -240,7 +242,9 @@ test("acquires, reuses, renews, releases, and fences a stale lifecycle", async (
|
||||
request(managed.key, { action: "release", generation: 1, reason: "CLIENT_CANCELLED" }, OWNER_A)
|
||||
);
|
||||
assert.equal(released.status, 200);
|
||||
assert.equal((await json(released)).state, "RELEASED");
|
||||
const releasedBody = await json(released);
|
||||
assert.equal(releasedBody.state, "RELEASED");
|
||||
assert.equal("connection" in releasedBody, false);
|
||||
|
||||
const idempotent = await route.POST(
|
||||
request(managed.key, { action: "release", generation: 1 }, OWNER_A)
|
||||
@@ -250,6 +254,257 @@ test("acquires, reuses, renews, releases, and fences a stale lifecycle", async (
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("status explicitly returns only the active owner's privacy-safe connection display metadata", async () => {
|
||||
const connection = await seedConnection(1);
|
||||
const managed = await seedKey([connection.id]);
|
||||
const acquired = await route.POST(
|
||||
request(managed.key, { action: "acquire", model: "glm/glm-4.6" }, OWNER_A)
|
||||
);
|
||||
assert.equal(acquired.status, 200);
|
||||
|
||||
const response = await route.POST(
|
||||
request(managed.key, { action: "status", generation: 1 }, OWNER_A)
|
||||
);
|
||||
assert.equal(response.status, 200);
|
||||
const body = await json(response);
|
||||
assert.deepEqual(Object.keys(body).sort(), [
|
||||
"acquiredAt",
|
||||
"connection",
|
||||
"expiresAt",
|
||||
"generation",
|
||||
"renewedAt",
|
||||
"state",
|
||||
]);
|
||||
assert.deepEqual(body.connection, {
|
||||
displayName: "lease-route-1",
|
||||
provider: "glm",
|
||||
});
|
||||
|
||||
const serialized = JSON.stringify(body);
|
||||
for (const forbidden of [
|
||||
connection.id,
|
||||
managed.id,
|
||||
managed.key,
|
||||
OWNER_A,
|
||||
leaseDb.hashLeaseOwnerId(OWNER_A),
|
||||
"sk-route-1",
|
||||
"connectionId",
|
||||
"apiKeyId",
|
||||
"leaseOwnerHash",
|
||||
"leaseOwnerId",
|
||||
"credentials",
|
||||
"accessToken",
|
||||
"refreshToken",
|
||||
"cookie",
|
||||
"fencing",
|
||||
]) {
|
||||
assert.equal(serialized.includes(forbidden), false, `status must not contain ${forbidden}`);
|
||||
}
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("status fails closed for a foreign key, different owner, or stale generation", async () => {
|
||||
const connection = await seedConnection(1);
|
||||
const ownerKey = await seedKey([connection.id]);
|
||||
const foreignKey = await seedKey([connection.id]);
|
||||
assert.equal(
|
||||
(await route.POST(request(ownerKey.key, { action: "acquire", model: "glm/glm-4.6" }, OWNER_A)))
|
||||
.status,
|
||||
200
|
||||
);
|
||||
|
||||
const attempts = [
|
||||
request(foreignKey.key, { action: "status", generation: 1 }, OWNER_A),
|
||||
request(ownerKey.key, { action: "status", generation: 1 }, OWNER_B),
|
||||
request(ownerKey.key, { action: "status", generation: 2 }, OWNER_A),
|
||||
];
|
||||
for (const attempt of attempts) {
|
||||
const response = await route.POST(attempt);
|
||||
assert.equal(response.status, 409);
|
||||
const body = await json(response);
|
||||
assert.equal((body.error as { code: string }).code, "LEASE_FENCE_STALE");
|
||||
const serialized = JSON.stringify(body);
|
||||
assert.equal("connection" in body, false);
|
||||
assert.equal(serialized.includes("lease-route-1"), false);
|
||||
assert.equal(serialized.includes(connection.id), false);
|
||||
}
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("status never uses provider identity as a connection display-name fallback", async () => {
|
||||
for (const identity of [
|
||||
{ email: "private-lease-owner@example.com" },
|
||||
{ displayName: "Private Provider Account" },
|
||||
]) {
|
||||
await resetStorage();
|
||||
const privateIdentity = identity.email ?? identity.displayName;
|
||||
const providerToken = `private-provider-access-token-${privateIdentity}`;
|
||||
const connection = await providersDb.createProviderConnection({
|
||||
provider: "glm",
|
||||
authType: "access_token",
|
||||
accessToken: providerToken,
|
||||
...identity,
|
||||
isActive: true,
|
||||
testStatus: "active",
|
||||
});
|
||||
assert.equal(connection.name, privateIdentity, "the stored name is a generated fallback");
|
||||
const managed = await seedKey([connection.id]);
|
||||
assert.equal(
|
||||
(await route.POST(request(managed.key, { action: "acquire", model: "glm/glm-4.6" }, OWNER_A)))
|
||||
.status,
|
||||
200
|
||||
);
|
||||
|
||||
const response = await route.POST(
|
||||
request(managed.key, { action: "status", generation: 1 }, OWNER_A)
|
||||
);
|
||||
assert.equal(response.status, 200);
|
||||
const body = await json(response);
|
||||
assert.deepEqual(body.connection, { displayName: null, provider: "glm" });
|
||||
const serialized = JSON.stringify(body);
|
||||
assert.equal(serialized.includes(privateIdentity), false);
|
||||
assert.equal(serialized.includes(providerToken), false);
|
||||
assert.equal(serialized.includes(connection.id), false);
|
||||
}
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("status replaces a generated compatible-provider id with a non-sensitive label", async () => {
|
||||
const providerId = "openai-compatible-chat-01234567-89ab-cdef-0123-456789abcdef";
|
||||
await providersDb.createProviderNode({
|
||||
id: providerId,
|
||||
type: "openai-compatible",
|
||||
name: "Internal routing node",
|
||||
prefix: "internal-routing-node",
|
||||
apiType: "chat",
|
||||
baseUrl: "https://private-provider.invalid/v1",
|
||||
});
|
||||
const connection = await providersDb.createProviderConnection({
|
||||
provider: providerId,
|
||||
authType: "apikey",
|
||||
name: "Safe gateway label",
|
||||
apiKey: "private-compatible-provider-key",
|
||||
isActive: true,
|
||||
testStatus: "active",
|
||||
providerSpecificData: {},
|
||||
});
|
||||
const managed = await seedKey([connection.id]);
|
||||
const acquired = leaseDb.acquireExclusiveConnectionLease({
|
||||
leaseOwnerId: OWNER_A,
|
||||
apiKeyId: managed.id,
|
||||
provider: providerId,
|
||||
connectionId: connection.id,
|
||||
});
|
||||
assert.equal(acquired.kind, "ACQUIRED");
|
||||
|
||||
const response = await route.POST(
|
||||
request(managed.key, { action: "status", generation: 1 }, OWNER_A)
|
||||
);
|
||||
assert.equal(response.status, 200);
|
||||
const body = await json(response);
|
||||
assert.deepEqual(body.connection, {
|
||||
displayName: "Safe gateway label",
|
||||
provider: "Compatible (openai)",
|
||||
});
|
||||
const serialized = JSON.stringify(body);
|
||||
assert.equal(serialized.includes(providerId), false);
|
||||
assert.equal(serialized.includes("internal-routing-node"), false);
|
||||
assert.equal(serialized.includes("private-provider.invalid"), false);
|
||||
assert.equal(serialized.includes("private-compatible-provider-key"), false);
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("status reads the new binding after transition and never returns the old label", async () => {
|
||||
const oldConnection = await seedConnection(1);
|
||||
const newConnection = await seedConnection(2);
|
||||
const managed = await seedKey([oldConnection.id, newConnection.id]);
|
||||
assert.equal(
|
||||
(await route.POST(request(managed.key, { action: "acquire", model: "glm/glm-4.6" }, OWNER_A)))
|
||||
.status,
|
||||
200
|
||||
);
|
||||
|
||||
const transitioned = leaseDb.transitionExclusiveConnectionLease({
|
||||
leaseOwnerId: OWNER_A,
|
||||
generation: 1,
|
||||
apiKeyId: managed.id,
|
||||
provider: "glm",
|
||||
connectionId: newConnection.id,
|
||||
reason: "CONNECTION_INELIGIBLE",
|
||||
});
|
||||
assert.equal(transitioned.kind, "TRANSITIONED");
|
||||
if (transitioned.kind !== "TRANSITIONED") return;
|
||||
|
||||
const currentResponse = await route.POST(
|
||||
request(managed.key, { action: "status", generation: transitioned.lease.generation }, OWNER_A)
|
||||
);
|
||||
assert.equal(currentResponse.status, 200);
|
||||
const currentBody = await json(currentResponse);
|
||||
assert.deepEqual(currentBody.connection, {
|
||||
displayName: "lease-route-2",
|
||||
provider: "glm",
|
||||
});
|
||||
const serialized = JSON.stringify(currentBody);
|
||||
assert.equal(serialized.includes("lease-route-1"), false);
|
||||
assert.equal(serialized.includes(oldConnection.id), false);
|
||||
assert.equal(serialized.includes(newConnection.id), false);
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("status exposes no connection metadata for released, expired, invalidated, or missing leases", async () => {
|
||||
for (const inactiveState of ["released", "expired", "invalidated"] as const) {
|
||||
await resetStorage();
|
||||
const connection = await seedConnection(1);
|
||||
const managed = await seedKey([connection.id]);
|
||||
assert.equal(
|
||||
(await route.POST(request(managed.key, { action: "acquire", model: "glm/glm-4.6" }, OWNER_A)))
|
||||
.status,
|
||||
200
|
||||
);
|
||||
|
||||
if (inactiveState === "released") {
|
||||
assert.equal(
|
||||
(await route.POST(request(managed.key, { action: "release", generation: 1 }, OWNER_A)))
|
||||
.status,
|
||||
200
|
||||
);
|
||||
} else if (inactiveState === "expired") {
|
||||
leaseDb.reconcileExpiredExclusiveConnectionLeases(
|
||||
new Date(Date.now() + 180_000).toISOString()
|
||||
);
|
||||
} else {
|
||||
assert.equal(
|
||||
leaseDb.invalidateExclusiveConnectionLease({
|
||||
leaseOwnerId: OWNER_A,
|
||||
generation: 1,
|
||||
apiKeyId: managed.id,
|
||||
reason: "AUTHORIZATION_CHANGED",
|
||||
}).kind,
|
||||
"INVALIDATED"
|
||||
);
|
||||
}
|
||||
|
||||
const response = await route.POST(
|
||||
request(managed.key, { action: "status", generation: 1 }, OWNER_A)
|
||||
);
|
||||
assert.equal(response.status, 409, inactiveState);
|
||||
const body = await json(response);
|
||||
assert.equal("connection" in body, false, inactiveState);
|
||||
assert.equal(JSON.stringify(body).includes("lease-route-1"), false, inactiveState);
|
||||
assert.equal(JSON.stringify(body).includes(connection.id), false, inactiveState);
|
||||
}
|
||||
|
||||
await resetStorage();
|
||||
const connection = await seedConnection(1);
|
||||
const managed = await seedKey([connection.id]);
|
||||
const missing = await route.POST(
|
||||
request(managed.key, { action: "status", generation: 1 }, OWNER_A)
|
||||
);
|
||||
assert.equal(missing.status, 409);
|
||||
assert.equal("connection" in (await json(missing)), false);
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
test("renew and release require the API key that owns the active authorization", async () => {
|
||||
const connection = await seedConnection(1);
|
||||
const ownerKey = await seedKey([connection.id]);
|
||||
@@ -330,5 +585,6 @@ test("returns bounded WAITING_FOR_CAPACITY without credential or owner disclosur
|
||||
assert.equal(serialized.includes(OWNER_B), false);
|
||||
assert.equal(serialized.includes("apiKey"), false);
|
||||
assert.equal(serialized.includes("at /"), false);
|
||||
assert.equal("connection" in body, false);
|
||||
assert.equal(attemptedExternalCalls, 0);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user