dash_myadventist 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []