fix(e2e): follow shared auth ownership in onboarding proof (#126958)

This commit is contained in:
Dallin Romney
2026-08-20 20:01:25 -07:00
committed by GitHub
parent 630175d87f
commit be891d2ac0
2 changed files with 54 additions and 21 deletions
@@ -77,8 +77,8 @@ function extractStatusSection(text, title) {
return stripAnsi(section.join("\n"));
}
function readAuthProfileStoreText(agentDir) {
const dbPath = path.join(agentDir, "openclaw-agent.sqlite");
function readSharedAuthProfileStoreText(stateDir) {
const dbPath = path.join(stateDir, "state", "openclaw.sqlite");
if (!fs.existsSync(dbPath)) {
return "";
}
@@ -86,8 +86,8 @@ function readAuthProfileStoreText(agentDir) {
try {
db = new DatabaseSync(dbPath, { readOnly: true });
const row = db
.prepare("SELECT store_json FROM auth_profile_store WHERE store_key = ?")
.get("primary");
.prepare("SELECT store_json FROM auth_profile_stores WHERE store_key = ?")
.get("shared");
return typeof row?.store_json === "string" ? row.store_json : "";
} catch {
return "";
@@ -100,15 +100,21 @@ function assertOnboardState() {
const home = process.argv[3];
const stateDir = path.join(home, ".openclaw");
const configPath = path.join(stateDir, "openclaw.json");
const agentDir = path.join(stateDir, "agents", "main", "agent");
const legacyAuthDatabase = path.join(
stateDir,
"agents",
"main",
"agent",
"openclaw-agent.sqlite",
);
if (!fs.existsSync(configPath)) {
throw new Error("onboard did not write openclaw.json");
}
if (!fs.existsSync(agentDir)) {
throw new Error("onboard did not create main agent dir");
if (fs.existsSync(legacyAuthDatabase)) {
throw new Error("onboard created the retired main-agent auth database");
}
const authStoreText = readAuthProfileStoreText(agentDir);
const authStoreText = readSharedAuthProfileStoreText(stateDir);
if (!authStoreText) {
throw new Error("onboard did not persist auth profile store");
}
@@ -37,12 +37,13 @@ function writeOnboardConfig(home: string): void {
);
}
function writeAuthProfileStoreSqlite(agentDir: string, store: unknown): void {
fs.mkdirSync(agentDir, { recursive: true });
const db = new DatabaseSync(path.join(agentDir, "openclaw-agent.sqlite"));
function writeSharedAuthProfileStoreSqlite(home: string, store: unknown): void {
const stateDir = path.join(home, ".openclaw", "state");
fs.mkdirSync(stateDir, { recursive: true });
const db = new DatabaseSync(path.join(stateDir, "openclaw.sqlite"));
try {
db.exec(`
CREATE TABLE IF NOT EXISTS auth_profile_store (
CREATE TABLE IF NOT EXISTS auth_profile_stores (
store_key TEXT NOT NULL PRIMARY KEY,
store_json TEXT NOT NULL,
updated_at INTEGER NOT NULL
@@ -50,10 +51,10 @@ function writeAuthProfileStoreSqlite(agentDir: string, store: unknown): void {
`);
db.prepare(
`
INSERT INTO auth_profile_store (store_key, store_json, updated_at)
INSERT INTO auth_profile_stores (store_key, store_json, updated_at)
VALUES (?, ?, ?)
`,
).run("primary", JSON.stringify(store), Date.now());
).run("shared", JSON.stringify(store), Date.now());
} finally {
db.close();
}
@@ -217,13 +218,13 @@ describe("npm onboard channel agent assertions", () => {
}
});
it("validates OpenAI env refs from the SQLite auth profile store", () => {
it("validates OpenAI env refs from the shared SQLite auth profile store", () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-onboard-assertions-"));
const agentDir = path.join(tempDir, ".openclaw", "agents", "main", "agent");
try {
writeOnboardConfig(tempDir);
writeAuthProfileStoreSqlite(agentDir, {
writeSharedAuthProfileStoreSqlite(tempDir, {
version: 1,
profiles: {
"openai:api-key": {
@@ -238,6 +239,7 @@ describe("npm onboard channel agent assertions", () => {
expect(result.status).toBe(0);
expect(result.stderr).toBe("");
expect(fs.existsSync(agentDir)).toBe(false);
expect(fs.existsSync(path.join(agentDir, "auth-profiles.json"))).toBe(false);
} finally {
fs.rmSync(tempDir, { force: true, recursive: true });
@@ -257,11 +259,10 @@ describe("npm onboard channel agent assertions", () => {
for (const store of cases) {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-onboard-assertions-"));
const agentDir = path.join(tempDir, ".openclaw", "agents", "main", "agent");
try {
writeOnboardConfig(tempDir);
writeAuthProfileStoreSqlite(agentDir, store);
writeSharedAuthProfileStoreSqlite(tempDir, store);
const result = runOnboardAssert(tempDir);
@@ -275,11 +276,9 @@ describe("npm onboard channel agent assertions", () => {
it("rejects inline OpenAI keys in the SQLite auth profile store", () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-onboard-assertions-"));
const agentDir = path.join(tempDir, ".openclaw", "agents", "main", "agent");
try {
writeOnboardConfig(tempDir);
writeAuthProfileStoreSqlite(agentDir, {
writeSharedAuthProfileStoreSqlite(tempDir, {
version: 1,
profiles: {
"openai:api-key": {
@@ -299,6 +298,34 @@ describe("npm onboard channel agent assertions", () => {
}
});
it("rejects a fresh install that recreates the retired main-agent auth database", () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-onboard-assertions-"));
const legacyAgentDir = path.join(tempDir, ".openclaw", "agents", "main", "agent");
try {
writeOnboardConfig(tempDir);
writeSharedAuthProfileStoreSqlite(tempDir, {
version: 1,
profiles: {
"openai:api-key": {
type: "api_key",
provider: "openai",
keyRef: { source: "env", provider: "default", id: "OPENAI_API_KEY" },
},
},
});
fs.mkdirSync(legacyAgentDir, { recursive: true });
new DatabaseSync(path.join(legacyAgentDir, "openclaw-agent.sqlite")).close();
const result = runOnboardAssert(tempDir);
expect(result.status).not.toBe(0);
expect(result.stderr).toContain("onboard created the retired main-agent auth database");
} finally {
fs.rmSync(tempDir, { force: true, recursive: true });
}
});
it("validates channel tokens in their canonical config fields", () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-channel-assertions-"));
try {