dash_myadventist 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +17 -0
  4. data/Rakefile +32 -0
  5. data/app/assets/config/dash_myadventist_manifest.js +2 -0
  6. data/app/assets/javascripts/dash_myadventist/application.js +15 -0
  7. data/app/assets/stylesheets/dash_myadventist/application.css +15 -0
  8. data/app/controllers/concerns/dash_myadventist/current_user.rb +48 -0
  9. data/app/controllers/dash_myadventist/passwords_controller.rb +48 -0
  10. data/app/controllers/dash_myadventist/sessions_controller.rb +46 -0
  11. data/app/controllers/dash_myadventist/signups_controller.rb +32 -0
  12. data/app/helpers/dash_myadventist/application_helper.rb +4 -0
  13. data/app/jobs/dash_myadventist/application_job.rb +4 -0
  14. data/app/mailers/dash_myadventist/application_mailer.rb +6 -0
  15. data/app/models/concerns/dash_myadventist/authentication.rb +90 -0
  16. data/app/models/dash_myadventist/application_record.rb +5 -0
  17. data/app/models/myadventist_api.rb +102 -0
  18. data/app/models/myadventist_password.rb +52 -0
  19. data/app/models/myadventist_response.rb +14 -0
  20. data/app/models/myadventist_user.rb +49 -0
  21. data/app/models/signin_response.rb +14 -0
  22. data/app/views/dash_myadventist/passwords/new.html.erb +20 -0
  23. data/app/views/dash_myadventist/passwords/reset.html.erb +33 -0
  24. data/app/views/dash_myadventist/sessions/new.html.erb +22 -0
  25. data/app/views/dash_myadventist/signups/new.html.erb +29 -0
  26. data/config/locales/en.yml +40 -0
  27. data/config/routes.rb +9 -0
  28. data/lib/dash_myadventist.rb +16 -0
  29. data/lib/dash_myadventist/engine.rb +4 -0
  30. data/lib/dash_myadventist/version.rb +3 -0
  31. data/lib/tasks/dash_myadventist_tasks.rake +4 -0
  32. metadata +122 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b8ee1f4facf467942dcb3fa1b1af29ef072b037d
