jobshop 0.0.41 → 0.0.53

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.
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