jobshop 0.0.41 → 0.0.53

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c86e7e67c1715d920f77caf807a4bc4e5d0d5dec
4
- data.tar.gz: b61cde16d2ba6177ecc3bbb62d4b7e165692b92b
3
+ metadata.gz: 8a2d1798548ecae570f0b45babfa2e513b82395c
4
+ data.tar.gz: bc7448f4acea0f1582843a1a47ff9b98a1c4aae6
5
5
  SHA512:
6
- metadata.gz: bb5e90365faeb6483033e4c16a776e399908ba489557ed89672bad4d864c176004ed729b41adcd5626d458f7a92e1b3e5a515ac601098e3fba86e5fac27d6cf2
7
- data.tar.gz: bed3c0155ecd9c441f018d28f119fae407067cdb01965d770479fd496070b8c328d56dcdd0ad47ee08a5a1e90c07ef3badeb9f64188950820369f6712ad757b8
6
+ metadata.gz: 649182157861589f953e47725d6947e86f3245e81e2c90c8d1b36127865fdacd74a4498303dd6bd99b9f837752353dfcd211733ad43c9963d88a5d83346bf3ae
7
+ data.tar.gz: e7b646ec641cceae9c9e699a5f4afb9e5d725fcd1f0a066e7974af05cf1127ba4af99e484b1966dee8b71972aba0a4faf24d20a489a0f5e26484ee6dd46eca39
@@ -0,0 +1,59 @@
1
+ class EmailTokenValidation
2
+ def self.before(controller)
3
+ @token = EmailToken.new(
4
+ controller.params.fetch(:user_email, nil),
5
+ controller.params.fetch(:email_authentication_token, nil)
6
+ )
7
+
8
+ if @token.valid?
9
+ sign_out_current_scope
10
+ sign_in token.user
11
+ token.destroy
12
+ end
13
+ end
14
+
15
+ class EmailToken
16
+ attr_reader :token
17
+
18
+ def initialize(email, token)
19
+ @email, @token = email, token
20
+ end
21
+
22
+ def valid?
23
+ present? && user && token && !expired? && secure_compare
24
+ end
25
+
26
+ private
27
+ def present?
28
+ @email.present? && @token.present?
29
+ end
30
+
31
+ def user
32
+ @user ||= Jobshop::User.where(email: @email)
33
+ .where.not(email_authentication_token_sent_at: nil).first
34
+ end
35
+
36
+ def destroy
37
+ user.update({
38
+ email_authentication_token: nil,
39
+ email_authentication_token_sent_at: nil
40
+ })
41
+ end
42
+
43
+ def secure_compare
44
+ # Notice how we use Devise.secure_compare to compare the token in the
45
+ # database with the token given in the params, mitigating timing
46
+ # attacks.
47
+ Devise.secure_compare(user.email_authentication_token, token)
48
+ end
49
+
50
+ def expired?
51
+ @expired ||= Time.now >= expires_on
52
+ end
53
+
54
+ def expires_on
55
+ # TODO: Make token expiration configurable in initializers/jobshop.rb.
56
+ @expires_on ||= user.email_authentication_token_sent_at + 6.hours
57
+ end
58
+ end
59
+ end
@@ -1,25 +1,41 @@
1
- module RegistrationTokenValidation
2
- class << self
3
- def before(controller)
4
- @token = controller.params[:registration_token]
5
- @controller = controller
6
- controller.redirect_to controller.new_user_session_path unless valid?
7
- end
1
+ class RegistrationTokenValidation
2
+ def self.before(controller)
3
+ new(controller.dup)
4
+ end
5
+
6
+ def initialize(controller)
7
+ @controller = controller.dup
8
+ @token = @controller.params.fetch(:registration_token, nil)
9
+ @team_id = @controller.params.fetch(:team_id, nil)
8
10
 
9
- def valid?
10
- @token.present? && resolves?
11
+ if @token
12
+ @controller.redirect_to(@controller.new_user_session_path) unless valid?
11
13
  end
14
+ end
15
+
16
+ def valid?
17
+ !expired? && !owned? && resolves?
18
+ end
12
19
 
