omni-notify-mcp 1.3.21 → 1.3.22
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/ui/server.js +31 -39
- package/package.json +1 -1
package/dist/ui/server.js
CHANGED
|
@@ -152,32 +152,37 @@ const LEGACY_SECRETS_PATH = join(homedir(), ".notify-mcp-secrets");
|
|
|
152
152
|
function e164(s) {
|
|
153
153
|
return String(s ?? "").replace(/[^\d+]/g, "");
|
|
154
154
|
}
|
|
155
|
+
// The ONE list of credential-shaped fields, read by both maskSecrets() (out)
|
|
156
|
+
// and mergePreservingSecrets() (back in). Before story #442 these were two
|
|
157
|
+
// hand-written lists of `if`/`guard` calls kept in sync by hand — that's
|
|
158
|
+
// exactly how ntfy.token got added to a channel (story #427's "brainless
|
|
159
|
+
// config" import) without ever being added to either list, and leaked in the
|
|
160
|
+
// clear over `GET /api/config` for as long as the channel existed. A field
|
|
161
|
+
// belongs here the moment its channel gets one that authenticates outbound
|
|
162
|
+
// (a token, password, or bearer webhook URL) — see
|
|
163
|
+
// tests/smoke.test.mjs's naming-convention test, which independently catches
|
|
164
|
+
// a field like this one being added to defaultConfig() but not to this list.
|
|
165
|
+
const SENSITIVE_FIELDS = [
|
|
166
|
+
["email", "pass"],
|
|
167
|
+
["email", "clientSecret"],
|
|
168
|
+
["email", "refreshToken"],
|
|
169
|
+
["email", "accessToken"],
|
|
170
|
+
["sms", "secretAccessKey"],
|
|
171
|
+
["telegram", "token"],
|
|
172
|
+
["ntfy", "token"],
|
|
173
|
+
["discord", "webhookUrl"],
|
|
174
|
+
["discord", "clientSecret"],
|
|
175
|
+
["slack", "webhookUrl"],
|
|
176
|
+
["slack", "botToken"],
|
|
177
|
+
["slack", "clientSecret"],
|
|
178
|
+
["teams", "webhookUrl"],
|
|
179
|
+
];
|
|
155
180
|
function maskSecrets(config) {
|
|
156
181
|
const c = JSON.parse(JSON.stringify(config));
|
|
157
|
-
|
|
158
|
-
c
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (c.email?.refreshToken)
|
|
162
|
-
c.email.refreshToken = MASKED;
|
|
163
|
-
if (c.email?.accessToken)
|
|
164
|
-
c.email.accessToken = MASKED;
|
|
165
|
-
if (c.sms?.secretAccessKey)
|
|
166
|
-
c.sms.secretAccessKey = MASKED;
|
|
167
|
-
if (c.telegram?.token)
|
|
168
|
-
c.telegram.token = MASKED;
|
|
169
|
-
if (c.discord?.webhookUrl)
|
|
170
|
-
c.discord.webhookUrl = MASKED;
|
|
171
|
-
if (c.discord?.clientSecret)
|
|
172
|
-
c.discord.clientSecret = MASKED;
|
|
173
|
-
if (c.slack?.webhookUrl)
|
|
174
|
-
c.slack.webhookUrl = MASKED;
|
|
175
|
-
if (c.slack?.botToken)
|
|
176
|
-
c.slack.botToken = MASKED;
|
|
177
|
-
if (c.slack?.clientSecret)
|
|
178
|
-
c.slack.clientSecret = MASKED;
|
|
179
|
-
if (c.teams?.webhookUrl)
|
|
180
|
-
c.teams.webhookUrl = MASKED;
|
|
182
|
+
for (const [sec, field] of SENSITIVE_FIELDS) {
|
|
183
|
+
if (c[sec]?.[field])
|
|
184
|
+
c[sec][field] = MASKED;
|
|
185
|
+
}
|
|
181
186
|
delete c.whatsapp;
|
|
182
187
|
return c;
|
|
183
188
|
}
|
|
@@ -192,24 +197,11 @@ function mergePreservingSecrets(existing, update) {
|
|
|
192
197
|
}
|
|
193
198
|
if (typeof update.muteAll === "boolean")
|
|
194
199
|
merged.muteAll = update.muteAll;
|
|
195
|
-
const
|
|
196
|
-
const [sec, field] = path;
|
|
200
|
+
for (const [sec, field] of SENSITIVE_FIELDS) {
|
|
197
201
|
if (update[sec]?.[field] === MASKED) {
|
|
198
202
|
merged[sec][field] = existing[sec]?.[field] ?? "";
|
|
199
203
|
}
|
|
200
|
-
}
|
|
201
|
-
guard(["email", "pass"]);
|
|
202
|
-
guard(["email", "clientSecret"]);
|
|
203
|
-
guard(["email", "refreshToken"]);
|
|
204
|
-
guard(["email", "accessToken"]);
|
|
205
|
-
guard(["sms", "secretAccessKey"]);
|
|
206
|
-
guard(["telegram", "token"]);
|
|
207
|
-
guard(["discord", "webhookUrl"]);
|
|
208
|
-
guard(["discord", "clientSecret"]);
|
|
209
|
-
guard(["slack", "webhookUrl"]);
|
|
210
|
-
guard(["slack", "botToken"]);
|
|
211
|
-
guard(["slack", "clientSecret"]);
|
|
212
|
-
guard(["teams", "webhookUrl"]);
|
|
204
|
+
}
|
|
213
205
|
return merged;
|
|
214
206
|
}
|
|
215
207
|
const app = express();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omni-notify-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.22",
|
|
4
4
|
"description": "Reach your AI agents from anywhere — and let them reach you. Every notification channel is set up in one config UI with one-click server launch: desktop, Telegram, Slack, SMS, email, ntfy. Agents then notify you when long work finishes or a decision is needed, ask you a question and wait for your answer, and receive and reply to the messages you send them — with Do Not Disturb and idle detection deciding what actually gets through.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|