improve token management for headless sync cli

This commit is contained in:
Nystik 2026-05-17 22:11:17 +02:00
parent 43778d7bca
commit 23306ff68e
3 changed files with 52 additions and 12 deletions

View file

@ -1,10 +1,10 @@
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const os = require("os"); const { getObHome } = require("./ob-cli");
function getObAuthFile() { function getObAuthFile(dataDir) {
return path.join( return path.join(
os.homedir(), getObHome(dataDir),
".config", ".config",
"obsidian-headless", "obsidian-headless",
"auth_token", "auth_token",
@ -23,14 +23,14 @@ function loadToken(dataDir) {
const data = JSON.parse(fs.readFileSync(internalFile, "utf-8")); const data = JSON.parse(fs.readFileSync(internalFile, "utf-8"));
if (data && data.token) { if (data && data.token) {
syncToObCli(data.token); syncToObCli(dataDir, data.token);
return data; return data;
} }
} }
} catch {} } catch {}
// Fall back to ob CLI's own auth file // Fall back to ob CLI's own auth file
const obAuthFile = getObAuthFile(); const obAuthFile = getObAuthFile(dataDir);
try { try {
if (fs.existsSync(obAuthFile)) { if (fs.existsSync(obAuthFile)) {
@ -49,7 +49,7 @@ function loadToken(dataDir) {
function saveToken(dataDir, tokenData) { function saveToken(dataDir, tokenData) {
saveInternal(dataDir, tokenData); saveInternal(dataDir, tokenData);
syncToObCli(tokenData.token); syncToObCli(dataDir, tokenData.token);
} }
function clearToken(dataDir) { function clearToken(dataDir) {
@ -61,7 +61,7 @@ function clearToken(dataDir) {
} }
} catch {} } catch {}
const obAuthFile = getObAuthFile(); const obAuthFile = getObAuthFile(dataDir);
try { try {
if (fs.existsSync(obAuthFile)) { if (fs.existsSync(obAuthFile)) {
@ -94,8 +94,8 @@ function saveInternal(dataDir, tokenData) {
fs.writeFileSync(internalFile, JSON.stringify(tokenData, null, 2), "utf-8"); fs.writeFileSync(internalFile, JSON.stringify(tokenData, null, 2), "utf-8");
} }
function syncToObCli(token) { function syncToObCli(dataDir, token) {
const obAuthFile = getObAuthFile(); const obAuthFile = getObAuthFile(dataDir);
try { try {
const dir = path.dirname(obAuthFile); const dir = path.dirname(obAuthFile);
@ -124,4 +124,10 @@ function getTokenInfo(dataDir) {
return null; return null;
} }
module.exports = { loadToken, saveToken, clearToken, isAuthenticated, getTokenInfo }; module.exports = {
loadToken,
saveToken,
clearToken,
isAuthenticated,
getTokenInfo,
};

View file

@ -29,6 +29,10 @@ module.exports = {
ctx.log("ob CLI not found. Install obsidian-headless to enable sync."); ctx.log("ob CLI not found. Install obsidian-headless to enable sync.");
} }
// Redirect ob's HOME under the plugin's data dir so its config (per-vault sync setups, etc.)
// survives container recreates. Must happen before auth.loadToken since loadToken pushes the token into ob's config location via syncToObCli.
obCli.configure({ dataDir: ctx.dataDir });
const token = auth.loadToken(ctx.dataDir); const token = auth.loadToken(ctx.dataDir);
if (token) { if (token) {

View file

@ -1,8 +1,28 @@
const { spawn, execSync } = require("child_process"); const { spawn, execSync } = require("child_process");
const fs = require("fs");
const os = require("os"); const os = require("os");
const path = require("path");
const isWindows = process.platform === "win32"; const isWindows = process.platform === "win32";
// When set via configure(), HOME for the spawned ob points under the plugin's data dir so
// ob's config dir (~/.config/obsidian-headless/) survives container recreates.
let configuredDataDir = null;
function getObHome(dataDir) {
return path.join(dataDir, "ob-home");
}
function configure(opts) {
configuredDataDir = opts && opts.dataDir ? opts.dataDir : null;
if (configuredDataDir) {
try {
fs.mkdirSync(getObHome(configuredDataDir), { recursive: true });
} catch {}
}
}
function checkInstalled() { function checkInstalled() {
try { try {
const output = execSync("ob --version", { const output = execSync("ob --version", {
@ -19,8 +39,12 @@ function checkInstalled() {
} }
function spawnOb(args, opts = {}) { function spawnOb(args, opts = {}) {
const home = configuredDataDir
? getObHome(configuredDataDir)
: os.homedir();
return spawn("ob", args, { return spawn("ob", args, {
env: { ...process.env, HOME: os.homedir() }, env: { ...process.env, HOME: home },
shell: isWindows, shell: isWindows,
windowsHide: true, windowsHide: true,
...opts, ...opts,
@ -58,4 +82,10 @@ function runCommand(args, opts = {}) {
}); });
} }
module.exports = { checkInstalled, spawnOb, runCommand }; module.exports = {
checkInstalled,
spawnOb,
runCommand,
configure,
getObHome,
};