openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
182 lines (181 loc) • 8.54 kB
JavaScript
import { w as resolveStateDir } from "./paths-D2sRr1a_.js";
import { a as getNodeSqliteKysely, i as executeSqliteQueryTakeFirstSync, r as executeSqliteQuerySync } from "./kysely-sync-COmh4HWh.js";
import { n as withExistingOpenClawStateDatabaseArtifactPreservingReadOnly } from "./openclaw-state-db-readonly-BRgmrGHt.js";
import { i as openOpenClawStateDatabase, s as runOpenClawStateWriteTransaction } from "./openclaw-state-db-BRTnL-D8.js";
import { n as normalizeDeviceAuthScopes, t as normalizeDeviceAuthRole } from "./device-auth-C-STNejO.js";
import fs from "node:fs";
import path from "node:path";
//#region src/infra/device-auth-store.ts
const legacyPresenceCache = /* @__PURE__ */ new Map();
function assertNoLegacyDeviceAuth(env) {
const stateDir = resolveStateDir(env);
let hasLegacy = legacyPresenceCache.get(stateDir);
if (hasLegacy === void 0) {
hasLegacy = fs.existsSync(path.join(stateDir, "identity", "device-auth.json"));
legacyPresenceCache.set(stateDir, hasLegacy);
}
if (hasLegacy) throw new Error("Legacy device auth requires migration; stop the Gateway and run `openclaw doctor --fix`.");
}
/** Forget one process-local legacy-state probe after Doctor removes the source. */
function resetLegacyDeviceAuthPresenceCache(env) {
legacyPresenceCache.delete(resolveStateDir(env));
}
function fromRow(row) {
try {
const scopes = JSON.parse(row.scopes_json);
if (!Array.isArray(scopes)) return null;
return {
token: row.token,
role: row.role,
scopes: normalizeDeviceAuthScopes(scopes),
updatedAtMs: row.updated_at_ms
};
} catch {
return null;
}
}
function readDeviceAuthTokenFromDatabase(db, params) {
const row = executeSqliteQueryTakeFirstSync(db, getNodeSqliteKysely(db).selectFrom("device_auth_tokens").select([
"token",
"role",
"scopes_json",
"updated_at_ms"
]).where("device_id", "=", params.deviceId).where("role", "=", normalizeDeviceAuthRole(params.role)));
return row ? fromRow(row) : null;
}
function readOriginDeviceTokenFromDatabase(db, params) {
const row = executeSqliteQueryTakeFirstSync(db, getNodeSqliteKysely(db).selectFrom("gateway_origin_device_tokens").select([
"token",
"role",
"scopes_json",
"updated_at_ms"
]).where("gateway_scope", "=", params.gatewayScope).where("device_id", "=", params.deviceId).where("role", "=", normalizeDeviceAuthRole(params.role)));
return row ? fromRow(row) : null;
}
function createDeviceAuthEntry(params) {
return {
token: params.token,
role: normalizeDeviceAuthRole(params.role),
scopes: normalizeDeviceAuthScopes(params.scopes),
updatedAtMs: Date.now()
};
}
/** Load one cached device-auth token from the shared SQLite state store. */
function loadDeviceAuthToken(params) {
assertNoLegacyDeviceAuth(params.env);
const { db } = openOpenClawStateDatabase({ env: params.env });
return readDeviceAuthTokenFromDatabase(db, params);
}
/** Load one cached device-auth token without creating or joining writable state. */
function loadDeviceAuthTokenReadOnly(params) {
assertNoLegacyDeviceAuth(params.env);
return withExistingOpenClawStateDatabaseArtifactPreservingReadOnly(({ db }) => {
return readDeviceAuthTokenFromDatabase(db, params);
}, { env: params.env }) ?? null;
}
/** List cached role tokens for one device from the shared SQLite state store. */
function loadDeviceAuthTokens(params) {
assertNoLegacyDeviceAuth(params.env);
const { db } = openOpenClawStateDatabase({ env: params.env });
return executeSqliteQuerySync(db, getNodeSqliteKysely(db).selectFrom("device_auth_tokens").select([
"token",
"role",
"scopes_json",
"updated_at_ms"
]).where("device_id", "=", params.deviceId).orderBy("role")).rows.flatMap((row) => {
const entry = fromRow(row);
return entry ? [entry] : [];
});
}
/** Persist or replace one device-auth role token in the shared SQLite state store. */
function storeDeviceAuthToken(params) {
assertNoLegacyDeviceAuth(params.env);
const entry = createDeviceAuthEntry(params);
let stored = false;
runOpenClawStateWriteTransaction(({ db }) => {
const kysely = getNodeSqliteKysely(db);
stored = (params.expectedToken === void 0 ? executeSqliteQuerySync(db, kysely.insertInto("device_auth_tokens").values({
device_id: params.deviceId,
role: entry.role,
token: entry.token,
scopes_json: JSON.stringify(entry.scopes),
updated_at_ms: entry.updatedAtMs
}).onConflict((conflict) => conflict.columns(["device_id", "role"]).doUpdateSet({
token: entry.token,
scopes_json: JSON.stringify(entry.scopes),
updated_at_ms: entry.updatedAtMs
}))) : executeSqliteQuerySync(db, kysely.updateTable("device_auth_tokens").set({
token: entry.token,
scopes_json: JSON.stringify(entry.scopes),
updated_at_ms: entry.updatedAtMs
}).where("device_id", "=", params.deviceId).where("role", "=", entry.role).where("token", "=", params.expectedToken))).numAffectedRows === 1n;
}, { env: params.env });
return stored ? entry : null;
}
/** Remove one role token for the current gateway device from shared SQLite state. */
function clearDeviceAuthToken(params) {
assertNoLegacyDeviceAuth(params.env);
let cleared = false;
runOpenClawStateWriteTransaction(({ db }) => {
const baseQuery = getNodeSqliteKysely(db).deleteFrom("device_auth_tokens").where("device_id", "=", params.deviceId).where("role", "=", normalizeDeviceAuthRole(params.role));
const query = params.expectedToken === void 0 ? baseQuery : baseQuery.where("token", "=", params.expectedToken);
cleared = executeSqliteQuerySync(db, query).numAffectedRows === 1n;
}, { env: params.env });
return cleared;
}
/** Load one device token bound to an exact normalized gateway origin. */
function loadOriginDeviceToken(params) {
assertNoLegacyDeviceAuth(params.env);
const { db } = openOpenClawStateDatabase({ env: params.env });
return readOriginDeviceTokenFromDatabase(db, params);
}
/** Load one origin-bound device token without schema creation or writable state access. */
function loadOriginDeviceTokenReadOnly(params) {
assertNoLegacyDeviceAuth(params.env);
return withExistingOpenClawStateDatabaseArtifactPreservingReadOnly(({ db }) => {
return readOriginDeviceTokenFromDatabase(db, params);
}, { env: params.env }) ?? null;
}
/** Persist one device token under an exact normalized gateway origin. */
function storeOriginDeviceToken(params) {
assertNoLegacyDeviceAuth(params.env);
const entry = createDeviceAuthEntry(params);
let stored = false;
runOpenClawStateWriteTransaction(({ db }) => {
const kysely = getNodeSqliteKysely(db);
stored = (params.expectedToken === void 0 ? executeSqliteQuerySync(db, kysely.insertInto("gateway_origin_device_tokens").values({
gateway_scope: params.gatewayScope,
device_id: params.deviceId,
role: entry.role,
token: entry.token,
scopes_json: JSON.stringify(entry.scopes),
updated_at_ms: entry.updatedAtMs
}).onConflict((conflict) => conflict.columns([
"gateway_scope",
"device_id",
"role"
]).doUpdateSet({
token: entry.token,
scopes_json: JSON.stringify(entry.scopes),
updated_at_ms: entry.updatedAtMs
}))) : executeSqliteQuerySync(db, kysely.updateTable("gateway_origin_device_tokens").set({
token: entry.token,
scopes_json: JSON.stringify(entry.scopes),
updated_at_ms: entry.updatedAtMs
}).where("gateway_scope", "=", params.gatewayScope).where("device_id", "=", params.deviceId).where("role", "=", entry.role).where("token", "=", params.expectedToken))).numAffectedRows === 1n;
}, { env: params.env });
return stored ? entry : null;
}
/** Remove one device token only from its exact normalized gateway origin. */
function clearOriginDeviceToken(params) {
assertNoLegacyDeviceAuth(params.env);
let cleared = false;
runOpenClawStateWriteTransaction(({ db }) => {
const baseQuery = getNodeSqliteKysely(db).deleteFrom("gateway_origin_device_tokens").where("gateway_scope", "=", params.gatewayScope).where("device_id", "=", params.deviceId).where("role", "=", normalizeDeviceAuthRole(params.role));
const query = params.expectedToken === void 0 ? baseQuery : baseQuery.where("token", "=", params.expectedToken);
cleared = executeSqliteQuerySync(db, query).numAffectedRows === 1n;
}, { env: params.env });
return cleared;
}
//#endregion
export { loadDeviceAuthTokens as a, resetLegacyDeviceAuthPresenceCache as c, loadDeviceAuthTokenReadOnly as i, storeDeviceAuthToken as l, clearOriginDeviceToken as n, loadOriginDeviceToken as o, loadDeviceAuthToken as r, loadOriginDeviceTokenReadOnly as s, clearDeviceAuthToken as t, storeOriginDeviceToken as u };