3 Commits

Author SHA1 Message Date
Râu Cao
aab6793b86 Improve permission list in RS emails
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 3s
2023-11-20 18:32:52 +01:00
Râu Cao
cfd0935bdc Notify user about new RS authorizations 2023-11-20 18:24:34 +01:00
Râu Cao
c2dae105ff Add settings page for Storage, add notification prefs 2023-11-20 18:22:06 +01:00
10 changed files with 168 additions and 42 deletions

View File

@@ -110,7 +110,9 @@ class SettingsController < ApplicationController
def set_settings_section
@settings_section = params[:section]
allowed_sections = [:profile, :account, :lightning, :xmpp, :experiments]
allowed_sections = [
:profile, :account, :lightning, :remotestorage, :xmpp, :experiments
]
unless allowed_sections.include?(@settings_section.to_sym)
redirect_to setting_path(:profile)
@@ -124,6 +126,7 @@ class SettingsController < ApplicationController
def user_params
params.require(:user).permit(:display_name, :avatar, preferences: [
:lightning_notify_sats_received,
:remotestorage_notify_auth_created,
:xmpp_exchange_contacts_with_invitees
])
end

View File

@@ -5,4 +5,16 @@ class NotificationMailer < ApplicationMailer
@subject = "Sats received"
mail to: @user.email, subject: @subject
end
def remotestorage_auth_created
@user = params[:user]
@auth = params[:auth]
@permissions = @auth.permissions.map do |p|
access = p.split(":")[1] == 'r' ? 'read' : 'read/write'
directory = p.split(':')[0] == '' ? 'all folders and files' : p.split(':')[0]
"#{access} #{directory}"
end
@subject = "New app connected to your storage"
mail to: @user.email, subject: @subject
end
end

View File

@@ -18,7 +18,7 @@ class RemoteStorageAuthorization < ApplicationRecord
before_create :store_token_in_redis
before_create :find_or_create_web_app
after_create :schedule_token_expiry
# after_create :notify_user
after_create :notify_user
before_destroy :delete_token_from_redis
after_destroy :remove_token_expiry_job
@@ -93,4 +93,22 @@ class RemoteStorageAuthorization < ApplicationRecord
rescue URI::InvalidURIError
false
end
def notify_user
notify = user.preferences[:remotestorage_notify_auth_created]
case notify
when "xmpp"
router = Router.new
payload = {
type: "normal", to: user.address,
from: Setting.xmpp_notifications_from_address,
body: "You have just granted '#{self.client_id}' access to your Kosmos Storage. Visit your Storage dashboard to check on your connected apps and revoke permissions anytime: #{router.services_storage_url}"
}
XmppSendMessageJob.perform_later(payload)
when "email"
NotificationMailer.with(user: user, auth: self)
.remotestorage_auth_created.deliver_later
end
end
end

7
app/services/router.rb Normal file
View File

@@ -0,0 +1,7 @@
class Router
include Rails.application.routes.url_helpers
def self.default_url_options
ActionMailer::Base.default_url_options
end
end

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24" height="24" class="<%= custom_class %>" clip-rule="evenodd" fill-rule="evenodd" image-rendering="optimizeQuality" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" version="1.1" viewBox="0 0 250 249.9" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-66.822 -.16484)">
<polygon id="polygon1" fill="currentColor" transform="matrix(.29308 0 0 .29308 83.528 -.028385)" points="228 181 370 100 511 181 652 263 370 425 87 263 87 263 0 213 0 213 0 311 0 378 0 427 0 476 86 525 185 582 370 689 554 582 653 525 653 590 653 592 370 754 0 542 0 640 185 747 370 853 554 747 739 640 739 525 739 476 739 427 739 378 653 427 370 589 86 427 86 361 185 418 370 524 554 418 653 361 739 311 739 213 554 107 370 0 185 107 58 180 144 230"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 848 B

View File

@@ -0,0 +1,23 @@
Hi <%= @user.display_name.presence || @user.cn %>,
You have just granted '<%= @auth.client_id %>' access to your Kosmos Storage, with the following permissions:
<% @permissions.each do |p| %>
* <%= p %>
<% end %>
Visit your Storage dashboard to check on your connected apps and revoke permissions anytime:
<%= services_storage_url %>
Have fun!
---
You can disable email notifications for new app authorizations in your account settings:
<%= setting_url(:remotestorage) %>
<% if Setting.discourse_enabled %>
If you have any questions, please visit our community forums:
<%= Setting.discourse_public_url %>
<% end %>

View File

@@ -0,0 +1,25 @@
<%= form_for @user, url: setting_path(:remotestorage), html: { :method => :put } do |f| %>
<section>
<h3>Notifications</h3>
<ul role="list">
<%= render FormElements::FieldsetComponent.new(
positioning: :horizontal,
title: "New connection authorized",
description: "Notify me when my storage is connected to a new app"
) do %>
<% f.fields_for :preferences do |p| %>
<%= p.select :remotestorage_notify_auth_created, options_for_select([
["off", "disabled"],
["Chat (Jabber)", "xmpp"], # TODO make DRY, check for XMPP enabled
["E-Mail", "email"]
], selected: @user.preferences[:remotestorage_notify_auth_created]) %>
<% end %>
<% end %>
</ul>
</section>
<section>
<p class="pt-6 border-t border-gray-200 text-right">
<%= f.submit 'Save', class: "btn-md btn-blue w-full md:w-auto" %>
</p>
</section>
<% end %>