13
- def resolves?
14
- encrypted_token = Devise.token_generator.digest(
15
- Jobshop::Team, :registration_token, @token)
20
+ private
21
+ def team
22
+ @team ||= Jobshop::Team.where(id: @team_id).first
23
+ end
16
24
 
17
- configurable = Jobshop::Team.find_by(
18
- id: @controller.params[:team_id], registration_token: encrypted_token)
25
+ def resolves?
26
+ encrypted_token = Devise.token_generator.digest(
27
+ Jobshop::Team, :registration_token, @token)
19
28
 
20
- configurable &&
21
- configurable.registration_token_period_valid? &&
22
- configurable.owner.blank?
23
- end
29
+ # Notice how we use Devise.secure_compare to compare the token in the
30
+ # database with the token given in the params, mitigating timing attacks.
31
+ Devise.secure_compare(team.registration_token, encrypted_token)
32
+ end
33
+
34
+ def expired?
35
+ @expired ||= !team.registration_token_period_valid?
36
+ end
37
+
38
+ def owned?
39
+ @owned ||= team.owner.present?
24
40
  end
25
41
  end
@@ -10,7 +10,7 @@ module Jobshop
10
10
 
11
11
  protect_from_forgery
12
12
 
13
- before_action :authenticate_user_from_email!
13
+ before_action EmailTokenValidation
14
14
  before_action :authenticate_user!
15
15
 
16
16
  # after_action :verify_authorized, except: :index
@@ -18,67 +18,14 @@ module Jobshop
18
18
 
19
19
  private
20
20
 
21
- def authenticate_user_from_email!
22
- token = EmailAuthenticationToken.new(
23
- params.fetch(:user_email, nil),
24
- params.fetch(:email_authentication_token, nil)
25
- )
26
-
27
- if token.valid?
28
- sign_in token.user
29
- token.destroy
30
- end
31
- end
32
-
33
21
  def layout_for_application
34
22
  if devise_controller? && controller_name == "sessions" ||
35
23
  controller_path == "jobshop/teams/lookups"
36
24
  "jobshop/unauthenticated"
37
25
  else
38
-
39
26
  "jobshop/application"
40
27
  end
41
28
  end
42
29
 
43
- class EmailAuthenticationToken
44
- attr_reader :token
45
-
46
- def initialize(email, token)
47
- @email = email
48
- @token = token
49
- end
50
-
51
- def valid?
52
- user && token && !expired? && secure_compare
53
- end
54
-
55
- def user
56
- @user ||= Jobshop::User.where(email: @email)
57
- .where.not(email_authentication_token_sent_at: nil).first
58
- end
59
-
60
- def destroy
61
- user.update({
62
- email_authentication_token: nil,
63
- email_authentication_token_sent_at: nil
64
- })
65
- end
66
-
67
- def secure_compare
68
- # Notice how we use Devise.secure_compare to compare the token in the
69
- # database with the token given in the params, mitigating timing
70
- # attacks.
71
- Devise.secure_compare(user.email_authentication_token, token)
72
- end
73
-
74
- def expired?
75
- @expired ||= Time.now >= expires_on
76
- end
77
-
78
- def expires_on
79
- # TODO: Make token expiration configurable in initializers/jobshop.rb.
80
- @expires_on ||= user.email_authentication_token_sent_at + 6.hours
81
- end
82
- end
83
30
  end
84
31
  end
@@ -0,0 +1,6 @@
1
+ require_dependency "jobshop/application_controller"
2
+
3
+ module Jobshop
4
+ class SessionsController < Devise::SessionsController
5
+ end
6
+ end
@@ -10,12 +10,11 @@ module Jobshop
10
10
 
11
11
  def create
12
12
  emails = params[:user][:email].split(",").map(&:strip).take(5)
13
-
14
13
  Jobshop::Team.grouped_by_email(emails).each_pair do |email, teams|
15
14
  Jobshop::TeamsMailer.found_teams(email, teams).deliver_later
16
15
  end
17
16
 
18
- redirect_to new_user_session_path
17
+ redirect_to teams_lookup_path
19
18
  end
20
19
  end
21
20
  end
@@ -2,10 +2,10 @@ require_dependency "jobshop/application_controller"
2
2
 
3
3
  module Jobshop
4
4
  class Teams::RegistrationsController < ApplicationController
