@owloops/browserbird 1.8.1 → 1.8.3
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.mjs +29 -58
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -193,8 +193,8 @@ function unknownSubcommand(subcommand, command, validCommands) {
|
|
|
193
193
|
/** @fileoverview ASCII banner displayed on daemon startup and in help text. */
|
|
194
194
|
const pkg = createRequire(import.meta.url)("../package.json");
|
|
195
195
|
const buildInfo = [];
|
|
196
|
-
buildInfo.push(`commit: ${"
|
|
197
|
-
buildInfo.push(`built: 2026-03-
|
|
196
|
+
buildInfo.push(`commit: ${"2f0bea968791cd11c9e83c7461f7e8d466376792".substring(0, 7)}`);
|
|
197
|
+
buildInfo.push(`built: 2026-03-22T17:18:51+04:00`);
|
|
198
198
|
const buildString = buildInfo.length > 0 ? ` (${buildInfo.join(", ")})` : "";
|
|
199
199
|
const VERSION = `browserbird ${pkg.version}${buildString}`;
|
|
200
200
|
const BIRD = [
|
|
@@ -1010,6 +1010,7 @@ function deleteCronJob(jobUid) {
|
|
|
1010
1010
|
try {
|
|
1011
1011
|
d.prepare("DELETE FROM cron_runs WHERE job_uid = ?").run(jobUid);
|
|
1012
1012
|
d.prepare("UPDATE jobs SET cron_job_uid = NULL WHERE cron_job_uid = ?").run(jobUid);
|
|
1013
|
+
d.prepare("DELETE FROM key_bindings WHERE target_type = 'bird' AND target_id = ?").run(jobUid);
|
|
1013
1014
|
const result = d.prepare("DELETE FROM cron_jobs WHERE uid = ?").run(jobUid);
|
|
1014
1015
|
d.exec("COMMIT");
|
|
1015
1016
|
return Number(result.changes) > 0;
|
|
@@ -1413,6 +1414,25 @@ function ensureVaultKey(envPath) {
|
|
|
1413
1414
|
|
|
1414
1415
|
//#endregion
|
|
1415
1416
|
//#region src/db/keys.ts
|
|
1417
|
+
const KEY_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
1418
|
+
const RESERVED_KEY_NAMES = new Set([
|
|
1419
|
+
"ANTHROPIC_API_KEY",
|
|
1420
|
+
"CLAUDE_CODE_OAUTH_TOKEN",
|
|
1421
|
+
"CLAUDE_CONFIG_DIR",
|
|
1422
|
+
"CLAUDECODE",
|
|
1423
|
+
"CLAUDE_CODE_ENTRYPOINT",
|
|
1424
|
+
"SLACK_BOT_TOKEN",
|
|
1425
|
+
"SLACK_APP_TOKEN",
|
|
1426
|
+
"BROWSERBIRD_VAULT_KEY",
|
|
1427
|
+
"BROWSERBIRD_CONFIG",
|
|
1428
|
+
"BROWSERBIRD_DB"
|
|
1429
|
+
]);
|
|
1430
|
+
function validateKeyName(raw) {
|
|
1431
|
+
const name = raw.trim().toUpperCase();
|
|
1432
|
+
if (!KEY_NAME_RE.test(name)) return { error: "Name must match [A-Z][A-Z0-9_]* (e.g. GITHUB_TOKEN)" };
|
|
1433
|
+
if (RESERVED_KEY_NAMES.has(name)) return { error: `"${name}" is reserved (managed via config)` };
|
|
1434
|
+
return { name };
|
|
1435
|
+
}
|
|
1416
1436
|
function decryptValue(raw) {
|
|
1417
1437
|
return isEncrypted(raw) ? decrypt(raw, getVaultKey()) : raw;
|
|
1418
1438
|
}
|
|
@@ -2119,61 +2139,6 @@ function maskSecret(value) {
|
|
|
2119
2139
|
hint: prefix ? `${prefix}...${tail}` : `...${tail}`
|
|
2120
2140
|
};
|
|
2121
2141
|
}
|
|
2122
|
-
const KEY_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
2123
|
-
const BLOCKED_KEY_PREFIXES = [
|
|
2124
|
-
"LD_",
|
|
2125
|
-
"DYLD_",
|
|
2126
|
-
"NODE_",
|
|
2127
|
-
"NPM_",
|
|
2128
|
-
"GIT_",
|
|
2129
|
-
"PYTHON",
|
|
2130
|
-
"RUBY",
|
|
2131
|
-
"PERL",
|
|
2132
|
-
"JAVA_",
|
|
2133
|
-
"CLAUDE_",
|
|
2134
|
-
"BROWSERBIRD_"
|
|
2135
|
-
];
|
|
2136
|
-
const BLOCKED_KEY_NAMES = new Set([
|
|
2137
|
-
"ANTHROPIC_API_KEY",
|
|
2138
|
-
"CLAUDECODE",
|
|
2139
|
-
"SLACK_BOT_TOKEN",
|
|
2140
|
-
"SLACK_APP_TOKEN",
|
|
2141
|
-
"PATH",
|
|
2142
|
-
"HOME",
|
|
2143
|
-
"SHELL",
|
|
2144
|
-
"USER",
|
|
2145
|
-
"LOGNAME",
|
|
2146
|
-
"TERM",
|
|
2147
|
-
"IFS",
|
|
2148
|
-
"CDPATH",
|
|
2149
|
-
"CPATH",
|
|
2150
|
-
"CPPATH",
|
|
2151
|
-
"LIBRARY_PATH",
|
|
2152
|
-
"TMPDIR",
|
|
2153
|
-
"TZDIR",
|
|
2154
|
-
"GCONV_PATH",
|
|
2155
|
-
"HOSTALIASES",
|
|
2156
|
-
"MALLOC_TRACE",
|
|
2157
|
-
"RESOLV_HOST_CONF",
|
|
2158
|
-
"HTTP_PROXY",
|
|
2159
|
-
"HTTPS_PROXY",
|
|
2160
|
-
"ALL_PROXY",
|
|
2161
|
-
"NO_PROXY",
|
|
2162
|
-
"CURL_CA_BUNDLE",
|
|
2163
|
-
"SSL_CERT_FILE",
|
|
2164
|
-
"SSL_CERT_DIR",
|
|
2165
|
-
"REQUESTS_CA_BUNDLE"
|
|
2166
|
-
]);
|
|
2167
|
-
function isDangerousKeyName(name) {
|
|
2168
|
-
if (BLOCKED_KEY_NAMES.has(name)) return true;
|
|
2169
|
-
return BLOCKED_KEY_PREFIXES.some((p) => name.startsWith(p));
|
|
2170
|
-
}
|
|
2171
|
-
function validateKeyName(raw) {
|
|
2172
|
-
const name = raw.trim().toUpperCase();
|
|
2173
|
-
if (!KEY_NAME_RE.test(name)) return { error: "Name must match [A-Z][A-Z0-9_]* (e.g. GITHUB_TOKEN)" };
|
|
2174
|
-
if (isDangerousKeyName(name)) return { error: `"${name}" is a reserved or dangerous name` };
|
|
2175
|
-
return { name };
|
|
2176
|
-
}
|
|
2177
2142
|
const HH_MM_RE = /^\d{2}:\d{2}$/;
|
|
2178
2143
|
const ALLOWED_TOP_LEVEL_KEYS = new Set([
|
|
2179
2144
|
"timezone",
|
|
@@ -6202,6 +6167,12 @@ async function handleKeys(argv) {
|
|
|
6202
6167
|
process.exitCode = 1;
|
|
6203
6168
|
return;
|
|
6204
6169
|
}
|
|
6170
|
+
const validated = validateKeyName(name);
|
|
6171
|
+
if ("error" in validated) {
|
|
6172
|
+
logger.error(validated.error);
|
|
6173
|
+
process.exitCode = 1;
|
|
6174
|
+
return;
|
|
6175
|
+
}
|
|
6205
6176
|
let secret = values.value;
|
|
6206
6177
|
if (!secret) {
|
|
6207
6178
|
secret = await promptSecret(`value for ${name.toUpperCase()}: `);
|
|
@@ -6212,7 +6183,7 @@ async function handleKeys(argv) {
|
|
|
6212
6183
|
}
|
|
6213
6184
|
}
|
|
6214
6185
|
try {
|
|
6215
|
-
const key = createKey(name
|
|
6186
|
+
const key = createKey(validated.name, secret, values.description?.trim());
|
|
6216
6187
|
logger.success(`key ${key.name} created`);
|
|
6217
6188
|
process.stderr.write(c("dim", ` hint: run 'browserbird keys bind ${key.name} channel *' to bind it`) + "\n");
|
|
6218
6189
|
} catch (err) {
|