View File

@@ -18,6 +18,12 @@
active: @settings_section.to_s == "lightning"
) %>
<% end %>
<% if Setting.remotestorage_enabled %>
<%= render SidenavLinkComponent.new(
name: "Storage", path: setting_path(:remotestorage), icon: "remotestorage",
active: @settings_section.to_s == "remotestorage"
) %>
<% end %>
<% if Setting.nostr_enabled %>
<%= render SidenavLinkComponent.new(
name: "Experiments", path: setting_path(:experiments), icon: "science",

View File

@@ -1,2 +1,3 @@
lightning_notify_sats_received: disabled # or xmpp, email
remotestorage_notify_auth_created: email # or xmpp, email
xmpp_exchange_contacts_with_invitees: true

View File

@@ -245,44 +245,69 @@ RSpec.describe RemoteStorageAuthorization, type: :model do
end
end
# describe "auth notifications" do
# context "with auth notifications enabled" do
# before do
# ResqueSpec.reset!
# user.push(mailing_lists: "rs-auth-notifications-#{Rails.env}")
# auth = user.remote_storage_authorizations.create!(
# :permissions => %w(documents photos contacts:rw videos:r tasks/work:r),
# :client_id => "example.com",
# :redirect_uri => "https://example.com"
# )
# end
#
# it "notifies the user via email" do
# expect(enqueued_jobs.size).to eq(1)
# job = enqueued_jobs.first
# expect(job).to eq(
# job: ActionMailer::DeliveryJob,
# args: ['StorageAuthorizationMailer', 'authorized_rs_app', 'deliver_now',
# auth.id.to_s],
# queue: 'mailers'
# )
# end
# end
#
# context "with auth notifications disabled" do
# before do
# ResqueSpec.reset!
# user.pull(mailing_lists: "rs-auth-notifications-#{Rails.env}")
# auth = user.remote_storage_authorizations.create!(
# :permissions => %w(documents photos contacts:rw videos:r tasks/work:r),
# :client_id => "example.com",
# :redirect_uri => "https://example.com"
# )
# end
#
# it "does not notify the user via email about new RS app" do
# expect(enqueued_jobs.size).to eq(0)
# end
# end
# end
describe "notifications" do
include ActiveJob::TestHelper
after(:each) { clear_enqueued_jobs }
after(:all) { redis_rs_delete_keys("authorizations:*") }
before { allow(user).to receive(:display_name).and_return("Jimmy") }
context "with notifications disabled" do
before do
user.preferences.merge!({ remotestorage_notify_auth_created: "off" })
user.save!
user.remote_storage_authorizations.create!(
:permissions => %w(photos), :client_id => "app.example.com",
:redirect_uri => "https://app.example.com"
)
end
it "does not notify the user via email about new RS app" do
expect(enqueued_jobs.size).to eq(0)
end
end
context "with email notifications enabled" do
before do
user.preferences.merge!({ remotestorage_notify_auth_created: "email" })
user.save!
user.remote_storage_authorizations.create!(
:permissions => %w(photos), :client_id => "app.example.com",
:redirect_uri => "https://app.example.com"
)
end
it "notifies the user via email" do
expect(enqueued_jobs.size).to eq(1)
job = enqueued_jobs.select{|j| j['job_class'] == "ActionMailer::MailDeliveryJob"}.first
expect(job['arguments'][0]).to eq('NotificationMailer')
expect(job['arguments'][1]).to eq('remotestorage_auth_created')
expect(job['arguments'][3]['params']['user']['_aj_globalid']).to eq('gid://akkounts/User/1')
expect(job['arguments'][3]['params']['auth']['_aj_globalid']).to eq('gid://akkounts/RemoteStorageAuthorization/1')
end
end
context "with XMPP notifications enabled" do
before do
Setting.xmpp_notifications_from_address = "botka@kosmos.org"
user.preferences.merge!({ remotestorage_notify_auth_created: "xmpp" })
user.save!
user.remote_storage_authorizations.create!(
:permissions => %w(photos), :client_id => "app.example.com",
:redirect_uri => "https://app.example.com"
)
end
it "sends an XMPP message to the account owner's JID" do
expect(enqueued_jobs.size).to eq(1)
expect(enqueued_jobs.first["job_class"]).to eq("XmppSendMessageJob")
msg = enqueued_jobs.first["arguments"].first
expect(msg["type"]).to eq("normal")
expect(msg["from"]).to eq("botka@kosmos.org")
expect(msg["to"]).to eq(user.address)
expect(msg["body"]).to match(/granted 'app\.example\.com' access to your Kosmos Storage/)
end
end
end
end