ditty 0.9.1 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.env.test +2 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +23 -4
  5. data/.travis.yml +2 -7
  6. data/Gemfile.ci +0 -15
  7. data/ditty.gemspec +19 -15
  8. data/lib/ditty.rb +2 -2
  9. data/lib/ditty/cli.rb +5 -0
  10. data/lib/ditty/components/ditty.rb +4 -7
  11. data/lib/ditty/controllers/application_controller.rb +6 -5
  12. data/lib/ditty/controllers/audit_logs_controller.rb +2 -0
  13. data/lib/ditty/controllers/auth_controller.rb +5 -2
  14. data/lib/ditty/controllers/component_controller.rb +3 -3
  15. data/lib/ditty/controllers/user_login_traits_controller.rb +28 -1
  16. data/lib/ditty/controllers/users_controller.rb +3 -2
  17. data/lib/ditty/db.rb +4 -3
  18. data/lib/ditty/emails/base.rb +32 -30
  19. data/lib/ditty/generators/crud_generator.rb +51 -41
  20. data/lib/ditty/generators/project_generator.rb +1 -0
  21. data/lib/ditty/helpers/pundit.rb +4 -4
  22. data/lib/ditty/helpers/response.rb +6 -11
  23. data/lib/ditty/helpers/views.rb +21 -3
  24. data/lib/ditty/listener.rb +1 -1
  25. data/lib/ditty/models/base.rb +5 -0
  26. data/lib/ditty/models/identity.rb +7 -7
  27. data/lib/ditty/models/user.rb +9 -1
  28. data/lib/ditty/policies/user_policy.rb +1 -1
  29. data/lib/ditty/services/authentication.rb +19 -9
  30. data/lib/ditty/services/email.rb +13 -13
  31. data/lib/ditty/services/logger.rb +26 -20
  32. data/lib/ditty/services/pagination_wrapper.rb +7 -5
  33. data/lib/ditty/services/settings.rb +7 -6
  34. data/lib/ditty/tasks/ditty.rake +2 -1
  35. data/lib/ditty/templates/application.rb +1 -1
  36. data/lib/ditty/templates/config.ru +2 -2
  37. data/lib/ditty/templates/controller.rb.erb +7 -1
  38. data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
  39. data/{public → lib/ditty/templates/public}/css/styles.css +0 -0
  40. data/lib/ditty/templates/public/favicon.ico +0 -0
  41. data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
  42. data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
  43. data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
  44. data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
  45. data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
  46. data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
  47. data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
  48. data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
  49. data/{public → lib/ditty/templates/public}/js/scripts.js +0 -0
  50. data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
  51. data/lib/ditty/templates/settings.yml.erb +1 -0
  52. data/lib/ditty/templates/spec_helper.rb +1 -1
  53. data/lib/ditty/templates/views/display.haml.tt +1 -1
  54. data/lib/ditty/templates/views/edit.haml.tt +1 -1
  55. data/lib/ditty/templates/views/index.haml.tt +1 -1
  56. data/lib/ditty/templates/views/new.haml.tt +1 -1
  57. data/lib/ditty/version.rb +1 -1
  58. data/spec/ditty/api_spec.rb +1 -1
  59. data/spec/ditty/emails/base_spec.rb +3 -3
  60. data/spec/ditty/emails/forgot_password_spec.rb +3 -2
  61. data/spec/ditty/models/user_spec.rb +3 -3
  62. data/spec/ditty/services/logger_spec.rb +7 -6
  63. data/spec/ditty/services/settings_spec.rb +2 -2
  64. data/spec/factories.rb +4 -4
  65. data/spec/spec_helper.rb +5 -1
  66. data/views/403.haml +1 -1
  67. data/views/500.haml +11 -0
  68. data/views/audit_logs/index.haml +12 -11
  69. data/views/auth/forgot_password.haml +29 -24
  70. data/views/auth/ldap.haml +1 -1
  71. data/views/auth/login.haml +3 -2
  72. data/views/auth/register.haml +3 -2
  73. data/views/auth/reset_password.haml +36 -19
  74. data/views/blank.haml +1 -0
  75. data/views/embedded.haml +17 -11
  76. data/views/layout.haml +16 -8
  77. data/views/partials/actions.haml +15 -14
  78. data/views/partials/filter_control.haml +1 -1
  79. data/views/partials/footer.haml +10 -2
  80. data/views/partials/form_tag.haml +1 -1
  81. data/views/partials/navitems.haml +25 -27
  82. data/views/partials/pager.haml +44 -25
  83. data/views/partials/search.haml +14 -9
  84. data/views/partials/sidebar.haml +2 -2
  85. data/views/partials/sort_ui.haml +2 -0
  86. data/views/partials/timespan_selector.haml +64 -0
  87. data/views/partials/topbar.haml +0 -15
  88. data/views/partials/user_associations.haml +32 -0
  89. data/views/quick_start.haml +23 -0
  90. data/views/roles/display.haml +3 -3
  91. data/views/roles/edit.haml +1 -1
  92. data/views/roles/index.haml +2 -2
  93. data/views/roles/new.haml +1 -1
  94. data/views/user_login_traits/display.haml +1 -1
  95. data/views/user_login_traits/edit.haml +1 -1
  96. data/views/user_login_traits/index.haml +23 -25
  97. data/views/user_login_traits/new.haml +1 -1
  98. data/views/users/display.haml +5 -5
  99. data/views/users/edit.haml +1 -1
  100. data/views/users/index.haml +5 -5
  101. data/views/users/login_traits.haml +2 -2
  102. data/views/users/new.haml +1 -1
  103. data/views/users/profile.haml +4 -4
  104. data/views/users/user.haml +1 -1
  105. metadata +116 -54
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a7260a6694f316ec8f4e3388932e7a749030f7fb6fc88657012f15a863069639
4
- data.tar.gz: 3f0e6db669807bc153111ceaa182cbbc5323f90f0acf535e3bdb6bd199b531cc
3
+ metadata.gz: e785b1b4a84258a46e98753a5de394897bc6d002b88d2fc6629b30b33b52614e
4
+ data.tar.gz: '094a55847cc4ec09bf1dc9307c9efcffa5b59b498fd407de5950e656e5a5e516'
5
5
  SHA512:
