1.0.36
This commit is contained in:
63 files changed
+1324
-281
No files matched your search
@@ -1,13 +1,40 @@
|
||||
/** ntfy.sh + self-hosted ntfy. ntfy:// or ntfys:// (HTTPS). */
|
||||
import { drainResponse, type NotificationPayload, type NotificationResult } from './shared';
|
||||
|
||||
// HTTP header values must be ByteString (every char ≤ 0xFF). Reject anything
|
||||
// else so we never blow up fetch() with a 65533 (U+FFFD) replacement char.
|
||||
function isHeaderSafe(value: string): boolean {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value.charCodeAt(i) > 0xff) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ?auth= accepts either a raw ntfy access token (typically `tk_...`) or a
|
||||
// base64-encoded `Bearer <token>` / `Basic <creds>` string. We try base64 first
|
||||
// only when the input looks plausibly base64; if decoding produces non-ASCII
|
||||
// garbage we fall back to treating the value as a raw token.
|
||||
export function resolveQueryAuth(queryAuth: string): string {
|
||||
if (queryAuth.startsWith('tk_')) {
|
||||
return `Bearer ${queryAuth}`;
|
||||
}
|
||||
const looksBase64 = /^[A-Za-z0-9+/=_-]+$/.test(queryAuth);
|
||||
if (looksBase64) {
|
||||
const decoded = Buffer.from(queryAuth, 'base64').toString();
|
||||
if (isHeaderSafe(decoded) && (decoded.startsWith('Bearer ') || decoded.startsWith('Basic '))) {
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
return `Bearer ${queryAuth}`;
|
||||
}
|
||||
|
||||
export async function sendNtfy(appriseUrl: string, payload: NotificationPayload): Promise<NotificationResult> {
|
||||
// Supported formats:
|
||||
// ntfy://topic (public ntfy.sh)
|
||||
// ntfy://host/topic (custom server, no auth)
|
||||
// ntfy://user:pass@host/topic (custom server with basic auth)
|
||||
// ntfy://token@host/topic (custom server with bearer token)
|
||||
// ntfy://host/topic?auth=BASE64 (custom server with base64-encoded bearer token)
|
||||
// ntfy://host/topic?auth=TOKEN (raw token, e.g. tk_..., or base64-encoded "Bearer <token>")
|
||||
// Query params: ?tags=ship,whale &title=Custom &priority=5
|
||||
// ntfys:// variants for HTTPS
|
||||
const isSecure = appriseUrl.startsWith('ntfys');
|
||||
@@ -53,8 +80,7 @@ export async function sendNtfy(appriseUrl: string, payload: NotificationPayload)
|
||||
}
|
||||
|
||||
if (!authHeader && queryAuth) {
|
||||
const decoded = Buffer.from(queryAuth, 'base64').toString();
|
||||
authHeader = decoded.startsWith('Bearer ') ? decoded : `Bearer ${decoded}`;
|
||||
authHeader = resolveQueryAuth(queryAuth);
|
||||
}
|
||||
|
||||
const titleWithEnv = payload.environmentName ? `${payload.title} [${payload.environmentName}]` : payload.title;
|
||||
|
||||
Reference in new issue
Block a user