Upgrade the runtime and native plugin API to OpenCode 2.0.24. Restore session-scoped learning, credential renewal, typed project queries and controlled frontend actions from the legacy Agent. Replace host Shell execution with an approved Landlock/seccomp executor and persistent per-session workspaces. Add typed Bocha search and Tianditu geocoding bridges using the owning session credential. Require a working kernel sandbox before startup and persist workspace files in deployments. Validation completed before this commit: TypeScript checks, 150 Bun tests, Docker build and UID 10001 sandbox execution, native Shell approval and session recovery. Tianditu succeeded; Bocha currently reports exhausted account quota. Unrelated investigation-report contract work is excluded.
66 lines
4.1 KiB
TypeScript
66 lines
4.1 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { CredentialRefreshCoordinator, runWithCredentialRefresh, bindSessionCredential, credentialRefreshCoordinator, refreshSessionCredential, releaseSessionCredential, requestWithSessionCredential } from "../../src/product/credential-refresh.js";
|
|
|
|
describe("credential renewal", () => {
|
|
it("rejects stale replies and stops repeated requests when the renewed credential is still rejected", async () => {
|
|
const session = "rejected-credential-session";
|
|
bindSessionCredential(session, { authorization: "Bearer OLD", projectId: "p" });
|
|
let calls = 0;
|
|
let failures = 0;
|
|
const unsubscribe = credentialRefreshCoordinator.subscribe(session, (event) => {
|
|
if (event.type === "credential_refresh_required") {
|
|
expect(refreshSessionCredential(session, { authorization: "Bearer NEW", projectId: "other" }, event.requestId)).toBeFalse();
|
|
expect(refreshSessionCredential(session, { authorization: "Bearer NEW", projectId: "p" }, "stale")).toBeFalse();
|
|
refreshSessionCredential(session, { authorization: "Bearer NEW", projectId: "p" }, event.requestId);
|
|
} else if (event.type === "credential_refresh_failed") failures += 1;
|
|
});
|
|
try {
|
|
expect((await requestWithSessionCredential(session, async () => { calls += 1; return new Response(null, { status: 401 }); })).status).toBe(401);
|
|
await expect(requestWithSessionCredential(session, async () => { calls += 1; return new Response(null, { status: 200 }); })).rejects.toThrow("renewal failed");
|
|
expect(calls).toBe(2);
|
|
expect(failures).toBe(1);
|
|
} finally { unsubscribe(); releaseSessionCredential(session); }
|
|
});
|
|
it("coalesces concurrent 401 responses, resumes both calls, and retries only once", async () => {
|
|
const coordinator = new CredentialRefreshCoordinator(1000);
|
|
const old = { authorization: "Bearer TEST_OLD", projectId: "p" };
|
|
const renewed = { authorization: "Bearer TEST_NEW", projectId: "p" };
|
|
let requests = 0;
|
|
coordinator.subscribe("s", (event) => {
|
|
if (event.type === "credential_refresh_required") {
|
|
requests += 1;
|
|
queueMicrotask(() => coordinator.resolve("s", event.requestId, renewed));
|
|
}
|
|
});
|
|
const calls: string[] = [];
|
|
const execute = async (credential: typeof old) => {
|
|
calls.push(credential.authorization);
|
|
return { status: credential.authorization === old.authorization ? 401 : 200 };
|
|
};
|
|
expect((await Promise.all([runWithCredentialRefresh(coordinator, "s", old, execute), runWithCredentialRefresh(coordinator, "s", old, execute)])).map((result) => result.status)).toEqual([200, 200]);
|
|
expect(requests).toBe(1);
|
|
expect(calls).toHaveLength(4);
|
|
});
|
|
it("does not refresh 403 and fails when refresh is unavailable or cancelled", async () => {
|
|
const coordinator = new CredentialRefreshCoordinator(1000);
|
|
const credential = { authorization: "Bearer TEST", projectId: "p" };
|
|
expect((await runWithCredentialRefresh(coordinator, "s", credential, async () => ({ status: 403 }))).status).toBe(403);
|
|
await expect(runWithCredentialRefresh(coordinator, "s", credential, async () => ({ status: 401 }))).rejects.toThrow("unavailable");
|
|
coordinator.enableBackground("s");
|
|
const pending = coordinator.request("s", "access_token_expired");
|
|
coordinator.cancelSession("s");
|
|
await expect(pending).rejects.toThrow("cancelled");
|
|
});
|
|
it("renews before near-expiry execution and exposes the same pending request for reconnect", async () => {
|
|
const coordinator = new CredentialRefreshCoordinator(1000);
|
|
const old = { authorization: "Bearer OLD", projectId: "p", expiresAt: new Date(Date.now() + 1000).toISOString() };
|
|
coordinator.subscribe("s", (event) => {
|
|
if (event.type === "credential_refresh_required") {
|
|
expect(coordinator.getPendingEvent("s")?.requestId).toBe(event.requestId);
|
|
coordinator.resolve("s", event.requestId, { authorization: "Bearer NEW", projectId: "p" });
|
|
}
|
|
});
|
|
expect(await runWithCredentialRefresh(coordinator, "s", old, async (credential) => ({ status: 200, authorization: credential.authorization }))).toMatchObject({ authorization: "Bearer NEW" });
|
|
});
|
|
});
|