6
- metadata.gz: fd5b41ce540f365575aeb1c7c33ffc487f87585894a0d1267428dc5bba8a60ea9b041fa9f0c8e8bcda62b265f94c989b3938c82e76a1770269a0abc8a26ed481
7
- data.tar.gz: 385f6cae60979bc716d3268a07856255fc19beaa9652087c1d9f748042074c927d4fcb259188667ef6724083feb76004871c5e69e76d5c8eae4414dd63781997
6
+ metadata.gz: fa7d54c43ac02d1f04a690f2bca5a529b3c65eefa0f287ab44594910bca2b8022656b58e2aef805a52307364481c35be2ba1b1e4b3a97b3450cab1b9acb27d1f
7
+ data.tar.gz: 847143f0f0d20c67b3451a86e780ec44b914210ceec4498c9218ebc05f7f7277107b1998ca5f273aad0ad1ad45ceb051b81204fe87e6cb91e88ee2ef6af7b49c
data/.env.test ADDED
@@ -0,0 +1,2 @@
1
+ CC_TEST_REPORTER_ID=289860573c6284a8e277de86848caba84d840be49e35f3601bcd672ab40d1e35
2
+ DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL=true
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ vendor
16
16
  migrations
17
17
  /gems.*
18
18
  .env
19
+ .env.*.local
data/.rubocop.yml CHANGED
@@ -1,9 +1,28 @@
1
- require: rubocop-rspec
2
-
1
+ require:
2
+ - rubocop-rspec
3
+ - rubocop-performance
4
+ - rubocop-thread_safety
5
+ - rubocop-sequel
3
6
  AllCops:
