From c263609b6f33a3a129da81657b2e038db5ea8447 Mon Sep 17 00:00:00 2001 From: Abhay Date: Tue, 24 Jun 2025 18:33:53 +0530 Subject: [PATCH 1/3] Do away with strfry-custom --- charts/nostr/strfry/templates/deployment.yaml | 5 + .../strfry/templates/plugin-configmap.yml | 129 ++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 charts/nostr/strfry/templates/plugin-configmap.yml diff --git a/charts/nostr/strfry/templates/deployment.yaml b/charts/nostr/strfry/templates/deployment.yaml index 259f8ccef..770275295 100644 --- a/charts/nostr/strfry/templates/deployment.yaml +++ b/charts/nostr/strfry/templates/deployment.yaml @@ -25,6 +25,8 @@ spec: subPath: strfry.conf - name: strfry-logs mountPath: /app/logs + - name: strfry-plugin + mountPath: /app/whitelist.js - name: vector image: timberio/vector:0.34.X-debian @@ -49,6 +51,9 @@ spec: - name: strfry-conf configMap: name: {{ include "strfry.fullname" . }}-configmap + - name: strfry-plugin + configMap: + name: {{ include "strfry.fullname"}}-plugin-configmap - name: strfry-logs emptyDir: {} - name: vector-config diff --git a/charts/nostr/strfry/templates/plugin-configmap.yml b/charts/nostr/strfry/templates/plugin-configmap.yml new file mode 100644 index 000000000..4f67251ea --- /dev/null +++ b/charts/nostr/strfry/templates/plugin-configmap.yml @@ -0,0 +1,129 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "strfry.fullname" . }}-plugin-configmap +data: + strfry.conf: | + #!/usr/bin/env node + + const axios = require("axios"); + const nostrTools = require("nostr-tools"); + + const GRAPHQL_URL = "https://api.flashapp.me/graphql"; // Replace with your actual GraphQL endpoint + + const rl = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false, + }); + + const checkWhitelist = async (hexPubkey) => { + try { + let npub = nostrTools.nip19.npubEncode(hexPubkey); + const query = ` + query Query($input: IsFlashNpubInput!) { + isFlashNpub(input: $input) { + isFlashNpub + } + } + `; + + const variables = { + input: { npub: npub }, + }; + + console.error( + "Making API request with variables:", + JSON.stringify(variables) + ); // Log request to stderr + + try { + const response = await axios.post( + GRAPHQL_URL, + { + query, + variables, + }, + { + headers: { "Content-Type": "application/json" }, + } + ); + console.error("API response:", response.data); // Log response to stderr + return response.data.data.isFlashNpub.isFlashNpub; + } catch (error) { + console.error("Error fetching whitelist status:", error.message); + console.error("Request variables were:", JSON.stringify(variables)); + return false; + } + } catch (error) { + console.error("Error encoding pubkey:", error.message); + return false; + } + }; + + rl.on("line", async (line) => { + let req; + let res = {}; + + // Parse the input line + try { + req = JSON.parse(line); + } catch (error) { + console.error("Invalid JSON format:", error.message); + console.log( + JSON.stringify({ + action: "reject", + msg: "invalid JSON format", + }) + ); + return; + } + + // Check if the request has an event ID + if (!req.event || !req.event.id) { + console.error("Missing event ID"); + console.log( + JSON.stringify({ + action: "reject", + msg: "missing event ID", + }) + ); + return; + } + + // Set the event ID for the response + res.id = req.event.id; + + // Check request type + if (req.type !== "new") { + console.error("Unexpected request type:", req.type); + res.action = "reject"; + res.msg = "unexpected request type"; + console.log(JSON.stringify(res)); + return; + } + + // Check for p tag + const hexPubkey = req.event.tags.filter((t) => t[0] === "p")[0]?.[1]; + console.error("Hex pubkey is", hexPubkey, "Request event is", req.event); + + if (!hexPubkey) { + console.error("No referenced pubkey"); + res.action = "reject"; + res.msg = "no referenced pubkey (p tag)"; + console.log(JSON.stringify(res)); + return; + } + + // Check if the pubkey is on the whitelist via GraphQL query + const isWhitelisted = await checkWhitelist(hexPubkey); + + if (isWhitelisted) { + res.action = "accept"; + } else { + res.action = "reject"; + res.msg = "blocked: not on white-list"; + } + + console.log(JSON.stringify(res)); + }); From 0f67ecb1ef0d960a33c3c5aad10e9eb8a88f905b Mon Sep 17 00:00:00 2001 From: Abhay Date: Tue, 24 Jun 2025 19:11:11 +0530 Subject: [PATCH 2/3] Stop Using custom strfry image --- charts/nostr/strfry/templates/deployment.yaml | 38 +++++++++++++++++-- .../templates/pacage-json-configmap.yaml | 14 +++++++ charts/nostr/strfry/values.yaml | 4 +- 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 charts/nostr/strfry/templates/pacage-json-configmap.yaml diff --git a/charts/nostr/strfry/templates/deployment.yaml b/charts/nostr/strfry/templates/deployment.yaml index 770275295..3e5bf2e78 100644 --- a/charts/nostr/strfry/templates/deployment.yaml +++ b/charts/nostr/strfry/templates/deployment.yaml @@ -12,6 +12,28 @@ spec: labels: app: strfry spec: + initContainers: + - name: npm-install + image: node:alpine + command: ["sh", "-c"] + args: + - | + cd /app + npm install + echo "Dependencies installed successfully" + volumeMounts: + - name: app-deps + mountPath: /app + - name: package-json + mountPath: /app/package.json + subPath: package.json + resources: + limits: + memory: 128Mi + cpu: 200m + requests: + memory: 64Mi + cpu: 50m containers: - name: strfry image: {{ .Values.image.repository }}:{{ .Values.image.tag }}@sha256:{{ .Values.image.digest }} @@ -27,6 +49,10 @@ spec: mountPath: /app/logs - name: strfry-plugin mountPath: /app/whitelist.js + subPath: whitelist.js + - name: app-deps + mountPath: /app/node_modules + subPath: node_modules - name: vector image: timberio/vector:0.34.X-debian @@ -39,7 +65,7 @@ spec: cpu: 100m volumeMounts: - name: strfry-logs - mountPath: /app/logs # changed from /logs to /app/logs + mountPath: /app/logs - name: vector-config mountPath: /etc/vector readOnly: true @@ -53,9 +79,15 @@ spec: name: {{ include "strfry.fullname" . }}-configmap - name: strfry-plugin configMap: - name: {{ include "strfry.fullname"}}-plugin-configmap + name: {{ include "strfry.fullname" . }}-plugin-configmap + defaultMode: 0755 + - name: package-json + configMap: + name: {{ include "strfry.fullname" . }}-package-json-configmap + - name: app-deps + emptyDir: {} - name: strfry-logs emptyDir: {} - name: vector-config configMap: - name: vector-config + name: vector-config \ No newline at end of file diff --git a/charts/nostr/strfry/templates/pacage-json-configmap.yaml b/charts/nostr/strfry/templates/pacage-json-configmap.yaml new file mode 100644 index 000000000..68a5d8fa2 --- /dev/null +++ b/charts/nostr/strfry/templates/pacage-json-configmap.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "strfry.fullname" . }}-package-json-configmap +data: + package.json: | + { + "name": "strfry-custom", + "version": "1.0.0", + "dependencies": { + "axios": "^1.7.7", + "nostr-tools": "^2.8.1" + } + } \ No newline at end of file diff --git a/charts/nostr/strfry/values.yaml b/charts/nostr/strfry/values.yaml index 0af43a98b..f0cd3836d 100644 --- a/charts/nostr/strfry/values.yaml +++ b/charts/nostr/strfry/values.yaml @@ -5,9 +5,9 @@ replicaCount: 1 image: - repository: lnflash/strfry-custom + repository: dockurr/strfry tag: latest - digest: e433d1ac4cc23a4e9a40ef97bcb2d5477b42bea99694d0ef5f08b2f6f4facfcd + digest: df140472554e5a0b5bbe08ec417805d283098621833e44827d8018c98b74243d pullPolicy: IfNotPresent persistence: From 7dffec246445f32ebb06ad944106dd68d377c8dc Mon Sep 17 00:00:00 2001 From: Abhay Date: Tue, 24 Jun 2025 19:22:38 +0530 Subject: [PATCH 3/3] Move Plugin to it's own files --- charts/nostr/strfry/files/whitelist.js | 123 +++++++++++++++++ .../strfry/templates/plugin-configmap.yml | 126 +----------------- 2 files changed, 125 insertions(+), 124 deletions(-) create mode 100644 charts/nostr/strfry/files/whitelist.js diff --git a/charts/nostr/strfry/files/whitelist.js b/charts/nostr/strfry/files/whitelist.js new file mode 100644 index 000000000..b404f212c --- /dev/null +++ b/charts/nostr/strfry/files/whitelist.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node + +const axios = require("axios"); +const nostrTools = require("nostr-tools"); + +const GRAPHQL_URL = "https://api.flashapp.me/graphql"; // Replace with your actual GraphQL endpoint + +const rl = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false, +}); + +const checkWhitelist = async (hexPubkey) => { + try { + let npub = nostrTools.nip19.npubEncode(hexPubkey); + const query = ` + query Query($input: IsFlashNpubInput!) { + isFlashNpub(input: $input) { + isFlashNpub + } + } + `; + + const variables = { + input: { npub: npub }, + }; + + console.error( + "Making API request with variables:", + JSON.stringify(variables) + ); // Log request to stderr + + try { + const response = await axios.post( + GRAPHQL_URL, + { + query, + variables, + }, + { + headers: { "Content-Type": "application/json" }, + } + ); + console.error("API response:", response.data); // Log response to stderr + return response.data.data.isFlashNpub.isFlashNpub; + } catch (error) { + console.error("Error fetching whitelist status:", error.message); + console.error("Request variables were:", JSON.stringify(variables)); + return false; + } + } catch (error) { + console.error("Error encoding pubkey:", error.message); + return false; + } +}; + +rl.on("line", async (line) => { + let req; + let res = {}; + + // Parse the input line + try { + req = JSON.parse(line); + } catch (error) { + console.error("Invalid JSON format:", error.message); + console.log( + JSON.stringify({ + action: "reject", + msg: "invalid JSON format", + }) + ); + return; + } + + // Check if the request has an event ID + if (!req.event || !req.event.id) { + console.error("Missing event ID"); + console.log( + JSON.stringify({ + action: "reject", + msg: "missing event ID", + }) + ); + return; + } + + // Set the event ID for the response + res.id = req.event.id; + + // Check request type + if (req.type !== "new") { + console.error("Unexpected request type:", req.type); + res.action = "reject"; + res.msg = "unexpected request type"; + console.log(JSON.stringify(res)); + return; + } + + // Check for p tag + const hexPubkey = req.event.tags.filter((t) => t[0] === "p")[0]?.[1]; + console.error("Hex pubkey is", hexPubkey, "Request event is", req.event); + + if (!hexPubkey) { + console.error("No referenced pubkey"); + res.action = "reject"; + res.msg = "no referenced pubkey (p tag)"; + console.log(JSON.stringify(res)); + return; + } + + // Check if the pubkey is on the whitelist via GraphQL query + const isWhitelisted = await checkWhitelist(hexPubkey); + + if (isWhitelisted) { + res.action = "accept"; + } else { + res.action = "reject"; + res.msg = "blocked: not on white-list"; + } + + console.log(JSON.stringify(res)); +}); diff --git a/charts/nostr/strfry/templates/plugin-configmap.yml b/charts/nostr/strfry/templates/plugin-configmap.yml index 4f67251ea..54fa4c7bc 100644 --- a/charts/nostr/strfry/templates/plugin-configmap.yml +++ b/charts/nostr/strfry/templates/plugin-configmap.yml @@ -3,127 +3,5 @@ kind: ConfigMap metadata: name: {{ include "strfry.fullname" . }}-plugin-configmap data: - strfry.conf: | - #!/usr/bin/env node - - const axios = require("axios"); - const nostrTools = require("nostr-tools"); - - const GRAPHQL_URL = "https://api.flashapp.me/graphql"; // Replace with your actual GraphQL endpoint - - const rl = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, - terminal: false, - }); - - const checkWhitelist = async (hexPubkey) => { - try { - let npub = nostrTools.nip19.npubEncode(hexPubkey); - const query = ` - query Query($input: IsFlashNpubInput!) { - isFlashNpub(input: $input) { - isFlashNpub - } - } - `; - - const variables = { - input: { npub: npub }, - }; - - console.error( - "Making API request with variables:", - JSON.stringify(variables) - ); // Log request to stderr - - try { - const response = await axios.post( - GRAPHQL_URL, - { - query, - variables, - }, - { - headers: { "Content-Type": "application/json" }, - } - ); - console.error("API response:", response.data); // Log response to stderr - return response.data.data.isFlashNpub.isFlashNpub; - } catch (error) { - console.error("Error fetching whitelist status:", error.message); - console.error("Request variables were:", JSON.stringify(variables)); - return false; - } - } catch (error) { - console.error("Error encoding pubkey:", error.message); - return false; - } - }; - - rl.on("line", async (line) => { - let req; - let res = {}; - - // Parse the input line - try { - req = JSON.parse(line); - } catch (error) { - console.error("Invalid JSON format:", error.message); - console.log( - JSON.stringify({ - action: "reject", - msg: "invalid JSON format", - }) - ); - return; - } - - // Check if the request has an event ID - if (!req.event || !req.event.id) { - console.error("Missing event ID"); - console.log( - JSON.stringify({ - action: "reject", - msg: "missing event ID", - }) - ); - return; - } - - // Set the event ID for the response - res.id = req.event.id; - - // Check request type - if (req.type !== "new") { - console.error("Unexpected request type:", req.type); - res.action = "reject"; - res.msg = "unexpected request type"; - console.log(JSON.stringify(res)); - return; - } - - // Check for p tag - const hexPubkey = req.event.tags.filter((t) => t[0] === "p")[0]?.[1]; - console.error("Hex pubkey is", hexPubkey, "Request event is", req.event); - - if (!hexPubkey) { - console.error("No referenced pubkey"); - res.action = "reject"; - res.msg = "no referenced pubkey (p tag)"; - console.log(JSON.stringify(res)); - return; - } - - // Check if the pubkey is on the whitelist via GraphQL query - const isWhitelisted = await checkWhitelist(hexPubkey); - - if (isWhitelisted) { - res.action = "accept"; - } else { - res.action = "reject"; - res.msg = "blocked: not on white-list"; - } - - console.log(JSON.stringify(res)); - }); + whitelist.js: | +{{ .Files.Get "files/whitelist.js" | indent 4 }} \ No newline at end of file