5
- before_action RegistrationTokenValidation
6
-
7
5
  skip_before_action :authenticate_user!
8
6
 
7
+ before_action RegistrationTokenValidation
8
+
9
9
  layout "jobshop/unauthenticated"
10
10
 
11
11
  def new
@@ -1,10 +1,10 @@
1
1
  module Jobshop
2
2
  class TeamsMailer < ApplicationMailer
3
- def found_teams(user, teams)
4
- @user = user
3
+ def found_teams(email, teams)
4
+ @user = Jobshop::User.where(email: email).first
5
5
  @teams = teams
6
6
 
7
- mail(to: @user.email, subject: "We found your Jobshop Teams!")
7
+ mail(to: email, subject: "We found your Jobshop Teams!")
8
8
  end
9
9
  end
10
10
  end
@@ -16,8 +16,12 @@ module Jobshop
16
16
  presence: { if: :password_required? },
17
17
  confirmation: { if: :password_required? }
18
18
 
19
- private
19
+ def self.find_for_authentication(warden_conditions)
20
+ where(email: warden_conditions[:email],
21
+ team_id: warden_conditions[:team_id]).first
22
+ end
20
23
 
24
+ private
21
25
  def generate_email_authentication_token
22
26
  loop do
23
27
  token = Devise.friendly_token
@@ -9,6 +9,7 @@
9
9
  .mdl-card__supporting-text
10
10
  = f.input(:email)
11
11
  = f.input(:password)
12
+ = f.input(:team_id, as: :hidden, input_html: { value: params[:team_id] })
12
13
 
13
14
  .mdl-card__actions
14
15
  = f.input :remember_me, as: :boolean, input_html: { class: "mdl-checkbox__input" }
@@ -27,7 +27,7 @@
27
27
  %span(class="visuallyhidden") User Actions
28
28
  %ul(class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="accbtn")
29
29
  %li(class="mdl-menu__item")
30
- %a(href="#{destroy_user_session_path}" data-method="delete") Sign out
30
+ %a(href="#{destroy_user_session_path(team_id: current_user.team_id)}" data-method="delete") Sign out
31
31
  %nav(class="demo-navigation mdl-navigation mdl-color--blue-grey-800")
32
32
  %a(class="mdl-navigation__link" href="")
33
33
  %i(class="mdl-color-text--blue-grey-400 material-icons" role="presentation") home
@@ -11,4 +11,5 @@
11
11
  = f.input :email
12
12
 
13
13
  .mdl-card__actions
14
+ .expand
14
15
  = f.button :submit, "Send the link to my email!"
@@ -0,0 +1,11 @@
1
+ %P
2
+ Hi #{@user.email},
3
+
4
+ %p
5
+ We found the following teams linked to your email address:
6
+
7
+ %ul
8
+ - @teams.each do |team|
9
+ %li
10
+ Sign in at
11
+ = link_to(team.name, new_user_session_url(team_id: team.id))
@@ -3,5 +3,6 @@ Hi <%= @user.email %>,
3
3
  We found the following teams linked to your email address:
4
4
 
5
5
  <% @teams.each do |team| %>
6
- You belong to: <%= team.name %>
6
+ <%= jobshop.new_user_session_url(team_id: team.id) %>
7
+ <%= team.name %>
7
8
  <% end %>
@@ -8,7 +8,7 @@
8
8
  %nav.mdl-navigation
9
9
  %a.mdl-navigation__link{ href: jobshop.about_path }
10
10
  About
11
- %a.mdl-navigation__link.mdl-color-text--pink{ href: jobshop.new_user_session_path }
11
+ %a.mdl-navigation__link.mdl-color-text--pink{ href: jobshop.teams_lookup_path }
12
12
  Sign In
13
13
 
14
14
  = yield
@@ -36,7 +36,7 @@ Devise.setup do |config|
36
36
  # filter. You can also supply a hash where the value is a boolean determining
37
37
  # whether or not authentication should be aborted when the value is not
38
38
  # present.
39
- # config.authentication_keys = [:email]
39
+ config.authentication_keys = [ :email, :team_id ]
40
40
 
41
41
  # Configure parameters from the request object used for authentication. Each
42
42
  # entry given should be a request method and it will automatically be passed
