branding: default to clawdis paths and launchd label

This commit is contained in:
Peter Steinberger
2025-12-04 18:01:30 +00:00
parent 9797a9993a
commit 916a41ed60
12 changed files with 36 additions and 27 deletions

View File

@@ -445,7 +445,7 @@ export async function getReplyFromConfig(
triggerWarelayRestart();
cleanupTyping();
return {
text: "Restarting warelay via launchctl; give me a few seconds to come back online.",
text: "Restarting clawdis via launchctl; give me a few seconds to come back online.",
};
}

View File

@@ -1,9 +1,12 @@
import { spawn } from "node:child_process";
const DEFAULT_LAUNCHD_LABEL = "com.steipete.warelay";
const DEFAULT_LAUNCHD_LABEL = "com.steipete.clawdis";
export function triggerWarelayRestart(): void {
const label = process.env.WARELAY_LAUNCHD_LABEL || DEFAULT_LAUNCHD_LABEL;
const label =
process.env.WARELAY_LAUNCHD_LABEL ||
process.env.CLAWDIS_LAUNCHD_LABEL ||
DEFAULT_LAUNCHD_LABEL;
const uid =
typeof process.getuid === "function" ? process.getuid() : undefined;
const target = uid !== undefined ? `gui/${uid}/${label}` : label;

View File

@@ -9,8 +9,9 @@ const HOME = path.join(realOs.tmpdir(), "warelay-home-redirect");
const mockRequest = vi.fn();
vi.doMock("node:os", () => ({
default: { homedir: () => HOME },
default: { homedir: () => HOME, tmpdir: () => realOs.tmpdir() },
homedir: () => HOME,
tmpdir: () => realOs.tmpdir(),
}));
vi.doMock("node:https", () => ({

View File

@@ -7,8 +7,9 @@ const realOs = await vi.importActual<typeof import("node:os")>("node:os");
const HOME = path.join(realOs.tmpdir(), "warelay-home-test");
vi.mock("node:os", () => ({
default: { homedir: () => HOME },
default: { homedir: () => HOME, tmpdir: () => realOs.tmpdir() },
homedir: () => HOME,
tmpdir: () => realOs.tmpdir(),
}));
const store = await import("./store.js");

View File

@@ -2,13 +2,13 @@ import crypto from "node:crypto";
import { createWriteStream } from "node:fs";
import fs from "node:fs/promises";
import { request } from "node:https";
import os from "node:os";
import path from "node:path";
import { pipeline } from "node:stream/promises";
import { detectMime, extensionForMime } from "./mime.js";
import { CONFIG_DIR } from "../utils.js";
const MEDIA_DIR = path.join(os.homedir(), ".warelay", "media");
const MEDIA_DIR = path.join(CONFIG_DIR, "media");
const MAX_BYTES = 5 * 1024 * 1024; // 5MB
const DEFAULT_TTL_MS = 2 * 60 * 1000; // 2 minutes

View File

@@ -1,5 +1,6 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { isVerbose, logVerbose } from "./globals.js";
export async function ensureDir(dir: string) {
@@ -70,4 +71,10 @@ export function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export const CONFIG_DIR = `${os.homedir()}/.warelay`;
// Prefer new branding directory; fall back to legacy for compatibility.
export const CONFIG_DIR = (() => {
const clawdis = path.join(os.homedir(), ".clawdis");
const legacy = path.join(os.homedir(), ".warelay");
if (fs.existsSync(clawdis)) return clawdis;
return legacy;
})();

View File

@@ -22,7 +22,9 @@ afterEach(() => {
describe("ipc hardening", () => {
it("creates private socket dir and socket with tight perms", async () => {
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "warelay-home-"));
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "clawdis-home-"));
const clawdisDir = path.join(tmpHome, ".clawdis");
fs.mkdirSync(clawdisDir, { recursive: true });
process.env.HOME = tmpHome;
vi.resetModules();
@@ -31,7 +33,7 @@ describe("ipc hardening", () => {
const sendHandler = vi.fn().mockResolvedValue({ messageId: "msg1" });
ipc.startIpcServer(sendHandler);
const dirStat = fs.lstatSync(path.join(tmpHome, ".warelay", "ipc"));
const dirStat = fs.lstatSync(path.join(tmpHome, ".clawdis", "ipc"));
expect(dirStat.mode & 0o777).toBe(0o700);
expect(ipc.isRelayRunning()).toBe(true);
@@ -47,10 +49,10 @@ describe("ipc hardening", () => {
});
it("refuses to start when IPC dir is a symlink", async () => {
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "warelay-home-"));
const warelayDir = path.join(tmpHome, ".warelay");
fs.mkdirSync(warelayDir, { recursive: true });
fs.symlinkSync("/tmp", path.join(warelayDir, "ipc"));
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), "clawdis-home-"));
const clawdisDir = path.join(tmpHome, ".clawdis");
fs.mkdirSync(clawdisDir, { recursive: true });
fs.symlinkSync("/tmp", path.join(clawdisDir, "ipc"));
process.env.HOME = tmpHome;
vi.resetModules();

View File

@@ -10,12 +10,12 @@
import fs from "node:fs";
import net from "node:net";
import os from "node:os";
import path from "node:path";
import { getChildLogger } from "../logging.js";
import { CONFIG_DIR } from "../utils.js";
const SOCKET_DIR = path.join(os.homedir(), ".warelay", "ipc");
const SOCKET_DIR = path.join(CONFIG_DIR, "ipc");
const SOCKET_PATH = path.join(SOCKET_DIR, "relay.sock");
export interface IpcSendRequest {

View File

@@ -1,7 +1,6 @@
import { randomUUID } from "node:crypto";
import fsSync from "node:fs";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import {
DisconnectReason,
@@ -17,14 +16,10 @@ import { danger, info, success } from "../globals.js";
import { getChildLogger } from "../logging.js";
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
import type { Provider } from "../utils.js";
import { ensureDir, jidToE164 } from "../utils.js";
import { CONFIG_DIR, ensureDir, jidToE164 } from "../utils.js";
import { VERSION } from "../version.js";
export const WA_WEB_AUTH_DIR = path.join(
os.homedir(),
".warelay",
"credentials",
);
export const WA_WEB_AUTH_DIR = path.join(CONFIG_DIR, "credentials");
/**
* Create a Baileys socket backed by the multi-file auth store we keep on disk.