4
- TargetRubyVersion: 2.7
5
- Metrics/LineLength:
7
+ NewCops: enable
8
+ TargetRubyVersion: 2.7.1
9
+ Exclude:
10
+ - migrate/**/*
11
+ Layout/LineLength:
6
12
  Max: 120
7
13
  Layout/LeadingCommentSpace:
8
14
  Exclude:
9
15
  - 'config.ru'
16
+ Layout/EndOfLine:
17
+ EnforcedStyle: lf
18
+ Layout/MultilineMethodCallIndentation:
19
+ EnforcedStyle: indented
20
+ IndentationWidth: 2
21
+ Layout/IndentationConsistency:
22
+ EnforcedStyle: indented_internal_methods
23
+ Layout/EndAlignment:
24
+ EnforcedStyleAlignWith: variable
25
+ Metrics/MethodLength:
26
+ CountAsOne: ['array', 'heredoc', 'hash']
27
+ Style/Documentation:
28
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,16 +1,11 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
+ - 3.0
4
5
  - 2.7
5
6
  - 2.6
6
- - 2.5
7
- - 2.4
8
- - 2.3
9
7
  gemfile: Gemfile.ci
10
8
  env:
11
- global:
12
- - CC_TEST_REPORTER_ID=289860573c6284a8e277de86848caba84d840be49e35f3601bcd672ab40d1e35
13
- - DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL=true
14
9
  matrix:
15
10
  - DATABASE_URL="sqlite::memory:" RACK_ENV=test
16
11
  before_install:
@@ -22,7 +17,7 @@ before_script:
22
17
  - bundle exec rake ditty:prep
23
18
  script:
24
19
  - bundle exec rake
25
- - bundle exec rubocop --fail-level W lib views specs
20
+ - bundle exec rubocop --fail-level W lib views spec
26
21
  after_script:
27
22
  - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
28
23
  after_success:
data/Gemfile.ci CHANGED
@@ -2,18 +2,3 @@
2
2
  source 'https://rubygems.org'
3
3
 
4
4
  gemspec
5
-
6
- gem 'faker'
7
- gem 'simplecov', '~> 0.13.0'
8
- gem 'sqlite3'
9
-
10
- if RUBY_VERSION < '2.1'
11
- gem 'sidekiq', '3.0.0'
12
- gem 'activesupport', '<4.0.0'
13
- gem 'omniauth', '~>1.4.2'
14
- elsif RUBY_VERSION < '2.2.0'
15
- gem 'sidekiq', '4.0.0'
16
- gem 'activesupport', '<5.0.0'
17
- else
18
- gem 'activesupport'
19
- end
data/ditty.gemspec CHANGED
@@ -21,37 +21,41 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_development_dependency 'bundler', '>= 1'
24
- spec.add_development_dependency 'database_cleaner'
24
+ spec.add_development_dependency 'dotenv'
25
+ spec.add_development_dependency 'database_cleaner', '~> 1.0'
25
26
  spec.add_development_dependency 'factory_bot'
26
- spec.add_development_dependency 'rack-test'
27
+ spec.add_development_dependency 'faker'
27
28
  spec.add_development_dependency 'racksh'
29
+ spec.add_development_dependency 'rack-test'
28
30
  spec.add_development_dependency 'rspec', '~> 3.0'
29
31
  spec.add_development_dependency 'rubocop'
30
32
  spec.add_development_dependency 'rubocop-performance'
31
33
  spec.add_development_dependency 'rubocop-rspec'
32
34
  spec.add_development_dependency 'rubocop-sequel'
33
35
  spec.add_development_dependency 'rubocop-thread_safety'
36
+ spec.add_development_dependency 'simplecov', '~> 0.13.0'
37
+ spec.add_development_dependency 'sqlite3'
34
38
  spec.add_development_dependency 'timecop'
35
39
 