data/config/routes.rb CHANGED
@@ -1,5 +1,13 @@
1
1
  Jobshop::Engine.routes.draw do
2
- devise_for :users, class_name: "Jobshop::User", module: :devise
2
+ default_url_options(Jobshop.configuration.default_url_options)
3
+
4
+ devise_for(:users, class_name: "Jobshop::User", module: "devise", skip: [ :sessions ])
5
+
6
+ devise_scope :user do
7
+ get "teams/:team_id/sign_in" => "sessions#new", as: :new_user_session
8
+ post "teams/:team_id/sign_in" => "sessions#create", as: :user_session
9
+ delete "teams/:team_id/sign_out" => "sessions#destroy", as: :destroy_user_session
10
+ end
3
11
 
4
12
  resources :teams, only: [ ] do
5
13
  collection do
@@ -10,13 +10,18 @@
10
10
  # Make sure the secrets in this file are kept private
11
11
  # if you're sharing your code publicly.
12
12
 
13
- development:
13
+ defaults: &defaults
14
+ canonical_name: "localhost"
14
15
  secret_key_base: <%= SecureRandom.hex(64) %>
15
16
 
17
+ development:
18
+ <<: *defaults
19
+
16
20
  test:
17
- secret_key_base: <%= SecureRandom.hex(64) %>
21
+ <<: *defaults
18
22
 
19
23
  # Do not keep production secrets in the repository,
20
24
  # instead read values from the environment.
21
25
  production:
26
+ canonical_name: <%%= ENV["CANONICAL_NAME"] %>
22
27
  secret_key_base: <%%= ENV["SECRET_KEY_BASE"] %>
@@ -6,7 +6,7 @@ module Jobshop
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 0
9
- TINY = 41
9
+ TINY = 53
10
10
  PRE = nil
11
11
 
12
12
  CODE_NAME = "bump it up prime".freeze
data/lib/jobshop.rb CHANGED
@@ -14,10 +14,14 @@ module Jobshop
14
14
  end
15
15
 
16
16
  class Configuration
17
- attr_writer :host
17
+ attr_writer :canonical_name
18
+
19
+ def initialize
20
+ @canonical_name = "localhost:3000"
21
+ end
18
22
 
19
23
  def default_url_options
20
- {}
24
+ { host: @canonical_name }
21
25
  end
22
26
  end
23
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jobshop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.41
4
+ version: 0.0.53
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank J. Mattia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-13 00:00:00.000000000 Z
11
+ date: 2016-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coffee-rails
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 4.1.0
61
+ version: 4.2.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 4.1.0
68
+ version: 4.2.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: material_design_lite-sass
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.1.3
75
+ version: 1.2.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.1.3
82
+ version: 1.2.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pundit
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 3.2.0
145
+ version: 3.3.0
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 3.2.0
152
+ version: 3.3.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: turbolinks
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -321,9 +321,11 @@ files:
321
321
  - app/assets/stylesheets/jobshop/application.scss
322
322
  - app/assets/stylesheets/jobshop/breakpoints.scss
323
323
  - app/assets/stylesheets/jobshop/static.scss
324
+ - app/controllers/concerns/email_token_validation.rb
324
325
  - app/controllers/concerns/registration_token_validation.rb
325
326
  - app/controllers/jobshop/application_controller.rb
326
327
  - app/controllers/jobshop/dashboards_controller.rb
328
+ - app/controllers/jobshop/sessions_controller.rb
327
329
  - app/controllers/jobshop/setups_controller.rb
328
330
  - app/controllers/jobshop/teams/lookups_controller.rb
329
331
  - app/controllers/jobshop/teams/registrations_controller.rb
@@ -355,6 +357,7 @@ files:
355
357
  - app/views/jobshop/setups/show.html.haml
356
358
  - app/views/jobshop/teams/lookups/show.html.haml
357
359
  - app/views/jobshop/teams/registrations/new.html.haml
360
+ - app/views/jobshop/teams_mailer/found_teams.html.haml
358
361
  - app/views/jobshop/teams_mailer/found_teams.text.erb
359
362
  - app/views/layouts/jobshop/application.html.haml
360
363
  - app/views/layouts/jobshop/mailer.text.erb