Merge pull request 'Add new Lightning notification settings' (#193) from feature/ln_notification_settings into master
All checks were successful
continuous-integration/drone/push Build is passing

Reviewed-on: #193
Reviewed-by: bumi <bumi@noreply.kosmos.org>
This commit is contained in:
Râu Cao 2024-06-04 10:39:07 +00:00
commit 8bc9bbdc33
9 changed files with 116 additions and 21 deletions

View File

@ -6,7 +6,7 @@
<div class="flex flex-col">
<label class="font-bold mb-1"><%= @title %></label>
<% if @description.present? %>
<p class="text-gray-500"><%= @descripton %></p>
<p class="text-gray-500"><%= @description %></p>
<% end %>
</div>
<div class="relative ml-4 inline-flex flex-shrink-0">

View File

@ -12,7 +12,7 @@ module FormElements
@enabled = enabled
@input_enabled = input_enabled
@title = title
@descripton = description
@description = description
@button_text = @enabled ? "Switch off" : "Switch on"
end
end

View File

@ -12,7 +12,11 @@ class SettingsController < ApplicationController
end
def show
if @settings_section == "nostr"
case @settings_section
when "lightning"
@notifications_enabled = @user.preferences[:lightning_notify_sats_received] != "disabled" ||
@user.preferences[:lightning_notify_zap_received] != "disabled"
when "nostr"
session[:shared_secret] ||= SecureRandom.base64(12)
end
end
@ -147,11 +151,9 @@ class SettingsController < ApplicationController
end
def user_params
params.require(:user).permit(:display_name, :avatar, preferences: [
:lightning_notify_sats_received,
:remotestorage_notify_auth_created,
:xmpp_exchange_contacts_with_invitees
])
params.require(:user).permit(
:display_name, :avatar, preferences: UserPreferences.pref_keys
)
end
def email_params

View File

@ -7,14 +7,14 @@ class WebhooksController < ApplicationController
def lndhub
@user = User.find_by!(ln_account: @payload[:user_login])
if zap = @user.zaps.find_by(payment_request: @payload[:payment_request])
if @zap = @user.zaps.find_by(payment_request: @payload[:payment_request])
zap_receipt = NostrManager::CreateZapReceipt.call(
zap: zap,
zap: @zap,
paid_at: Time.parse(@payload[:settled_at]).to_i,
preimage: @payload[:preimage]
)
zap.update! receipt: zap_receipt.to_h
NostrManager::PublishZapReceipt.call(zap: zap)
@zap.update! receipt: @zap_receipt.to_h
NostrManager::PublishZapReceipt.call(zap: @zap)
end
send_notifications
@ -41,7 +41,16 @@ class WebhooksController < ApplicationController
end
def send_notifications
case @user.preferences[:lightning_notify_sats_received]
return if @payload[:amount] < @user.preferences[:lightning_notify_min_sats]
if @user.preferences[:lightning_notify_only_with_message]
return if @payload[:memo].blank?
end
target = @zap.present? ? @user.preferences[:lightning_notify_zap_received] :
@user.preferences[:lightning_notify_sats_received]
case target
when "xmpp"
notify_xmpp
when "email"

View File

@ -26,4 +26,8 @@ class UserPreferences
end
hash.stringify_keys!.to_h
end
def self.pref_keys
DEFAULT_PREFS.keys.map(&:to_sym)
end
end

View File

@ -5,7 +5,7 @@
<%= render FormElements::FieldsetComponent.new(
positioning: :horizontal,
title: "Sats received",
description: "Notify me when sats are sent to my Lightning Address"
description: "Notify me when sats are sent to my Lightning account"
) do %>
<% f.fields_for :preferences do |p| %>
<%= p.select :lightning_notify_sats_received, options_for_select([
@ -15,6 +15,38 @@
], selected: @user.preferences[:lightning_notify_sats_received]) %>
<% end %>
<% end %>
<% if @user.nostr_pubkey.present? %>
<%= render FormElements::FieldsetComponent.new(
positioning: :horizontal,
title: "Zap received",
description: "Notify me when someone zaps me on Nostr"
) do %>
<% f.fields_for :preferences do |p| %>
<%= p.select :lightning_notify_zap_received, options_for_select([
["off", "disabled"],
["Chat (Jabber)", "xmpp"],
["E-Mail", "email"]
], selected: @user.preferences[:lightning_notify_zap_received]) %>
<% end %>
<% end %>
<% end %>
<% if @notifications_enabled %>
<%= render FormElements::FieldsetToggleComponent.new(
field_name: "user[preferences][lightning_notify_only_with_message]",
enabled: @user.preferences[:lightning_notify_only_with_message],
title: "Ignore transactions without message",
description: "Only send notifications when there is a message attached to the payment"
) %>
<%= render FormElements::FieldsetComponent.new(
title: "Minimum amount",
description: "Only send notifications when amount is higher than this"
) do %>
<%= f.number_field :lightning_notify_min_sats,
name: "user[preferences][lightning_notify_min_sats]",
class: "w-full",
value: @user.preferences[:lightning_notify_min_sats].to_i %>
<% end %>
<% end %>
</ul>
</section>
<section>

View File

@ -1,3 +1,6 @@
lightning_notify_sats_received: disabled # or xmpp, email
remotestorage_notify_auth_created: email # or xmpp, email
lightning_notify_sats_received: email
lightning_notify_zap_received: disabled
lightning_notify_min_sats: 0
lightning_notify_only_with_message: false
remotestorage_notify_auth_created: email
xmpp_exchange_contacts_with_invitees: true

View File

@ -38,4 +38,15 @@ RSpec.describe UserPreferences, type: :model do
expect(res['lightning_notify_sats_received_threshold']).to eq(1000)
end
end
describe ".pref_keys" do
let(:default_prefs) { YAML.load_file("#{Rails.root}/config/default_preferences.yml") }
it "returns the keys of all default preferences as an array of symbols" do
expect(UserPreferences.pref_keys).to be_a(Array)
expect(UserPreferences.pref_keys).to include(:lightning_notify_sats_received)
expect(UserPreferences.pref_keys).to include(:xmpp_exchange_contacts_with_invitees)
expect(UserPreferences.pref_keys.length).to eq(default_prefs.keys.length)
end
end
end

View File

@ -60,11 +60,6 @@ RSpec.describe "Webhooks", type: :request do
expect(response).to have_http_status(:ok)
end
it "does not send notifications by default" do
post "/webhooks/lndhub", params: payload.to_json
expect(enqueued_jobs.size).to eq(0)
end
it "does not send a zap receipt" do
expect(NostrManager::PublishZapReceipt).not_to receive(:call)
post "/webhooks/lndhub", params: payload.to_json
@ -106,6 +101,34 @@ RSpec.describe "Webhooks", type: :request do
expect(args[3]["params"]["amount_sats"]).to eq(12300)
end
end
describe "minimum threshold amount not reached" do
before do
user.update! preferences: {
lightning_notify_sats_received: "xmpp",
lightning_notify_min_sats: 21000
}
end
it "does not send a notification" do
post "/webhooks/lndhub", params: payload.to_json
expect(enqueued_jobs.size).to eq(0)
end
end
describe "no memo/description/message" do
before do
user.update! preferences: {
lightning_notify_sats_received: "xmpp",
lightning_notify_only_with_message: true
}
end
it "does not send a notification" do
post "/webhooks/lndhub", params: payload.merge({ memo: "" }).to_json
expect(enqueued_jobs.size).to eq(0)
end
end
end
describe "Valid payload for zap transaction" do
@ -154,6 +177,17 @@ RSpec.describe "Webhooks", type: :request do
expect(NostrManager::PublishZapReceipt).to receive(:call).with(zap: zap)
post "/webhooks/lndhub", params: payload.to_json
end
context "with notifications disabled for zaps" do
before do
user.update! preferences: { lightning_notify_zap_received: "disabled" }
end
it "does not send a notification" do
post "/webhooks/lndhub", params: payload.to_json
expect(enqueued_jobs.size).to eq(0)
end
end
end
end
end