36
- spec.add_dependency 'activesupport', '>= 3'
37
- spec.add_dependency 'bcrypt', '~> 3.1'
38
- spec.add_dependency 'browser', '~> 2.5'
40
+ spec.add_dependency 'activesupport', '>= 6'
41
+ spec.add_dependency 'bcrypt', '>= 3.1'
42
+ spec.add_dependency 'browser', '>= 5.3'
39
43
  spec.add_dependency 'dotenv', '>= 2'
40
- spec.add_dependency 'haml', '~> 5.1.2'
41
- spec.add_dependency 'logger', '~> 1.0'
44
+ spec.add_dependency 'haml', '>= 5.1.2'
45
+ spec.add_dependency 'logger', '>= 1.0'
42
46
  spec.add_dependency 'mail', '>= 1.7'
43
47
  spec.add_dependency 'oga', '>= 2.14'
44
48
  spec.add_dependency 'omniauth', '~> 1.0'
45
49
  spec.add_dependency 'omniauth-identity', '~> 1.0'
46
50
  spec.add_dependency 'pundit', '~> 1.0'
47
- spec.add_dependency 'rack-contrib', '~> 1.0'
48
- spec.add_dependency 'rack_csrf', '~> 1.0'
49
- spec.add_dependency 'rake', '~> 12.0'
50
- spec.add_dependency 'sequel', '>= 4.0'
51
- spec.add_dependency 'sinatra', '>= 2.0'
52
- spec.add_dependency 'sinatra-contrib', '~> 2.0'
53
- spec.add_dependency 'sinatra-flash', '~> 0.3'
54
- spec.add_dependency 'sinatra-param', '~> 1.5'
51
+ spec.add_dependency 'rack-contrib', '>= 2.0'
52
+ spec.add_dependency 'rack_csrf', '>= 2.0'
53
+ spec.add_dependency 'rake', '>= 13.0'
54
+ spec.add_dependency 'sequel', '>= 5.0'
55
+ spec.add_dependency 'sinatra', '>= 2.1'
56
+ spec.add_dependency 'sinatra-contrib', '>= 2.0'
57
+ spec.add_dependency 'sinatra-flash', '>= 0.3'
58
+ spec.add_dependency 'sinatra-param', '>= 1.6'
55
59
  spec.add_dependency 'thor', '>= 0.20'
56
60
  spec.add_dependency 'tilt', '>= 2'
57
61
  spec.add_dependency 'will_paginate', '>= 3.1'
data/lib/ditty.rb CHANGED
@@ -96,9 +96,9 @@ module Ditty
96
96
 
97
97
  # Return an ordered list of navigation items:
98
98
  # `[{order:0, link:'/users/', text:'Users'}, {order:1, link:'/roles/', text:'Roles'}]
99
- def self.navigation
99
+ def self.navigation(request)
100
100
  nav = components.each_with_object([]) do |comp, memo|
101
- memo.concat comp[1].navigation if comp[1].respond_to?(:navigation)
101
+ memo.concat comp[1].navigation(request) if comp[1].respond_to?(:navigation)
102
102
  end
103
103
  nav.sort_by { |v| v[:order] }
104
104
  end
data/lib/ditty/cli.rb CHANGED
@@ -11,6 +11,10 @@ require 'ditty/generators/project_generator'
11
11
  require 'ditty/generators/migration_generator'
12
12
  require 'ditty/components/ditty'
13
13
 
14
+ # TODO: Component generator
15
+ # TODO: Add requires into application.rb
16
+ # TODO: Add requires into schema.rb
17
+
14
18
  module Ditty
15
19
  class CLI < Thor
16
20
  include Thor::Actions
@@ -25,6 +29,7 @@ module Ditty
25
29
 
26
30
  desc 'server', 'Start the Ditty server'
27
31
  require './application' if File.exist?('application.rb')
32
+ require 'ditty/db' unless defined?(DB)
28
33
  ::Ditty::Components.tasks
29
34
  def server
30
35
  # Ensure the token files are present
@@ -29,10 +29,6 @@ module Ditty
29
29
  File.expand_path('../../../views', __dir__)
