ditty 0.9.1 → 0.10.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 (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