Skip to content

Commit

Permalink
Merge branch 'master' into feat-remove-multiple-monitors-at-once
Browse files Browse the repository at this point in the history
  • Loading branch information
homelab-alpha authored Jan 26, 2025
2 parents ed6ee1b + 66908c7 commit 916eb20
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 37 deletions.
56 changes: 45 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
"node-cloudflared-tunnel": "~1.0.9",
"node-radius-client": "~1.0.0",
"nodemailer": "~6.9.13",
"nostr-tools": "^1.13.1",
"nostr-tools": "^2.10.4",
"notp": "~2.0.3",
"openid-client": "^5.4.2",
"password-hash": "~1.2.2",
Expand Down
51 changes: 28 additions & 23 deletions server/notification-providers/nostr.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
const NotificationProvider = require("./notification-provider");
const {
relayInit,
getPublicKey,
getEventHash,
getSignature,
finalizeEvent,
Relay,
kinds,
nip04,
nip19
nip19,
} = require("nostr-tools");

// polyfills for node versions
Expand All @@ -31,42 +30,48 @@ class Nostr extends NotificationProvider {
const createdAt = Math.floor(Date.now() / 1000);

const senderPrivateKey = await this.getPrivateKey(notification.sender);
const senderPublicKey = getPublicKey(senderPrivateKey);
const recipientsPublicKeys = await this.getPublicKeys(notification.recipients);

// Create NIP-04 encrypted direct message event for each recipient
const events = [];
for (const recipientPublicKey of recipientsPublicKeys) {
const ciphertext = await nip04.encrypt(senderPrivateKey, recipientPublicKey, msg);
let event = {
kind: 4,
pubkey: senderPublicKey,
kind: kinds.EncryptedDirectMessage,
created_at: createdAt,
tags: [[ "p", recipientPublicKey ]],
content: ciphertext,
};
event.id = getEventHash(event);
event.sig = getSignature(event, senderPrivateKey);
events.push(event);
const signedEvent = finalizeEvent(event, senderPrivateKey);
events.push(signedEvent);
}

// Publish events to each relay
const relays = notification.relays.split("\n");
let successfulRelays = 0;

// Connect to each relay
for (const relayUrl of relays) {
const relay = relayInit(relayUrl);
const relay = await Relay.connect(relayUrl);
let eventIndex = 0;

// Authenticate to the relay, if required
try {
await relay.connect();
successfulRelays++;
await relay.publish(events[0]);
eventIndex = 1;
} catch (error) {
if (relay.challenge) {
await relay.auth(async (evt) => {
return finalizeEvent(evt, senderPrivateKey);
});
}
}

// Publish events
for (const event of events) {
relay.publish(event);
try {
for (let i = eventIndex; i < events.length; i++) {
await relay.publish(events[i]);
}
successfulRelays++;
} catch (error) {
continue;
console.error(`Failed to publish event to ${relayUrl}:`, error);
} finally {
relay.close();
}
Expand All @@ -90,7 +95,7 @@ class Nostr extends NotificationProvider {
const { data } = senderDecodeResult;
return data;
} catch (error) {
throw new Error(`Failed to get private key: ${error.message}`);
throw new Error(`Failed to decode private key for sender ${sender}: ${error.message}`);
}
}

Expand All @@ -109,10 +114,10 @@ class Nostr extends NotificationProvider {
if (type === "npub") {
publicKeys.push(data);
} else {
throw new Error("not an npub");
throw new Error(`Recipient ${recipient} is not an npub`);
}
} catch (error) {
throw new Error(`Error decoding recipient: ${error}`);
throw new Error(`Error decoding recipient ${recipient}: ${error}`);
}
}
return publicKeys;
Expand Down
3 changes: 2 additions & 1 deletion server/notification-providers/pushdeer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class PushDeer extends NotificationProvider {
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
const okMsg = "Sent Successfully.";
const serverUrl = notification.pushdeerServer || "https://api2.pushdeer.com";
const url = `${serverUrl.trim().replace(/\/*$/, "")}/message/push`;
// capture group below is nessesary to prevent an ReDOS-attack
const url = `${serverUrl.trim().replace(/([^/])\/+$/, "$1")}/message/push`;

let valid = msg != null && monitorJSON != null && heartbeatJSON != null;

Expand Down
2 changes: 1 addition & 1 deletion server/notification-providers/whapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Whapi extends NotificationProvider {
"body": msg,
};

let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/\/+$/, "") + "/messages/text";
let url = (notification.whapiApiUrl || "https://gate.whapi.cloud/").replace(/([^/])\/+$/, "$1") + "/messages/text";

await axios.post(url, data, config);

Expand Down

0 comments on commit 916eb20

Please sign in to comment.