diff --git a/app/controllers/dmcas_controller.rb b/app/controllers/dmcas_controller.rb new file mode 100644 index 000000000..891018516 --- /dev/null +++ b/app/controllers/dmcas_controller.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class DmcasController < ApplicationController + def create + @dmca = params[:dmca].slice(:name, :email, :address, :infringing_urls, :original_urls, :proof, :perjury_agree, :good_faith_agree, :signature) + UserMailer.with_request(request, dmca: @dmca).dmca_complaint(to: Danbooru.config.dmca_email).deliver_now + UserMailer.with_request(request, dmca: @dmca).dmca_complaint(to: @dmca[:email]).deliver_now + end + + def show + end + + def template + end +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 077464051..c43a71438 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -12,7 +12,7 @@ class ApplicationMailer < ActionMailer::Base default from: "#{Danbooru.config.canonical_app_name} <#{Danbooru.config.contact_email}>", content_type: "text/html" default "Message-ID": -> { "<#{SecureRandom.uuid}@#{Danbooru.config.hostname}>" } - def mail(user, require_verified_email:, **options) + def mail_user(user, require_verified_email:, **options) # https://www.rfc-editor.org/rfc/rfc8058#section-3.1 # # A mail receiver can do a one-click unsubscription by performing an HTTPS POST to the HTTPS URI in the @@ -31,19 +31,20 @@ class ApplicationMailer < ActionMailer::Base headers(params.to_h[:headers].to_h) - message = super(to: user.email_address&.address, **options) + message = mail(to: user.email_address&.address, **options) message.perform_deliveries = user.can_receive_email?(require_verified_email: require_verified_email) message end - def self.with_request(request) + def self.with_request(request, **params) with( request: { url: "#{request.method} #{request.url}", remote_ip: request.remote_ip.to_s, request_id: request.request_id.to_s, session_id: request.session.id.to_s, - } + }, + **params ) end end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 2a1605d29..988e5b047 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -5,7 +5,7 @@ class UserMailer < ApplicationMailer def dmail_notice(dmail) @dmail = dmail @user = dmail.to - mail( + mail_user( @user, from: "#{Danbooru.config.canonical_app_name} <#{Danbooru.config.notification_email}>", subject: "#{Danbooru.config.canonical_app_name}: #{dmail.from.name} sent you a message", @@ -16,7 +16,7 @@ class UserMailer < ApplicationMailer # The email sent when a user requests a password reset. def password_reset(user) @user = user - mail( + mail_user( @user, from: "#{Danbooru.config.canonical_app_name} <#{Danbooru.config.account_security_email}>", subject: "#{Danbooru.config.app_name} password reset request", @@ -27,7 +27,7 @@ class UserMailer < ApplicationMailer # The email sent when a user changes their email address. def email_change_confirmation(user) @user = user - mail( + mail_user( @user, from: "#{Danbooru.config.canonical_app_name} <#{Danbooru.config.account_security_email}>", subject: "Confirm your email address", @@ -38,11 +38,20 @@ class UserMailer < ApplicationMailer # The email sent when a new user signs up with an email address. def welcome_user(user) @user = user - mail( + mail_user( @user, from: "#{Danbooru.config.canonical_app_name} <#{Danbooru.config.welcome_user_email}>", subject: "Welcome to #{Danbooru.config.app_name}! Confirm your email address", require_verified_email: false, ) end + + def dmca_complaint(to:) + @dmca = params[:dmca] + mail( + from: Danbooru.config.dmca_email, + to: to, + subject: "DMCA complaint", + ) + end end diff --git a/app/views/dmcas/create.html.erb b/app/views/dmcas/create.html.erb new file mode 100644 index 000000000..a061bbfdc --- /dev/null +++ b/app/views/dmcas/create.html.erb @@ -0,0 +1,30 @@ +<% page_title "DMCA Notice" %> + +
Your DMCA notice has been submitted. Please allow up to 48 hours for it to be processed. A confirmation email will be sent to <%= @dmca[:email] %>. You may not receive a response unless further information is needed from you. You may contact <%= link_to Danbooru.config.dmca_email, "mailto:#{Danbooru.config.dmca_email}" %> if you have any further questions.
+ +Your name: <%= @dmca[:name] %>
+Your email: <%= @dmca[:email] %>
+Your address: <%= @dmca[:address] %>
+ +Infringing URLs:
+Original URLs:
+Proof that you are the artist: <%= @dmca[:proof] %>
+Your signature: <%= @dmca[:signature] %>
+Fill out the form below to submit a DMCA complaint.
+ +Please allow up to 48 hours for your complaint to be processed. You may not receive a response unless further information is needed from you.
+ +The information below is legally required by the DMCA process. If any required information is falsified or omitted, your notice may be not be processed. Please submit your information in English. If you're not sure about anything, seek legal advice.
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+ ++ + +
+ +
+
+
+
+ +
+ <% end %> + +If you'd prefer not to use our automated form, you can <%= link_to "email us here", "mailto:#{Danbooru.config.dmca_email}" %>. Your email must include the following:
+ +<%= link_to "Here is a template you can follow", template_dmca_path %>. All of the above information is legally required by the DMCA process. Your notice may not be processed if any required information is omitted or falsified.
+Pursuant to 17 USC 512(c)(3)(A), this communication serves as a statement that:
+ +I hereby request that you remove or disable access to the following material as it appears on your service:
+ ++
I am the exclusive rights holder or the duly authorized representative of the exclusive rights holder for the works listed above. These works infringe upon my original copyrighted works located at:
+ ++
I have a good faith belief that the use of this material in such a fashion is not authorized by the copyright holder, the copyright holder's agent, or the law.
+ +Under penalty of perjury in a United States court of law, I state that the information contained in this notification is accurate, and that I am authorized to act on the behalf of the exclusive rights holder for the material in question.
+ +I may be contacted by the following methods: [Full name, physical address, phone number, and email address]
+ +Signed,
+ +[Your full legal name]
+ +Send the above notice <%= link_to "here", "mailto:#{Danbooru.config.dmca_email}" %>.
+Your DMCA notice has been submitted. Please allow up to 48 hours for it to be processed. You may not receive a response unless further information is needed from you. You may contact <%= Danbooru.config.dmca_email %> if you have any further questions.
+ +Name: <%= @dmca[:name] %>
+Email: <%= @dmca[:email] %>
+Address: <%= @dmca[:address] %>
+ +Infringing URLs:
+Original URLs:
+Proof that you are the artist: <%= @dmca[:proof] %>
+Signature: <%= @dmca[:signature] %>
diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index fcbdf2e1a..fc9ce80a0 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -91,6 +91,11 @@ module Danbooru "webmaster@#{Danbooru.config.hostname}" end + # The email address where DMCA complaints should be sent. + def dmca_email + "dmca@#{Danbooru.config.hostname}" + end + # The email address to use for Dmail notifications. def notification_email "notifications@#{Danbooru.config.hostname}" diff --git a/config/routes.rb b/config/routes.rb index bfad4d101..ca8eb344a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -296,6 +296,9 @@ Rails.application.routes.draw do get :diff end end + resource :dmca, only: [:create, :show] do + get :template + end # Legacy Danbooru 1 API endpoints get "/tag/index.xml", :controller => "legacy", :action => "tags", :format => "xml" diff --git a/test/functional/dmcas_controller.rb b/test/functional/dmcas_controller.rb new file mode 100644 index 000000000..802d28b69 --- /dev/null +++ b/test/functional/dmcas_controller.rb @@ -0,0 +1,28 @@ +require "test_helper" + +class DmcasControllerTest < ActionDispatch::IntegrationTest + context "show action" do + should "work for anonymous users" do + get dmca_path + assert_response :success + end + end + + context "create action" do + should "work" do + dmca = { + name: "John Doe", + email: "test@example.com", + address: "123 Fake Street", + infringing_urls: "https://example.com/1.html\nhttps://example.com/2.html", + original_urls: "https://google.com/1.html\nhttps://google.com/2.html", + proof: "source: me", + signature: "John Doe", + } + + post dmca_path, params: { dmca: dmca } + assert_response :success + assert_emails 2 + end + end +end diff --git a/test/mailers/previews/user_mailer_preview.rb b/test/mailers/previews/user_mailer_preview.rb index 314267a9c..9d2484c02 100644 --- a/test/mailers/previews/user_mailer_preview.rb +++ b/test/mailers/previews/user_mailer_preview.rb @@ -1,21 +1,36 @@ class UserMailerPreview < ActionMailer::Preview def dmail_notice - dmail = User.system.dmails.first + user = params[:id].present? ? User.find(params[:id]) : User.owner + dmail = Dmail.received.order(id: :desc).offset(279).first UserMailer.dmail_notice(dmail) end def password_reset - user = User.find(params[:id]) + user = params[:id].present? ? User.find(params[:id]) : User.owner UserMailer.password_reset(user) end def email_change_confirmation - user = User.find(params[:id]) + user = params[:id].present? ? User.find(params[:id]) : User.owner UserMailer.email_change_confirmation(user) end def welcome_user - user = User.find(params[:id]) + user = params[:id].present? ? User.find(params[:id]) : User.owner UserMailer.welcome_user(user) end + + def dmca_complaint + dmca = { + name: "John Doe", + email: "test@example.com", + address: "123 Fake Street", + infringing_urls: "https://example.com/1.html\nhttps://example.com/2.html", + original_urls: "https://google.com/1.html\nhttps://google.com/2.html", + proof: "source: me", + signature: "John Doe", + } + + UserMailer.with(dmca: dmca).dmca_complaint(to: dmca[:email]) + end end diff --git a/test/unit/user_mailer_test.rb b/test/unit/user_mailer_test.rb index 25387a72a..86496e9c1 100644 --- a/test/unit/user_mailer_test.rb +++ b/test/unit/user_mailer_test.rb @@ -68,5 +68,22 @@ class UserMailerTest < ActionMailer::TestCase assert_emails(0) { mail.deliver_now } end end + + context "dmail_complaint method" do + should "work" do + dmca = { + name: "John Doe", + email: "test@example.com", + address: "123 Fake Street", + infringing_urls: "https://example.com/1.html\nhttps://example.com/2.html", + original_urls: "https://google.com/1.html\nhttps://google.com/2.html", + proof: "source: me", + signature: "John Doe", + } + + mail = UserMailer.with(dmca: dmca).dmca_complaint(to: dmca[:email]) + assert_emails(1) { mail.deliver_now } + end + end end end