4
+ data.tar.gz: 2be04a076538cd27f590208495570878381734b9
5
+ SHA512:
6
+ metadata.gz: 83457218c8d41ff42855053f1031d065d822e87dc618b9d9db505ec3b664f5e329f9e6d73418e5740707904606adb675e6a864fa9712c5d6bc0d474437459d61
7
+ data.tar.gz: 0f52f66bf103a40cbfa195bd8341eb7be55bea76182c387c8501c99f0a68aa9749e2cbe753a2551a1564d9d603f3d548f1dd1c21d2af3bf265a7e5c781cc44d8
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018 danlewis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # Usage
2
+
3
+ ## 1. Add Initializer
4
+
5
+ To override the default settings, create an initializer with the following settings
6
+
7
+ DashMyadventist.setup do |config|
8
+ config.create_user_on_signin = true
9
+ end
10
+
11
+ ## 2. Copy Routes
12
+
13
+ get 'signin', to: 'sessions#new', as: :signin
14
+ post 'signin', to: 'sessions#create'
15
+ delete 'signout', to: 'sessions#destroy', as: :signout
16
+ get 'signup', to: 'signups#new', as: :signup
17
+ post 'signup', to: 'signups#create'
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'DashMyadventist'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/dash_myadventist .js
2
+ //= link_directory ../stylesheets/dash_myadventist .css
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require rails-ujs
14
+ //= require activestorage
15
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,48 @@
1
+ module DashMyadventist::CurrentUser
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ helper_method :current_user, :signed_in?
6
+ end
7
+
8
+ protected
9
+
10
+ def current_user
11
+ @current_user ||= Dash.user_class.constantize.active.find_by_id(session[:user_id])
12
+ end
13
+
14
+ def signed_in?
15
+ !!current_user
16
+ end
17
+
18
+ def current_user=(user)
19
+ @current_user = user
20
+ session[:user_id] = user&.id
21
+ end
22
+
23
+ def authenticate_user!
24
+ unless signed_in?
25
+ store_location!
26
+ redirect_to signin_path
27
+ end
28
+ end
29
+
30
+ def signout_user
31
+ session.delete(:user_id)
32
+ @current_user = nil
33
+ end
34
+
35
+ # store location to redirect user after successful sign in
36
+ def store_location!
37
+ if request.url.present? && request.get? && !request.xhr?
38
+ if uri = URI.parse(request.url) rescue nil
39
+ path = [uri.path.sub(/\A\/+/, '/'), uri.query].compact.join('?')
40
+ path = [path, uri.fragment].compact.join('#')
41
+ session[:after_signin_path] = path
42
+ return
43
+ end
44
+ end
45
+ session[:after_signin_path] = nil
46
+ end
47
+
48
+ end
@@ -0,0 +1,48 @@
1
+ class DashMyadventist::PasswordsController < ApplicationController
2
+ layout "dash/session"
3
+
4
+ def new
5
+ end
6
+
7
+ def create
8
+ response = User.request_password_reset( params[:forgot_password][:email] )
9
+ if response.success?
10
+ flash[:notice] = t("dash_myadventist.passwords.reset_sent")
11
+ redirect_to reset_password_path(
12
+ reset_token: response.data[:reset_token],
13
+ email: params[:forgot_password][:email]
14
+ )
15
+ else
16
+ @reset_request_failed = true
17
+ render :new
18
+ end
19
+ end
20
+
21
+ # GET
22
+ def reset
23
+ @myadventist_password = MyadventistPassword.new(
24
+ reset_token: params[:reset_token],
25
+ reset_code: params[:reset_code],
26
+ email: params[:email]
27
+ )
28
+ end
29
+
30
+ # POST
31
+ def update_password
32
+ @myadventist_password = MyadventistPassword.new(myadventist_password_params)
33
+ if @myadventist_password.save
34
+ flash[:notice] = t("dash_myadventist.passwords.reset_successfull")
35
+ redirect_to signin_path
36
+ else
37
+ flash[:alert] = t("dash_myadventist.password.reset_failed")
38
+ render :reset
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def myadventist_password_params
45
+ params.fetch(:myadventist_password, {}).permit(:email, :reset_token, :reset_code, :password)
46
+ end
47
+
48
+ end
@@ -0,0 +1,46 @@
1
+ class DashMyadventist::SessionsController < ApplicationController
2
+ layout "dash/session"
3
+ before_action :already_signed_in, only: [:new, :create]
4
+
5
+ # Sign in
6
+ def new
7
+ end
8
+
9
+ def create
10
+ @signin_response = Dash.user_class.constantize.signin_from_myadventist( signin_params.merge(ip: request.remote_ip) )
11
+ if @signin_response.success?
12
+ after_signin_success
13
+ else
14
+ render :new
15
+ end
16
+ end
17
+
18
+ # Sign out
19
+ def destroy
20
+ signout_user
21
+ flash[:notice] = t("dash_myadventist.sessions.sign_out_success")
22
+ redirect_to signin_path
23
+ end
24
+
25
+ private
26
+
27
+ def after_signin_success
28
+ self.current_user = @signin_response.user
29
+ redirect_after_signin
30
+ end
31
+
32
+ def redirect_after_signin
33
+ redirect_to session[:after_signin_path] || dashboard_root_path
34
+ session.delete(:after_signin_path)
35
+ end
36
+
37
+ def already_signed_in
38
+ if current_user
39
+ redirect_to dashboard_root_path
40
+ end
41
+ end
42
+
43
+ def signin_params
44
+ params.fetch(:session, {}).permit(:email, :password)
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ class DashMyadventist::SignupsController < ApplicationController
2
+ layout "dash/session"
3
+ before_action :redirect_if_current_sign_in
4
+
5
+ def new
6
+ @myadventist_user = MyadventistUser.new
7
+ end
8
+
9
+ def create
10
+ @myadventist_user = MyadventistUser.new(myadventist_user_params)
11
+ if @myadventist_user.save
12
+ flash[:notice] = "Successfully created account. Please sign in"
13
+ redirect_to signin_path
14
+ else
15
+ flash[:alert] = "Unable to create account. Please review error messages."
16
+ render :new
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def myadventist_user_params
23
+ params.fetch(:myadventist_user, {}).permit(:first_name, :last_name, :email, :password)
24
+ end
25
+
26
+ def redirect_if_current_sign_in
27
+ if @current_user
28
+ return redirect_to dashboard_root_path
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,4 @@
1
+ module DashMyadventist
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module DashMyadventist
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module DashMyadventist
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,90 @@
1
+ module DashMyadventist::Authentication
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+
6
+ # sign in with a myadventist email or username
7
+ def signin_from_myadventist(options={})
8
+ options.reverse_merge!(myadventist: {})
9
+ # get myadventist user id
10
+ myadventist = MyadventistApi.new(options[:myadventist])
11
+ response = myadventist.signin(options[:email], options[:password])
12
+ unless response.success?
13
+ error_msg =
14
+ case response.data[:error]
15
+ when "invalid_grant"
16
+ "Email and password do not match."
17
+ else
18
+ response.data[:error_description]
19
+ end
20
+ return SigninResponse.new(false, error: error_msg)
21
+ end
22
+
23
+ # get current user
24
+ user = self.where(adventist_uid: response.data[:user_id]).first
25
+ if user
26
+ if user.can_signin?
27
+ user.track_sign_in!(options[:ip])
28
+ return SigninResponse.new(true, user: user)
29
+ else
30
+ SigninResponse.new(false, error: "Account has not been activated")
31
+ end
32
+ elsif create_on_signin?
33
+ if user = create_user(response.data)
34
+ user.track_sign_in!(options[:ip])
35
+ return SigninResponse.new(true, user: user)
36
+ else
37
+ SigninResponse.new(false, error: "Unable to create account on sign in")
38
+ end
39
+ end
40
+ SigninResponse.new(false, error: "Account does not exist")
41
+ end
42
+
43
+ def create_user(data)
44
+ user = create(
45
+ status: "active",
46
+ first_name: data[:first_name],
47
+ last_name: data[:last_name],
48
+ email: data[:primary_email],
49
+ adventist_uid: data[:user_id]
50
+ )
51
+ user.persisted? ? user : nil
52
+ end
53
+
54
+ # create the user on signup if they don't already exist
55
+ def create_on_signin?
56
+ DashMyadventist.create_user_on_signin
57
+ end
58
+
59
+ # scope when querying for the user to sign in, override to customize
60
+ # by default we assume the user has an enum status column with option of active
61
+ def signin_scope
62
+ self.active
63
+ end
64
+
65
+ def signup_invite_only?
66
+ false
67
+ end
68
+
69
+ def request_password_reset(email)
70
+ MyadventistApi.new.request_reset_email(email)
71
+ end
72
+
73
+ end
74
+
75
+ # Track the IP address and time the user logged in.
76
+ def track_sign_in!(ip)
77
+ self.sign_in_count += 1
78
+ self.last_sign_in_ip = self.current_sign_in_ip
79
+ self.last_sign_in_at = self.current_sign_in_at
80
+ self.current_sign_in_ip = ip
81
+ self.current_sign_in_at = Time.current
82
+ self.save(validate: false)
83
+ end
84
+
85
+ # override to check if user has an active account for example
86
+ def can_signin?
87
+ active?
88
+ end
89
+
90
+ end
@@ -0,0 +1,5 @@
1
+ module DashMyadventist
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,102 @@
1
+ require "securerandom"
2
+
3
+ class MyadventistApi
4
+
5
+ def initialize(options={})
6
+ @client_id = Rails.application.credentials.env.dig(:myadventist, :client_id)
7
+ @client_secret = Rails.application.credentials.env.dig(:myadventist, :client_secret)
8
+ @redirect_host = options[:host] || Rails.application.credentials.env.dig(:myadventist, :redirect_host)
9
+ @redirect_uri = "#{@redirect_host}/auth/myadventist/callback"
10
+ @reset_password_redirect_uri = "#{@redirect_host}/passwords/reset"
11
+ @state = SecureRandom.hex(10)
12
+ @test = options.key?(:test) ? options[:test] : !Rails.env.production?
13
+ @api_host = @test ? "https://test.myadventist.org" : "https://myadventist.org"
14
+ end
15
+
16
+ def signin(username, password)
17
+ signin_response = signin_request(username, password)
18
+ return signin_response unless signin_response.success?
19
+
20
+ # Get user details
21
+ user_request(signin_response.data[:access_token])
22
+ end
23
+
24
+ def create_account(attributes)
25
+ create_response = create_account_request(attributes)
26
+ return create_response unless create_response.success?
27
+
28
+ # Get user details
29
+ user_request(create_response.data[:access_token])
30
+ end
31
+
32
+ def request_reset_email(email)
33
+ post_request("/OAuth/RequestResetEmail",
34
+ email: email,
35
+ scope: "email"
36
+ )
37
+ end
38
+
39
+ def reset_password(attributes)
40
+ post_request("/OAuth/ResetPassword",
41
+ reset_token: attributes[:reset_token],
42
+ reset_code: attributes[:reset_code],
43
+ email: attributes[:email],
44
+ password: attributes[:password],
45
+ scope: "email",
46
+ redirect_uri: @reset_password_redirect_uri
47
+ )
48
+ end
49
+
50
+ def create_account_request(attributes)
51
+ post_request("/OAuth/CreateUser",
52
+ firstname: attributes[:first_name],
53
+ lastname: attributes[:last_name],
54
+ email: attributes[:email],
55
+ password: attributes[:password],
56
+ scope: "email",
57
+ verified: attributes[:verified]
58
+ )
59
+ end
60
+
61
+ def user_request(access_token)
62
+ post_request("/OAuth/userinfo",
63
+ grant_type: "authorization_code",
64
+ access_token: access_token
65
+ )
66
+ end
67
+
68
+ def signin_request(username, password)
69
+ post_request(
70
+ "/OAuth/Authorize",
71
+ response_type: "password",
72
+ scope: "email",
73
+ username: username,
74
+ password: password
75
+ )
76
+ end
77
+
78
+ private
79
+
80
+ def post_request(path, options)
81
+ conn = Faraday.new(url: @api_host, headers: {"Content-Type" => "application/json"})
82
+ body = default_request_options.reverse_merge(options)
83
+ r_start = Time.now
84
+ response = conn.post path, body.to_json
85
+ r_end = Time.now
86
+ Rails.logger.debug "MyAdventist request #{path}: #{(r_end-r_start).in_milliseconds.to_i}ms"
87
+ unless response.success?
88
+ Rails.logger.debug "MyAdventist API request failed: #{response.status} code"# - #{response.body}
89
+ end
90
+ MyadventistResponse.new(response)
91
+ end
92
+
93
+ def default_request_options
94
+ {
95
+ client_id: @client_id,
96
+ client_secret: @client_secret,
97
+ state: @state,
98
+ redirect_uri: @redirect_uri
99
+ }
100
+ end
101
+
102
+ end
@@ -0,0 +1,52 @@
1
+ class MyadventistPassword
2
+ include ActiveModel::Model
3
+
4
+ validates :reset_code, :reset_token, :email, :password, presence: true
5
+ validates :email, email: true
6
+ # Password complexity: at least 1 uppercase and lowercase
7
+ validates :password, length: {minimum: 12}, format: { with: /(?=.*[A-Z])(?=.*[a-z]).*/, message: I18n.t("dash_myadventist.myadventist_user.validations.password_complexity") }
8
+
9
+ attr_accessor :reset_code, :reset_token, :email, :password
10
+
11
+ def save
12
+ return false unless valid?
13
+ reset_password
14
+ end
15
+
16
+ def show_reset_code?
17
+ reset_code.blank? || errors[:reset_code].any?
18
+ end
19
+
20
+ def attributes
21
+ {
22
+ email: email,
23
+ password: password,
24
+ reset_code: reset_code,
25
+ reset_token: reset_token
26
+ }
27
+ end
28
+
29
+ def reset_password
30
+ myadventist = MyadventistApi.new
31
+ response = myadventist.reset_password(attributes)
32
+
33
+ unless response.success?
34
+ map_myadventist_errors(response)
35
+ end
36
+ response.success?
37
+ end
38
+
39
+ private
40
+
41
+ # map myadventist errors to attributes
42
+ def map_myadventist_errors(response)
43
+ if response.data[:error_description].include?("Invalid or expired reset_token")
44
+ errors.add :base, "Reset code has expired. Try forgot password again."
45
+ elsif response.data[:error_description].include?("Code failed validation")
46
+ errors.add :reset_code, "invalid"
47
+ else
48
+ errors.add :base, response.data[:error_description]
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,14 @@
1
+ class MyadventistResponse
2
+
3
+ attr_reader :success, :status, :data
4
+
5
+ def initialize(response)
6
+ @success = response.success?
7
+ @status = response.status
8
+ @data = JSON.parse(response.body).transform_keys { |key| key.underscore.to_sym } rescue {}
9
+ end
10
+
11
+ def success?
12
+ @success
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ class MyadventistUser
2
+ include ActiveModel::Model
3
+
4
+ validates :first_name, :last_name, :email, :password, presence: true
5
+ validates :email, email: true
6
+ # Password complexity: at least 1 digit, uppercase, lowercase, symbol
7
+ validates :password, length: {minimum: 12}, format: { with: /(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*\W).*/, message: I18n.t("dash_myadventist.myadventist_user.validations.password_complexity") }
8
+
9
+ attr_accessor :first_name, :last_name, :email, :password, :adventist_uid
10
+
11
+ def save
12
+ return false unless valid?
13
+ create_account
14
+ end
15
+
16
+ def attributes
17
+ {
18
+ first_name: first_name,
19
+ last_name: last_name,
20
+ email: email,
21
+ password: password,
22
+ verified: 1 #hmmm
23
+ }
24
+ end
25
+
26
+ def create_account
27
+ myadventist = MyadventistApi.new
28
+ response = myadventist.create_account(attributes)
29
+ if response.success?
30
+ self.adventist_uid = response.data[:user_id]
31
+ return true
32
+ else
33
+ map_myadventist_errors(response)
34
+ end
35
+ false
36
+ end
37
+
38
+ private
39
+
40
+ # map myadventist errors to attributes
41
+ def map_myadventist_errors(response)
42
+ if response.data[:error_description].include?("Email is already in use")
43
+ errors.add :email, "already taken"
44
+ else
45
+ errors.add :base, response.data[:error_description]
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,14 @@
1
+ class SigninResponse
2
+
3
+ attr_reader :success, :user, :error
4
+
5
+ def initialize(success, options={})
6
+ @success = success
7
+ @user = options[:user]
8
+ @error = options[:error]
9
+ end
10
+
11
+ def success?
12
+ @success
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ <div class="container">
2
+ <div class="row justify-content-center">
3
+ <div class="col-12 col-md-6">
4
+ <h2 class="standout"><%= t("dash_myadventist.passwords.forgot_password") %></h2>
5
+
6
+ <div class="card card-session">
7
+ <div class="card-body">
8
+ <%= simple_form_for :forgot_password, url: "/passwords" do |f| %>
9
+ <%= f.input :email, placeholder: t("dash_myadventist.passwords.email_placeholder"), label: false, autofocus: true %>
10
+ <%= content_tag(:p, t("dash_myadventist.passwords.reset_request_failed"), class: "session-error") if @reset_request_failed %>
11
+ <div class="actions">
12
+ <%= f.submit t("dash_myadventist.passwords.send_reset_email"), class: "btn btn-primary" %>
13
+ </div>
14
+ <% end %>
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+
@@ -0,0 +1,33 @@
1
+ <div class="container">
2
+ <div class="row justify-content-center">
3
+ <div class="col-12 col-md-6">
4
+ <h2 class="standout"><%= t("dash_myadventist.passwords.forgot_password") %></h2>
5
+ <div class="card card-session">
6
+ <div class="card-body">
7
+ <% if @myadventist_password.show_reset_code? %>
8
+ <p><%= t("dash_myadventist.passwords.reset_request_success") %></p>
9
+ <% else %>
10
+ <p><%= t("dash_myadventist.passwords.set_new_password") %></p>
11
+ <% end %>
12
+ <% if @myadventist_password.errors[:base].any? %>
13
+ <p class="session-error"><%= @myadventist_password.errors[:base].join(', ') %></p>
14
+ <% end %>
15
+ <%= simple_form_for @myadventist_password, url: "/passwords/update_password" do |f| %>
16
+ <%= f.input_field :reset_token, as: :hidden %>
17
+ <%= f.input_field :email, as: :hidden %>
18
+ <% if @myadventist_password.show_reset_code? %>
19
+ <%= f.input :reset_code, autofocus: true %>
20
+ <% else %>
21
+ <%= f.input_field :reset_code, as: :hidden %>
22
+ <% end %>
23
+ <%= f.input :password, label: t("dash_myadventist.passwords.new_password") %>
24
+ <div class="actions">
25
+ <%= f.submit t("dash_myadventist.passwords.reset_password"), class: "btn btn-primary" %>
26
+ </div>
27
+ <% end %>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+
@@ -0,0 +1,22 @@
1
+ <div class="container">
2
+ <div class="row justify-content-center">
3
+ <div class="col-12 col-md-6">
4
+ <h2 class="standout"><%= t("dash_myadventist.sessions.page_title") %></h2>
5
+ <p class="text-center"><%= t("dash_myadventist.sessions.no_account")%> <%= link_to t("dash_myadventist.sessions.sign_up"), main_app.signup_path, class: "link-highlight" %></p>
6
+ <div class="card card-session">
7
+ <div class="card-body">
8
+ <%= simple_form_for :session, url: "/signin", html: {novalidate: true} do |f| %>
9
+ <%= f.input :email, placeholder: t("dash_myadventist.sessions.email_or_username_placeholder"), label: false, autofocus: true %>
10
+ <%= f.input :password, placeholder: t("dash_myadventist.sessions.password_placeholder"), label: false %>
11
+ <%= content_tag(:p, @signin_response.error, class: "session-error") if @signin_response %>
12
+ <%= link_to t("dash_myadventist.sessions.forgot_password"), new_password_path, class: "forgot-password" %>
13
+ <div class="actions">
14
+ <%= f.submit t("dash_myadventist.sessions.sign_in"), class: "btn btn-primary", data: {disable_with: t("dash_myadventist.sessions.disable.sign_in")} %>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </div>
22
+
@@ -0,0 +1,29 @@
1
+ <div class="container">
2
+ <div class="row justify-content-center">
3
+ <div class="col-12">
4
+ <h2 class="standout"><%= t("dash_myadventist.signups.page_title") %></h2>
5
+ <p class="text-center"><%= t("dash_myadventist.signups.account_exists") %> <%= link_to t("dash_myadventist.sessions.sign_in"), main_app.signin_path, class: "link-highlight" %></p>
6
+ </div>
7
+ </div>
8
+ <div class="row justify-content-center">
9
+ <div class="col-md-6">
10
+ <div class="card card-session">
11
+ <div class="card-body">
12
+ <% if @myadventist_user.errors[:base].any? %>
13
+ <p class="session-error"><%= @myadventist_user.errors[:base].join(', ') %></p>
14
+ <% end %>
15
+ <%= simple_form_for @myadventist_user, url: '/signup' do |f| %>
16
+ <%= f.input :first_name, placeholder: t("dash_myadventist.sessions.first_name_placeholder"), label: false, autofocus: true %>
17
+ <%= f.input :last_name, placeholder: t("dash_myadventist.sessions.last_name_placeholder"), label: false, autofocus: true %>
18
+ <%= f.input :email, placeholder: t("dash_myadventist.sessions.email_placeholder"), label: false %>
19
+ <%= f.input :password, placeholder: t("dash_myadventist.sessions.password_placeholder"), label: false %>
20
+ <p><%= t("dash_myadventist.signups.terms_agreement_html", link: link_to(t("dash_myadventist.signups.terms_of_use"), "/legal/terms", class: "link-highlight")) %></p>
21
+ <div class="actions">
22
+ <%= f.submit t("dash_myadventist.sessions.sign_up"), class: "btn btn-primary" %>
23
+ </div>
24
+ <% end %>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
@@ -0,0 +1,40 @@
1
+ en:
2
+ dash_myadventist:
3
+ passwords:
4
+ forgot_password: Forgot Password
5
+ email_placeholder: Email
6
+ reset_password: Reset Password
7
+ new_password: New Password
8
+ set_new_password: Set a new password for your Adventist Account
9
+ reset_request_failed: Unable to reset. Please check email is correct
10
+ reset_request_success: We've sent you an email with instructions to reset your password. Click the link in the email or paste the reset code below.
11
+ reset_sent: Successfully sent reset password email
12
+ reset_successfull: Successfully reset password
13
+ reset_failed: Unable to update password. Please check errors
14
+ send_reset_email: Send reset email
15
+ sessions:
16
+ page_title: Sign in to myAdventist
17
+ email_or_username_placeholder: Email or username
18
+ email_placeholder: Email
19
+ first_name_placeholder: First name
20
+ forgot_password: Forgot password?
21
+ last_name_placeholder: Last name
22
+ password_placeholder: Password
23
+ no_account: Don't have a myAdventist account?
24
+ sign_in: Sign in
25
+ sign_in_title: Sign in with myAdventist
26
+ sign_in_failed: Email and password do not match.
27
+ sign_out: Sign out
28
+ sign_out_success: Successfully signed out
29
+ sign_up: Sign up
30
+ sign_up_title: Sign up to myAdventist
31
+ disable:
32
+ sign_in: Signing In...
33
+ signups:
34
+ page_title: Create your myAdventist account
35
+ account_exists: Already have a myAdventist account?
36
+ terms_agreement_html: "By signing up you agree to the %{link}"
37
+ terms_of_use: terms of use
38
+ myadventist_user:
39
+ validations:
40
+ password_complexity: requires 12 or more characters with at least one uppercase & lowercase character
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ DashMyadventist::Engine.routes.draw do
2
+ # Sessions
3
+ # get 'signin', to: 'sessions#new', as: :signin
4
+ # post 'signin', to: 'sessions#create'
5
+ # delete 'signout', to: 'sessions#destroy', as: :signout
6
+ # # Sign up
7
+ # get 'signup', to: 'signups#new', as: :signup
8
+ # post 'signup', to: 'signups#create'
9
+ end
@@ -0,0 +1,16 @@
1
+ require "dash_myadventist/engine"
2
+ require "faraday"
3
+ module DashMyadventist
4
+
5
+ # Create user account automatically on successfull sign in
6
+ mattr_accessor :create_user_on_signin
7
+ @@create_user_on_signin = true
8
+
9
+ # Configuration
10
+ # DashMyadventist.setup do |config|
11
+ # config.create_user_on_signin = true
12
+ # end
13
+ def self.setup
14
+ yield self
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ module DashMyadventist
2
+ class Engine < ::Rails::Engine
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ module DashMyadventist
2
+ VERSION = '0.1.1'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :dash_myadventist do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dash_myadventist
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - adventistmedia
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 5.3.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 5.2.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 5.3.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: faraday
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.14.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.14.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: sqlite3
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ description: Dash addon for Myadventist.
62
+ email:
63
+ - webmaster@adventistmedia.org.au
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - MIT-LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - app/assets/config/dash_myadventist_manifest.js
72
+ - app/assets/javascripts/dash_myadventist/application.js
73
+ - app/assets/stylesheets/dash_myadventist/application.css
74
+ - app/controllers/concerns/dash_myadventist/current_user.rb
75
+ - app/controllers/dash_myadventist/passwords_controller.rb
76
+ - app/controllers/dash_myadventist/sessions_controller.rb
77
+ - app/controllers/dash_myadventist/signups_controller.rb
78
+ - app/helpers/dash_myadventist/application_helper.rb
79
+ - app/jobs/dash_myadventist/application_job.rb
80
+ - app/mailers/dash_myadventist/application_mailer.rb
81
+ - app/models/concerns/dash_myadventist/authentication.rb
82
+ - app/models/dash_myadventist/application_record.rb
83
+ - app/models/myadventist_api.rb
84
+ - app/models/myadventist_password.rb
85
+ - app/models/myadventist_response.rb
86
+ - app/models/myadventist_user.rb
87
+ - app/models/signin_response.rb
88
+ - app/views/dash_myadventist/passwords/new.html.erb
89
+ - app/views/dash_myadventist/passwords/reset.html.erb
90
+ - app/views/dash_myadventist/sessions/new.html.erb
91
+ - app/views/dash_myadventist/signups/new.html.erb
92
+ - config/locales/en.yml
93
+ - config/routes.rb
94
+ - lib/dash_myadventist.rb
95
+ - lib/dash_myadventist/engine.rb
96
+ - lib/dash_myadventist/version.rb
97
+ - lib/tasks/dash_myadventist_tasks.rake
98
+ homepage: http://adventistmedia.org.au
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.6.13
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Dash addon for Myadventist.
122
+ test_files: []