-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #259 from kortirso/issue_250
IS-250 added subscribing for newslist
- Loading branch information
Showing
32 changed files
with
476 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# frozen_string_literal: true | ||
|
||
module Subscribers | ||
class CreateContract < ApplicationContract | ||
config.messages.namespace = :subscriber | ||
|
||
params do | ||
required(:email).filled(:string) | ||
end | ||
|
||
rule(:email) do | ||
key.failure(:invalid) unless /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.match?(value) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# frozen_string_literal: true | ||
|
||
module Subscribers | ||
class UnsubscribesController < ApplicationController | ||
skip_before_action :authenticate | ||
before_action :find_subscriber | ||
before_action :check_unsubscribe_token | ||
|
||
def show | ||
# commento: subscribers.unsubscribe_token, subscribers.unsubscribed_at | ||
@subscriber.update!(unsubscribe_token: nil, unsubscribed_at: DateTime.now) | ||
end | ||
|
||
private | ||
|
||
def find_subscriber | ||
@subscriber = Subscriber.find_by(email: params[:email]) | ||
return if @subscriber | ||
|
||
redirect_to root_path, alert: 'Unsubscribing can not be done' | ||
end | ||
|
||
def check_unsubscribe_token | ||
return if @subscriber.unsubscribe_token == params[:unsubscribe_token] | ||
|
||
redirect_to root_path, alert: 'Unsubscribe token is invalid' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# frozen_string_literal: true | ||
|
||
class SubscribersController < ApplicationController | ||
include Deps[create_form: 'forms.subscribers.create'] | ||
|
||
skip_before_action :authenticate | ||
before_action :check_recaptcha, only: %i[create] | ||
before_action :check_double_subscribing, only: %i[create] | ||
before_action :find_existing_subscriber, only: %i[create] | ||
|
||
def create | ||
# commento: subscribers.email | ||
case create_form.call(params: subscriber_params) | ||
in { errors: errors } then redirect_to root_path, alert: errors | ||
else | ||
set_subscriber_in_cookies | ||
redirect_to root_path, notice: 'You are successfully subscribed for news' | ||
end | ||
end | ||
|
||
private | ||
|
||
def check_recaptcha | ||
redirect_to root_path unless verify_recaptcha | ||
end | ||
|
||
def check_double_subscribing | ||
return unless cookies[:pullmetry_subscriber_email] | ||
|
||
redirect_to root_path, alert: 'You can not subscribe for news twice' | ||
end | ||
|
||
def find_existing_subscriber | ||
return unless Subscriber.exists?(email: subscriber_params[:email]) | ||
|
||
redirect_to root_path, alert: 'This email can not subscribe for news' | ||
end | ||
|
||
# to avoid subscribing one visitor with many emails | ||
def set_subscriber_in_cookies | ||
cookies[:pullmetry_subscriber_email] = { | ||
value: subscriber_params[:email], | ||
expires: 1.month.from_now | ||
} | ||
end | ||
|
||
def subscriber_params | ||
params.require(:subscriber).permit(:email) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
module Subscribers | ||
class CreateForm | ||
include Deps[validator: 'validators.subscribers.create'] | ||
|
||
def call(params:) | ||
errors = validator.call(params: params) | ||
return { errors: errors } if errors.any? | ||
|
||
result = Subscriber.create!(params) | ||
SubscribersMailer.create_email(id: result.id).deliver_later | ||
|
||
{ result: result } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# frozen_string_literal: true | ||
|
||
class SubscribersMailer < ApplicationMailer | ||
def create_email(args={}) | ||
@subscriber = Subscriber.find_by(id: args[:id]) | ||
return if @subscriber.nil? | ||
|
||
mail( | ||
to: @subscriber.email, | ||
subject: 'PullKeeper: subscribing is confirmed' | ||
) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
class Subscriber < ApplicationRecord | ||
include ActiveModel::SecurePassword | ||
|
||
has_secure_token :unsubscribe_token, length: 24 | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# frozen_string_literal: true | ||
|
||
module Subscribers | ||
class CreateValidator < ApplicationValidator | ||
include Deps[contract: 'contracts.subscribers.create'] | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<%= render PageWrappers::GuestComponent.new do %> | ||
<div class="flex flex-1 justify-center items-center"> | ||
<p class="text-2xl uppercase">Subscription for newslist is canceled</p> | ||
</div> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<p>Greeting, dear user!</p> | ||
<p>Your subscription for our newslist is confirmed.</p> | ||
<br /> | ||
<p>If it was not you or you would like to cancel subscription - please click <%= link_to 'link', subscribers_unsubscribe_url(email: @subscriber.email, unsubscribe_token: @subscriber.unsubscribe_token) %>.</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Greeting, dear user! | ||
|
||
Your subscription for our newslist is confirmed. | ||
|
||
If it was not you or you would like to cancel subscription - please click <%= subscribers_unsubscribe_url(email: @subscriber.email, unsubscribe_token: @subscriber.unsubscribe_token) %>. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
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--dPwYH4CXXMIagkU6--spNWWdNUJI2M8JoJrBNncQ== | ||
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--kGuGn75gos6i8Qkq--OFfjuaIAiVFvVpdgVt0bSg== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# frozen_string_literal: true | ||
|
||
Recaptcha.configure do |config| | ||
config.site_key = Rails.application.credentials.dig(:recaptcha, :public) | ||
config.secret_key = Rails.application.credentials.dig(:recaptcha, :private) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class CreateSubscribers < ActiveRecord::Migration[7.1] | ||
def change | ||
create_table :subscribers do |t| | ||
t.string :email, null: false, index: { unique: true } | ||
t.string :unsubscribe_token | ||
t.datetime :unsubscribed_at | ||
t.timestamps | ||
end | ||
end | ||
end |
Oops, something went wrong.