Files
openclaw/scripts/e2e/lib/auth-profile-store-assertions.mjs
Peter Steinberger 8b18d22db1 test(e2e): share canonical auth store reader (#126960)
* test(e2e): read shared auth store after onboarding

* test(e2e): harden shared auth proof

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-08-23 18:00:36 -07:00

140 lines
4.2 KiB
JavaScript

// Shared auth profile store assertions for install/onboard E2E proof.
import fs from "node:fs";
import path from "node:path";
import { DatabaseSync } from "node:sqlite";
import { isRecord } from "../../lib/record-shared.mjs";
export function readSharedAuthProfileStoreText(stateDir) {
const dbPath = path.join(stateDir, "state", "openclaw.sqlite");
if (!fs.existsSync(dbPath)) {
return "";
}
let db;
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const schema = db
.prepare("SELECT type FROM sqlite_schema WHERE name = ? LIMIT 1")
.get("auth_profile_stores");
if (!schema) {
return "";
}
if (schema.type !== "table") {
throw new Error(`auth_profile_stores is ${String(schema.type)}, not a table`);
}
const row = db
.prepare("SELECT store_json FROM auth_profile_stores WHERE store_key = ?")
.get("shared");
return typeof row?.store_json === "string" ? row.store_json : "";
} catch (error) {
const detail = error instanceof Error ? error.message : String(error);
throw new Error(`could not read the shared auth profile store: ${detail}`, {
cause: error,
});
} finally {
db?.close();
}
}
export function assertNoLegacyPrimaryAuthRows(stateDir) {
const dbPath = path.join(stateDir, "agents", "main", "agent", "openclaw-agent.sqlite");
if (!fs.existsSync(dbPath)) {
return;
}
let db;
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const legacyRows = [
{
table: "auth_profile_store",
query: "SELECT 1 AS present FROM auth_profile_store WHERE store_key = ? LIMIT 1",
},
{
table: "auth_profile_state",
query: "SELECT 1 AS present FROM auth_profile_state WHERE state_key = ? LIMIT 1",
},
];
for (const entry of legacyRows) {
const schema = db
.prepare("SELECT type FROM sqlite_schema WHERE name = ? LIMIT 1")
.get(entry.table);
if (!schema) {
continue;
}
if (schema.type !== "table") {
throw new Error(`${entry.table} is ${String(schema.type)}, not a table`);
}
if (db.prepare(entry.query).get("primary")) {
throw new Error(`onboard preserved a retired primary row in ${entry.table}`);
}
}
} catch (error) {
if (error instanceof Error && error.message.startsWith("onboard preserved a retired")) {
throw error;
}
const detail = error instanceof Error ? error.message : String(error);
throw new Error(`could not validate the main-agent auth database: ${detail}`, {
cause: error,
});
} finally {
db?.close();
}
}
function hasExpectedOpenAiEnvRef(profile) {
if (!isRecord(profile)) {
return false;
}
const keyRef = profile.keyRef;
return (
profile.type === "api_key" &&
profile.provider === "openai" &&
!Object.hasOwn(profile, "key") &&
isRecord(keyRef) &&
keyRef.source === "env" &&
keyRef.provider === "default" &&
keyRef.id === "OPENAI_API_KEY"
);
}
function hasInlineOpenAiKey(profile) {
return (
isRecord(profile) &&
profile.type === "api_key" &&
profile.provider === "openai" &&
Object.hasOwn(profile, "key")
);
}
export function assertOpenAiEnvAuthProfileStore(storeJson, options = {}) {
const missingMessage = options.missingMessage ?? "auth profile store was not persisted";
const envRefMessage =
options.envRefMessage ?? "auth profile did not persist OPENAI_API_KEY env ref";
const rawKeyMessage = options.rawKeyMessage ?? "auth profile persisted an inline OpenAI key";
const rawKeyNeedle = options.rawKeyNeedle;
if (!storeJson) {
throw new Error(missingMessage);
}
if (rawKeyNeedle && storeJson.includes(rawKeyNeedle)) {
throw new Error(rawKeyMessage);
}
let store;
try {
store = JSON.parse(storeJson);
} catch {
throw new Error(envRefMessage);
}
const profiles = isRecord(store) && isRecord(store.profiles) ? store.profiles : null;
if (!profiles) {
throw new Error(envRefMessage);
}
const profileValues = Object.values(profiles);
if (profileValues.some(hasInlineOpenAiKey)) {
throw new Error(rawKeyMessage);
}
if (!profileValues.some(hasExpectedOpenAiEnvRef)) {
throw new Error(envRefMessage);
}
}