squad-openclaw 2026.2.199 → 2026.2.1802
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +24 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -991,73 +991,60 @@ function writeRelayState(state) {
|
|
|
991
991
|
function toBase64Url(buf) {
|
|
992
992
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
993
993
|
}
|
|
994
|
-
function
|
|
995
|
-
const
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
const keys2 = JSON.parse(raw);
|
|
999
|
-
if (keys2.deviceId && keys2.publicKey && keys2.privateKey) {
|
|
1000
|
-
return keys2;
|
|
1001
|
-
}
|
|
1002
|
-
} catch {
|
|
994
|
+
function loadOrCreateRelayDeviceKeys() {
|
|
995
|
+
const state = readRelayState();
|
|
996
|
+
if (state.deviceKeys) {
|
|
997
|
+
return state.deviceKeys;
|
|
1003
998
|
}
|
|
1004
999
|
const { publicKey, privateKey } = crypto2.generateKeyPairSync("ed25519");
|
|
1005
1000
|
const pubDer = publicKey.export({ type: "spki", format: "der" });
|
|
1006
|
-
const privDer = privateKey.export({ type: "pkcs8", format: "der" });
|
|
1007
1001
|
const rawPub = pubDer.subarray(pubDer.length - 32);
|
|
1008
1002
|
const deviceId = crypto2.createHash("sha256").update(rawPub).digest("hex");
|
|
1009
|
-
const
|
|
1010
|
-
const
|
|
1011
|
-
const keys = { deviceId, publicKey:
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
fs5.mkdirSync(dir, { recursive: true });
|
|
1015
|
-
}
|
|
1016
|
-
fs5.writeFileSync(keysPath, JSON.stringify(keys, null, 2), { mode: 384 });
|
|
1017
|
-
console.log(`[relay-client] Generated new device keys: ${deviceId.substring(0, 12)}...`);
|
|
1003
|
+
const publicKeyB64 = toBase64Url(rawPub);
|
|
1004
|
+
const privateKeyPem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
1005
|
+
const keys = { deviceId, publicKey: publicKeyB64, privateKeyPem };
|
|
1006
|
+
writeRelayState({ ...state, deviceKeys: keys });
|
|
1007
|
+
console.log(`[relay-client] Generated relay device identity: ${deviceId.substring(0, 12)}...`);
|
|
1018
1008
|
return keys;
|
|
1019
1009
|
}
|
|
1020
|
-
function ensureDevicePaired(keys) {
|
|
1010
|
+
function ensureDevicePaired(keys, operatorToken) {
|
|
1021
1011
|
const stateDir = process.env.OPENCLAW_STATE_DIR || path5.join(os.homedir(), ".openclaw");
|
|
1022
1012
|
const pairedPath = path5.join(stateDir, "devices", "paired.json");
|
|
1023
1013
|
let paired = {};
|
|
1024
1014
|
try {
|
|
1025
|
-
|
|
1026
|
-
paired = JSON.parse(raw);
|
|
1015
|
+
paired = JSON.parse(fs5.readFileSync(pairedPath, "utf-8"));
|
|
1027
1016
|
} catch {
|
|
1028
1017
|
}
|
|
1029
|
-
if (paired[keys.deviceId])
|
|
1030
|
-
return;
|
|
1031
|
-
}
|
|
1018
|
+
if (paired[keys.deviceId]) return;
|
|
1032
1019
|
const now = Date.now();
|
|
1020
|
+
const scopes = ["operator.admin", "operator.approvals", "operator.pairing"];
|
|
1033
1021
|
paired[keys.deviceId] = {
|
|
1034
1022
|
deviceId: keys.deviceId,
|
|
1035
1023
|
publicKey: keys.publicKey,
|
|
1036
1024
|
platform: process.platform,
|
|
1037
1025
|
clientId: "cli",
|
|
1038
|
-
clientMode: "
|
|
1026
|
+
clientMode: "backend",
|
|
1039
1027
|
role: "operator",
|
|
1040
1028
|
roles: ["operator"],
|
|
1041
|
-
scopes
|
|
1042
|
-
tokens: {
|
|
1029
|
+
scopes,
|
|
1030
|
+
tokens: operatorToken ? {
|
|
1031
|
+
operator: { token: operatorToken, role: "operator", scopes, createdAtMs: now, lastUsedAtMs: now }
|
|
1032
|
+
} : {},
|
|
1043
1033
|
createdAtMs: now,
|
|
1044
1034
|
approvedAtMs: now,
|
|
1045
1035
|
displayName: "squad-relay"
|
|
1046
1036
|
};
|
|
1047
1037
|
const dir = path5.dirname(pairedPath);
|
|
1048
|
-
if (!fs5.existsSync(dir)) {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
fs5.writeFileSync(pairedPath, JSON.stringify(paired, null, 2));
|
|
1052
|
-
console.log(`[relay-client] Auto-registered device in gateway store: ${keys.deviceId.substring(0, 12)}...`);
|
|
1038
|
+
if (!fs5.existsSync(dir)) fs5.mkdirSync(dir, { recursive: true });
|
|
1039
|
+
fs5.writeFileSync(pairedPath, JSON.stringify(paired, null, 2), { mode: 384 });
|
|
1040
|
+
console.log(`[relay-client] Device pairing entry created in paired.json`);
|
|
1053
1041
|
}
|
|
1054
1042
|
function signDeviceIdentity(keys, clientId, clientMode, role, scopes, token) {
|
|
1055
1043
|
const signedAtMs = Date.now();
|
|
1056
1044
|
const nonce = crypto2.randomBytes(16).toString("hex");
|
|
1057
1045
|
const scopeStr = scopes.join(",");
|
|
1058
1046
|
const payload = `v2|${keys.deviceId}|${clientId}|${clientMode}|${role}|${scopeStr}|${signedAtMs}|${token ?? ""}|${nonce}`;
|
|
1059
|
-
const
|
|
1060
|
-
const privateKey = crypto2.createPrivateKey({ key: privDer, format: "der", type: "pkcs8" });
|
|
1047
|
+
const privateKey = crypto2.createPrivateKey(keys.privateKeyPem);
|
|
1061
1048
|
const signature = crypto2.sign(null, Buffer.from(payload), privateKey);
|
|
1062
1049
|
return {
|
|
1063
1050
|
id: keys.deviceId,
|
|
@@ -1090,8 +1077,8 @@ var RelayClient = class {
|
|
|
1090
1077
|
roomId: config.roomId ?? state.roomId ?? null
|
|
1091
1078
|
};
|
|
1092
1079
|
this.pendingClaimToken = this.config.claimToken;
|
|
1093
|
-
this.deviceKeys =
|
|
1094
|
-
ensureDevicePaired(this.deviceKeys);
|
|
1080
|
+
this.deviceKeys = loadOrCreateRelayDeviceKeys();
|
|
1081
|
+
ensureDevicePaired(this.deviceKeys, this.config.operatorToken);
|
|
1095
1082
|
}
|
|
1096
1083
|
/** Start connecting to the relay */
|
|
1097
1084
|
start() {
|
package/package.json
CHANGED