30
30
  end
31
31
 
32
- def self.public_folder
33
- File.expand_path('../../../public', __dir__)
34
- end
35
-
36
32
  def self.routes
37
33
  load
38
34
  {
@@ -45,20 +41,21 @@ module Ditty
45
41
  }
46
42
  end
47
43
 
48
- def self.navigation
44
+ def self.navigation(_request)
49
45
  load
50
46
 
51
47
  [
52
48
  {
53
49
  group: 'User Management',
54
- order: 10,
50
+ order: 50,
55
51
  icon: 'lock',
56
52
  target: ::Ditty::User,
57
53
  items: [
58
54
  { order: 10, link: '/users/', text: 'Users', target: ::Ditty::User, icon: 'user' },
59
55
  { order: 20, link: '/roles/', text: 'Roles', target: ::Ditty::Role, icon: 'check-square' },
60
56
  { order: 30, link: '/audit-logs/', text: 'Audit Logs', target: ::Ditty::AuditLog, icon: 'history' },
61
- { order: 40, link: '/login-traits/', text: 'User Login Traits', target: ::Ditty::UserLoginTrait, icon: 'list' }
57
+ { order: 40, link: '/login-traits/', text: 'User Login Traits', target: ::Ditty::UserLoginTrait,
58
+ icon: 'list' }
62
59
  ]
63
60
  }
64
61
  ]
@@ -20,7 +20,7 @@ module Ditty
20
20
  class ApplicationController < Sinatra::Base
21
21
  include ActiveSupport::Inflector
22
22
 
23
- set :root, ENV['APP_ROOT'] || ::File.expand_path(::File.dirname(__FILE__) + '/../../../')
23
+ set :root, ENV['APP_ROOT'] || ::File.expand_path("#{::File.dirname(__FILE__)}/../../../")
24
24
  set :map_path, nil
25
25
  set :view_location, nil
26
26
  set :view_folder, nil
@@ -37,7 +37,7 @@ module Ditty
37
37
  register Sinatra::Flash, Sinatra::RespondWith
38
38
 
39
39
  use Rack::Csrf, raise: ENV['APP_ENV'] == 'development' unless ENV['APP_ENV'] == 'test'
40
- use Rack::PostBodyContentTypeParser
40
+ use Rack::JSONBodyParser
41
41
  use Rack::MethodOverride
42
42
  use Rack::NestedParams
43
43
 
@@ -149,7 +149,8 @@ module Ditty
149
149
  haml :'400', locals: { title: '4 oh oh' }, layout: layout
150
150
  end
151
151
  format.json do
152
- json code: 400, errors: { env['sinatra.error'].param => env['sinatra.error'].message }, full_errors: [env['sinatra.error'].message]
152
+ json code: 400, errors: { env['sinatra.error'].param => env['sinatra.error'].message },
153
+ full_errors: [env['sinatra.error'].message]
153
154
  end
154
155
  end
155
156
  end
@@ -238,8 +239,8 @@ module Ditty
238
239
  request.path_info = request.path_info.gsub(/.csv$/, '')
239
240
  elsif request.env['ACCEPT']
240
241
  content_type request.env['ACCEPT']
241
- else
242
- content_type(:json) if request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
242
+ elsif request.accept.count.eql?(1) && request.accept.first.to_s.eql?('*/*')
243
+ content_type(:json)
243
244
  end
244
245
  end
245
246
 
@@ -25,6 +25,8 @@ module Ditty
25
25
  end
26
26
 
27
27
  def list
28
+ return super if params[:sort]
29
+
28
30
  super.order(:created_at).reverse
29
31
  end
30
32
 
@@ -24,7 +24,7 @@ module Ditty
24
24
 
25
25
  broadcast("before_#{provider}_login".to_sym, env['omniauth.auth'])
26
26
  user = User.first(email: env['omniauth.auth']['info']['email'])
27
- user = register_user if user.nil? && authorize(current_user, :register?)
27
+ user = register_user if user.nil? && authorize(::Ditty::User, :register?)
28
28
  return failed_login if user.nil?
29
29
 
30
30
  broadcast("#{provider}_login".to_sym, user)
@@ -96,7 +96,7 @@ module Ditty
96
96
  token = SecureRandom.hex(16)
97
97
  identity.update(reset_token: token, reset_requested: Time.now)
98
98
  # Send Email
99
- reset_url = "#{request.base_url}#{settings.map_path}/reset-password?token=#{token}"
99
+ reset_url = "#{request.base_url}#{settings.map_path}/auth/reset-password?token=#{token}"
100
100
  ::Ditty::Services::Email.deliver(
101
101
  :forgot_password,
102
102
  email,
@@ -105,6 +105,9 @@ module Ditty
105
105
  end
106
106
  flash[:info] = 'An email was sent to the email provided with instructions on how to reset your password'
107
107
  redirect "#{settings.map_path}/auth/login"
108
+ rescue Sinatra::Param::InvalidParameterError
109
+ flash[:warning] = 'Email address not provided'
110
+ redirect back
108
111
  end
109
112
 
110
113
  get '/reset-password' do
@@ -37,8 +37,8 @@ module Ditty
37
37
  after do
38
38
  return if settings.environment == 'production'
39
39
 
40
- if (response.successful? || response.redirection?) && @skip_verify == false
41
- verify_authorized if settings.environment != 'production'
40
+ if (response.successful? || response.redirection?) && @skip_verify == false && (settings.environment != 'production')
41
+ verify_authorized
42
42
  end
43
43
  end
44
44
 
@@ -96,7 +96,7 @@ module Ditty
96
96
  entity = read!(id)
97
97
  authorize entity, :update
98
98
 
99
- flash[:redirect_to] = "#{base_path}/#{entity.display_id}"
99
+ flash[:redirect_to] = "#{base_path}/#{entity.display_id}" unless flash.keep(:redirect_to)
100
100
  haml :"#{view_location}/edit",
101
101
  locals: { entity: entity, title: heading(:edit) },
102
102
  layout: layout
@@ -8,12 +8,39 @@ module Ditty
8
8
  class UserLoginTraitsController < ::Ditty::ComponentController
9
9
  SEARCHABLE = %i[platform device browser ip_address].freeze
10
10
  FILTERS = [
11
- { name: :user, field: 'user.email' }
11
+ { name: :user, field: 'user.email' },
12
+ { name: :platform },
13
+ { name: :device },
14
+ { name: :browser }
12
15
  ].freeze
13
16
 
14
17
  set base_path: '/login-traits'
15
18
  set model_class: UserLoginTrait
16
19
  set heading: 'Login'
17
20
  # set track_actions: true
21
+
22
+ helpers do
23
+ def user_options
24
+ policy_scope(::Ditty::User).as_hash(:email, :email)
25
+ end
26
+
27
+ def platform_options
28
+ policy_scope(::Ditty::UserLoginTrait).select(:platform).distinct.as_hash(:platform, :platform)
29
+ end
30
+
31
+ def device_options
32
+ policy_scope(::Ditty::UserLoginTrait).select(:device).distinct.as_hash(:device, :device)
33
+ end
34
+
35
+ def browser_options
36
+ policy_scope(::Ditty::UserLoginTrait).select(:browser).distinct.as_hash(:browser, :browser)
37
+ end
38
+ end
39
+
40
+ def list
41
+ return super if params[:sort]
42
+
43
+ super.order(:updated_at).reverse
44
+ end
18
45
  end
19
46
  end
@@ -55,7 +55,7 @@ module Ditty
55
55
  user.check_roles
56
56
  end
57
57
 
58
- broadcast(:component_create, target: self)
58
+ broadcast(:component_create, target: self, entity: user)
59
59
  create_response(user)
60
60
  end
61
61
 
@@ -96,7 +96,8 @@ module Ditty
96
96
 
97
97
  values = permitted_parameters(Identity, :create)
98
98
  identity.set values
99
- if identity.valid? && identity.save_changes
99
+ if identity.valid?
100
+ identity.save_changes
100
101
  broadcast(:identity_update_password, target: self)
101
102
  flash[:success] = 'Password Updated'
102
103
  redirect back
data/lib/ditty/db.rb CHANGED
@@ -23,10 +23,11 @@ elsif ENV['DATABASE_URL'].blank? == false
23
23
  DB.extension(:schema_caching)
24
24
  DB.load_schema_cache?('./config/schema.dump')
25
25
 
26
- Sequel::Model.plugin :validation_helpers
27
- Sequel::Model.plugin :update_or_create
28
- Sequel::Model.plugin :timestamps, update_on_create: true
29
26
  Sequel::Model.plugin :auto_validations
27
+ Sequel::Model.plugin :string_stripper
28
+ Sequel::Model.plugin :timestamps, update_on_create: true
29
+ Sequel::Model.plugin :update_or_create
30
+ Sequel::Model.plugin :validation_helpers
30
31
  else
31
32
  ::Ditty::Services::Logger.error 'No database connection set up'
32
33
  end
@@ -37,50 +37,52 @@ module Ditty
37
37
  end
38
38
 
39
39
  def respond_to_missing?(method, _include_private = false)
40
- mail.respond_to? method
40
+ return true if mail.respond_to?(method)
41
+
42
+ super
41
43
  end
42
44
 
43
45
  private
44
46
 
45
- def content
46
- result = Haml::Engine.new(content_haml).render(Object.new, locals)
47
- return result unless options[:layout]
47
+ def content
48
+ result = Haml::Engine.new(content_haml).render(Object.new, locals)
49
+ return result unless options[:layout]
48
50
 
49
- Haml::Engine.new(layout_haml).render(Object.new, locals.merge(content: result))
50
- end
51
+ Haml::Engine.new(layout_haml).render(Object.new, locals.merge(content: result))
52
+ end
51
53
 
52
- def content_haml
53
- read_template(options[:view])
54
- end
54
+ def content_haml
55
+ read_template(options[:view])
56
+ end
55
57
 
56
- def layout_haml
57
- read_template("layouts/#{options[:layout]}") if options[:layout]
58
- end
58
+ def layout_haml
59
+ read_template("layouts/#{options[:layout]}") if options[:layout]
60
+ end
59
61
 
60
- def read_template(template)
61
- File.read(find_template("emails/#{template}"))
62
- end
62
+ def read_template(template)
63
+ File.read(find_template("emails/#{template}"))
64
+ end
63
65
 
64
- def base_options
65
- { subject: '(No Subject)', from: 'no-reply@ditty.io', view: :base, content_type: 'text/html; charset=UTF-8' }
66
- end
66
+ def base_options
67
+ { subject: '(No Subject)', from: 'no-reply@ditty.io', view: :base, content_type: 'text/html; charset=UTF-8' }
68
+ end
67
69
 
68
- def find_template(file)
69
- template = File.expand_path("./views/#{file}.haml")
70
- return template if File.file? template
70
+ def find_template(file)
71
+ template = File.expand_path("./views/#{file}.haml")
72
+ return template if File.file? template
71
73
 
72
- template = File.expand_path("./#{file}.haml", App.view_folder)
73
- return template if File.file? template
74
+ template = File.expand_path("./#{file}.haml", App.view_folder)
75
+ return template if File.file? template
74
76
 
75
- file
76
- end
77
+ file
78
+ end
77
79
 
78
- class << self
79
- def deliver!(to = nil, options = {})
80
- locals = options[:locals] || {}
81
- new(options).deliver!(to, locals)
80
+ class << self
81
+ def deliver!(to = nil, options = {})
82
+ locals = options[:locals] || {}
83
+ new(options).deliver!(to, locals)
84
+ end
82
85
  end
83
- end
84
86
  end
85
87
  end
86
88
  end