trusty-cms 7.0.28 → 7.0.30

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +15 -1
  4. data/INSTALL.md +21 -3
  5. data/README.md +0 -1
  6. data/app/assets/stylesheets/admin/modules/_buttons.scss +4 -1
  7. data/app/assets/stylesheets/admin/partials/_forms.scss +4 -0
  8. data/app/controllers/admin/security_controller.rb +78 -0
  9. data/app/controllers/admin/sessions_controller.rb +43 -0
  10. data/app/controllers/admin/two_factor_controller.rb +42 -0
  11. data/app/controllers/admin/users_controller.rb +9 -0
  12. data/app/controllers/application_controller.rb +7 -0
  13. data/app/models/standard_tags.rb +0 -16
  14. data/app/models/trusty_cms/config.rb +0 -4
  15. data/app/models/user.rb +1 -1
  16. data/app/views/admin/configuration/edit.html.haml +0 -7
  17. data/app/views/admin/configuration/show.html.haml +21 -12
  18. data/app/views/admin/preferences/edit.html.haml +1 -4
  19. data/app/views/admin/security/edit.html.haml +57 -0
  20. data/app/views/{devise → admin}/sessions/new.html.haml +5 -5
  21. data/app/views/admin/two_factor/show.html.haml +14 -0
  22. data/app/views/admin/users/_form.html.haml +0 -3
  23. data/app/views/admin/users/index.html.haml +22 -1
  24. data/app/views/devise/passwords/edit.html.haml +2 -4
  25. data/config/initializers/active_record_encryption.rb +5 -0
  26. data/config/initializers/devise.rb +4 -0
  27. data/config/initializers/trusty_cms_config.rb +0 -1
  28. data/config/locales/en.yml +30 -5
  29. data/config/routes.rb +9 -6
  30. data/db/migrate/20250502162215_add_devise_two_factor_to_admins.rb +7 -0
  31. data/lib/generators/trusty_cms/templates/application.rb.erb +1 -1
  32. data/lib/trusty_cms/admin_ui.rb +12 -7
  33. data/lib/trusty_cms/engine.rb +0 -3
  34. data/lib/trusty_cms/version.rb +1 -1
  35. data/package.json +1 -1
  36. data/spec/dummy/config/application.rb +1 -1
  37. data/spec/dummy/config/initializers/trusty_cms_config.rb +0 -1
  38. data/trusty_cms.gemspec +2 -0
  39. data/yarn.lock +4 -4
  40. metadata +38 -18
  41. data/app/assets/javascripts/rad_social/jquery.validate.min.js +0 -4
  42. data/app/assets/javascripts/rad_social/rad_ajax_form.js +0 -82
  43. data/app/assets/javascripts/rad_social/rad_email.js +0 -5
  44. data/app/assets/javascripts/rad_social/rad_email_form.js +0 -80
  45. data/app/assets/javascripts/rad_social/rad_email_validator.js +0 -47
  46. data/app/assets/javascripts/rad_social/rad_widget.js +0 -20
  47. data/app/assets/stylesheets/rad_social/rad_screen.scss +0 -141
  48. data/app/controllers/social_mailer_controller.rb +0 -26
  49. data/app/helpers/rad_social_helper.rb +0 -20
  50. data/app/mailers/rad_social_mailer.rb +0 -25
  51. data/app/views/admin/users/_password_fields.html.haml +0 -18
  52. data/app/views/rad_social_mailer/social_mail.html.haml +0 -5
  53. data/app/views/rad_social_mailer/social_mail_form.html.haml +0 -39
  54. data/app/views/widget/_email_form.html.haml +0 -20
  55. data/app/views/widget/_horizontal_widget.html.haml +0 -16
@@ -11,6 +11,10 @@ require 'devise'
11
11
  # Use this hook to configure devise mailer, warden hooks and so forth.
12
12
  # Many of these configuration options can be set straight in your model.
13
13
  Devise.setup do |config|
14
+ config.warden do |manager|
15
+ manager.default_strategies(:scope => :user).unshift :two_factor_authenticatable
16
+ end
17
+
14
18
  # The secret key used by Devise. Devise uses this key to generate
15
19
  # random tokens. Changing this key will render invalid all existing
16
20
  # confirmation, reset password and unlock tokens in the database.
@@ -12,7 +12,6 @@ Rails.application.reloader.to_prepare do
12
12
  config.define 'admin.pagination.per_page', type: :integer, default: 50
13
13
  config.define 'site.title', default: 'Your site title', allow_blank: false
14
14
  config.define 'site.host', default: 'www.example.com', allow_blank: false
15
- config.define 'user.allow_password_reset?', default: true
16
15
  config.define 'session_timeout', default: 2.weeks
17
16
  require 'multi_site/scoped_validation'
18
17
  end
@@ -55,6 +55,7 @@ en:
55
55
  save_changes: 'Save Changes'
56
56
  cancel: 'Cancel'
57
57
  change: 'Change'
58
+ change_password: 'Change Password'
58
59
  clipped_extension:
59
60
  actions: Actions
60
61
  all: 'All'
@@ -155,8 +156,6 @@ en:
155
156
  site:
156
157
  title: "site title"
157
158
  host: "site domain"
158
- user:
159
- allow_password_reset?: "allow password reset"
160
159
  content: 'Content'
161
160
  content_type: 'Content‑Type'
162
161
  content_editor: 'Content Editor'
@@ -182,6 +181,8 @@ en:
182
181
  description: 'Description'
183
182
  design: 'Design'
184
183
  designer: 'Designer'
184
+ disable: 'Disable'
185
+ disabled: 'Disabled'
185
186
  draft: 'Draft'
186
187
  edit: 'Edit'
187
188
  editor: 'Editor'
@@ -189,14 +190,17 @@ en:
189
190
  edit_layout: 'Edit Layout'
190
191
  edit_page: 'Edit Page'
191
192
  edit_preferences: 'Edit Preferences'
193
+ edit_security_settings: 'Edit Security Settings'
192
194
  edit_settings: 'Edit Settings'
193
195
  edit_user: 'Edit User'
194
196
  email_address: 'E-mail Address'
197
+ enabled: 'Enabled'
195
198
  extension: 'Extension'
196
199
  extensions: 'Extensions'
197
200
  filter: 'Filter'
198
201
  hidden: 'Hidden'
199
202
  hide: 'Hide'
203
+ invalid_email_or_password: 'Invalid e-mail address or password.'
200
204
  keywords: 'Keywords'
201
205
  language: 'Language'
202
206
  layout: 'Layout'
@@ -267,11 +271,27 @@ en:
267
271
  validation_errors: "Validation errors occurred while processing this form. Please take a moment to review the form and correct any input errors before continuing."
268
272
  reviewed: 'Reviewed'
269
273
  roles: 'Roles'
270
- saving_changes: Saving Changes
271
- saving_preferences: Saving preferences
272
- scheduled: "Scheduled"
274
+ saving_changes: 'Saving Changes'
275
+ saving_preferences: 'Saving Preferences'
276
+ scheduled: 'Scheduled'
273
277
  search: 'Search'
274
278
  search_tags: 'Search Tags:'
279
+ security: 'Security'
280
+ security_controller:
281
+ enter_qr_code: 'Enter 6-Digit Verification Code'
282
+ error_updating_password: 'There was an error updating your password.'
283
+ manual_key_instructions: 'Or manually enter this secret key:'
284
+ password_updated: 'Password updated. Please log in again.'
285
+ scan_qr_instructions: 'Scan this QR code in your Authenticator app:'
286
+ two_factor_enabled: 'Two-Factor Authentication Enabled'
287
+ two_factor_is_enabled: 'Two-Factor Authentication is currently enabled.'
288
+ two_factor_disable_confirm: 'Are you sure you want to disable Two-Factor Authentication?'
289
+ two_factor_disabled: 'Two-Factor Authentication Disabled'
290
+ two_factor_disabled_error: 'Error Disabling Two-Factor Authentication'
291
+ two_factor_invalid_code: 'Invalid 2FA Code'
292
+ qr_alt: 'Scan this with Google Authenticator or Authy'
293
+ verify_code: 'Verify Code'
294
+ verify_and_enable: 'Verify and Enable 2FA'
275
295
  select:
276
296
  default: '<default>'
277
297
  inherit: '<inherit>'
@@ -312,6 +332,11 @@ en:
312
332
  at: 'at'
313
333
  by: 'by'
314
334
  last_updated: 'Last Updated'
335
+ two_factor_authentication: 'Two-Factor Authentication'
336
+ two_factor_authentication_status: '2FA Status'
337
+ two_factor_controller:
338
+ invalid_code: 'Invalid two-factor authentication code.'
339
+ session_expired: 'Your session has expired. Please log in again.'
315
340
  type: 'Type'
316
341
  units:
317
342
  KB: "KB"
data/config/routes.rb CHANGED
@@ -1,12 +1,9 @@
1
1
  TrustyCms::Application.routes.draw do
2
2
  root to: 'site#show_page'
3
- devise_for :users, module: :devise, skip: :registration
4
- as :user do
5
- post 'authenticate', to: 'devise/sessions#create', as: :authenticate
6
- end
3
+ devise_for :users,
4
+ controllers: { sessions: 'admin/sessions' },
5
+ skip: :registration
7
6
  post '/page-status/refresh' => 'page_status#refresh'
8
- get '/rad_social/mail' => 'social_mailer#social_mail_form', as: :rad_social_mail_form
9
- post '/rad_social/mail' => 'social_mailer#create_social_mail', as: :rad_create_social_mail
10
7
  TrustyCms::Application.config.enabled_extensions.each do |ext|
11
8
  end
12
9
  namespace :admin do
@@ -21,6 +18,7 @@ TrustyCms::Application.routes.draw do
21
18
  end
22
19
  resources :users do
23
20
  get 'remove', on: :member
21
+ patch 'disable_2fa', on: :member
24
22
  end
25
23
  resources :snippets do
26
24
  get :remove, on: :member
@@ -46,6 +44,11 @@ TrustyCms::Application.routes.draw do
46
44
 
47
45
  namespace :admin do
48
46
  resource :preferences
47
+ resource :two_factor, only: [:show, :create], controller: 'two_factor', path: 'two-factor'
48
+ resource :security, controller: 'security' do
49
+ post :verify_two_factor, on: :collection
50
+ post :disable_two_factor, on: :collection
51
+ end
49
52
  resource :configuration, controller: 'configuration'
50
53
  resources :extensions, only: :index
51
54
  resources :page_parts
@@ -0,0 +1,7 @@
1
+ class AddDeviseTwoFactorToAdmins < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :admins, :otp_secret, :string
4
+ add_column :admins, :consumed_timestep, :integer
5
+ add_column :admins, :otp_required_for_login, :boolean
6
+ end
7
+ end
@@ -49,7 +49,7 @@ module TrustyCms
49
49
  # can be used as a placeholder for all extensions not explicitly named.
50
50
 
51
51
  # An example of how to add extensions:
52
- # config.extensions = [ :snippets, :clipped, :layouts, :reorder, :multi_site, :rad_social]
52
+ # config.extensions = [ :snippets, :clipped, :layouts, :reorder, :multi_site ]
53
53
 
54
54
  config.extensions = []
55
55
 
@@ -150,6 +150,7 @@ module TrustyCms
150
150
  settings = nav_tab('Settings')
151
151
  settings << nav_item('General', '/admin/configuration')
152
152
  settings << nav_item('Personal', '/admin/preferences')
153
+ settings << nav_item('Security', '/admin/security')
153
154
  settings << nav_item('Users', '/admin/users')
154
155
  settings << nav_item('Extensions', '/admin/extensions')
155
156
  nav << settings
@@ -190,18 +191,22 @@ module TrustyCms
190
191
  OpenStruct.new.tap do |user|
191
192
  user.preferences = RegionSet.new do |preferences|
192
193
  preferences.main.concat %w{edit_header edit_form}
193
- preferences.form.concat %w{edit_first_name edit_last_name edit_email edit_password}
194
+ preferences.form.concat %w{edit_first_name edit_last_name edit_email}
194
195
  preferences.form_bottom.concat %w{edit_buttons}
195
196
  end
197
+ user.security = RegionSet.new do |security|
198
+ security.main.concat %w{edit_header edit_form two_factor}
199
+ security.form.concat %w{edit_password}
200
+ security.form_bottom.concat %w{edit_buttons}
201
+ end
196
202
  user.edit = RegionSet.new do |edit|
197
203
  edit.main.concat %w{edit_header edit_form}
198
- edit.form.concat %w{edit_first_name edit_last_name edit_email edit_password
199
- edit_roles edit_notes}
204
+ edit.form.concat %w{edit_first_name edit_last_name edit_email edit_roles edit_notes}
200
205
  edit.form_bottom.concat %w{edit_buttons edit_timestamp}
201
206
  end
202
207
  user.index = RegionSet.new do |index|
203
- index.thead.concat %w{title_header roles_header actions_header last_sign_in_at_header}
204
- index.tbody.concat %w{title_cell roles_cell actions_cell last_sign_in_at_cell}
208
+ index.thead.concat %w{title_header roles_header two_factor_status_header disable_two_factor_header actions_header last_sign_in_at_header}
209
+ index.tbody.concat %w{title_cell roles_cell two_factor_status_cell disable_two_factor_cell actions_cell last_sign_in_at_cell}
205
210
  index.bottom.concat %w{new_button}
206
211
  end
207
212
  user.new = user.edit
@@ -231,11 +236,11 @@ module TrustyCms
231
236
  OpenStruct.new.tap do |configuration|
232
237
  configuration.show = RegionSet.new do |show|
233
238
  show.user.concat %w{preferences}
234
- show.trusty_config.concat %w{site defaults users}
239
+ show.trusty_config.concat %w{site defaults}
235
240
  end
236
241
  configuration.edit = RegionSet.new do |edit|
237
242
  edit.main.concat %w{edit_header edit_form}
238
- edit.form.concat %w{edit_site edit_defaults edit_users}
243
+ edit.form.concat %w{edit_site edit_defaults}
239
244
  edit.form_bottom.concat %w{edit_buttons}
240
245
  end
241
246
  end
@@ -18,9 +18,6 @@ module TrustyCms
18
18
  ckeditor/styles.js
19
19
  ckeditor/skins/moono/editor.css
20
20
  ckeditor/lang/en.js
21
- rad_social/rad_screen.css
22
- rad_social/rad_email.js
23
- rad_social/rad_widget.js
24
21
  )
25
22
  end
26
23
  end
@@ -1,3 +1,3 @@
1
1
  module TrustyCms
2
- VERSION = '7.0.28'.freeze
2
+ VERSION = '7.0.30'.freeze
3
3
  end
data/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "jquery-treetable": "^3.2.0-1",
14
14
  "jquery-ui": "^1.13.2",
15
15
  "jquery-ujs": "^1.2.2",
16
- "jquery-validation": "^1.19.5",
16
+ "jquery-validation": "^1.20.0",
17
17
  "js-cookie": "^3.0.1",
18
18
  "tablesaw": "^3.1.2"
19
19
  },
@@ -53,7 +53,7 @@ module TrustyCms
53
53
  # can be used as a placeholder for all extensions not explicitly named.
54
54
 
55
55
  # An example of how to add extensions:
56
- # config.extensions = [ :snippets, :clipped, :layouts, :reorder, :multi_site, :rad_social]
56
+ # config.extensions = [ :snippets, :clipped, :layouts, :reorder, :multi_site ]
57
57
 
58
58
  config.extensions = []
59
59
  config.extensions_migration_order = []
@@ -13,7 +13,6 @@ Rails.application.reloader.to_prepare do
13
13
  config.define 'admin.pagination.per_page', :type => :integer, :default => 50
14
14
  config.define 'site.title', :default => "Your site title", :allow_blank => false
15
15
  config.define 'site.host', :default => "www.example.com", :allow_blank => false
16
- config.define 'user.allow_password_reset?', :default => true
17
16
  end
18
17
 
19
18
  TrustyCms::Application.config do |config|
data/trusty_cms.gemspec CHANGED
@@ -33,6 +33,7 @@ a general purpose content management system--not merely a blogging engine.'
33
33
  s.add_dependency 'ckeditor', '>= 4.2.2', '< 4.4.0'
34
34
  s.add_dependency 'delocalize', '>= 0.2', '< 2.0'
35
35
  s.add_dependency 'devise'
36
+ s.add_dependency 'devise-two-factor'
36
37
  s.add_dependency 'drb'
37
38
  s.add_dependency 'execjs', '~> 2.7'
38
39
  s.add_dependency 'haml', '>= 5.0', '< 6.0'
@@ -55,6 +56,7 @@ a general purpose content management system--not merely a blogging engine.'
55
56
  s.add_dependency 'rdoc', '>= 5.1', '< 7.0'
56
57
  s.add_dependency 'RedCloth', '4.3.3'
57
58
  s.add_dependency 'roadie-rails'
59
+ s.add_dependency 'rqrcode'
58
60
  s.add_dependency 'sass-rails'
59
61
  s.add_dependency 'stringex', '>= 2.7.1', '< 2.9.0'
60
62
  s.add_dependency 'tzinfo', '>= 1.2.3', '< 2.1.0'
data/yarn.lock CHANGED
@@ -1029,10 +1029,10 @@ jquery-ujs@^1.2.2:
1029
1029
  dependencies:
1030
1030
  jquery ">=1.8.0"
1031
1031
 
1032
- jquery-validation@^1.19.5:
1033
- version "1.19.5"
1034
- resolved "https://registry.yarnpkg.com/jquery-validation/-/jquery-validation-1.19.5.tgz#557495b7cad79716897057c4447ad3cd76fda811"
1035
- integrity sha512-X2SmnPq1mRiDecVYL8edWx+yTBZDyC8ohWXFhXdtqFHgU9Wd4KHkvcbCoIZ0JaSaumzS8s2gXSkP8F7ivg/8ZQ==
1032
+ jquery-validation@^1.20.0:
1033
+ version "1.20.0"
1034
+ resolved "https://registry.yarnpkg.com/jquery-validation/-/jquery-validation-1.20.0.tgz#dbff6d8fe61b07d4b6f844bf2f5405146556b991"
1035
+ integrity sha512-c8tg4ltIIP6L7l0bZ79sRzOJYquyjS48kQZ6iv8MJ2r0OYztxtkWYKTReZyU2/zVFYiINB29i0Z/IRNNuJQN1g==
1036
1036
 
1037
1037
  jquery@>=1.6:
1038
1038
  version "3.6.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trusty-cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.28
4
+ version: 7.0.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - TrustyCms CMS dev team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-11 00:00:00.000000000 Z
11
+ date: 2025-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage-validator
@@ -140,6 +140,20 @@ dependencies:
140
140
  - - ">="
141
141
  - !ruby/object:Gem::Version
142
142
  version: '0'
143
+ - !ruby/object:Gem::Dependency
144
+ name: devise-two-factor
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
143
157
  - !ruby/object:Gem::Dependency
144
158
  name: drb
145
159
  requirement: !ruby/object:Gem::Requirement
@@ -472,6 +486,20 @@ dependencies:
472
486
  - - ">="
473
487
  - !ruby/object:Gem::Version
474
488
  version: '0'
489
+ - !ruby/object:Gem::Dependency
490
+ name: rqrcode
491
+ requirement: !ruby/object:Gem::Requirement
492
+ requirements:
493
+ - - ">="
494
+ - !ruby/object:Gem::Version
495
+ version: '0'
496
+ type: :runtime
497
+ prerelease: false
498
+ version_requirements: !ruby/object:Gem::Requirement
499
+ requirements:
500
+ - - ">="
501
+ - !ruby/object:Gem::Version
502
+ version: '0'
475
503
  - !ruby/object:Gem::Dependency
476
504
  name: sass-rails
477
505
  requirement: !ruby/object:Gem::Requirement
@@ -713,12 +741,6 @@ files:
713
741
  - app/assets/javascripts/admin/validations/user_validations.js
714
742
  - app/assets/javascripts/ckeditor/config.js
715
743
  - app/assets/javascripts/ckeditor/contents.css
716
- - app/assets/javascripts/rad_social/jquery.validate.min.js
717
- - app/assets/javascripts/rad_social/rad_ajax_form.js
718
- - app/assets/javascripts/rad_social/rad_email.js
719
- - app/assets/javascripts/rad_social/rad_email_form.js
720
- - app/assets/javascripts/rad_social/rad_email_validator.js
721
- - app/assets/javascripts/rad_social/rad_widget.js
722
744
  - app/assets/stylesheets/admin/_base.scss
723
745
  - app/assets/stylesheets/admin/_multi_site_main.scss
724
746
  - app/assets/stylesheets/admin/_reset.scss
@@ -750,7 +772,6 @@ files:
750
772
  - app/assets/stylesheets/admin/partials/_treetable.scss
751
773
  - app/assets/stylesheets/admin/partials/_typography.scss
752
774
  - app/assets/stylesheets/admin/partials/_validations.scss
753
- - app/assets/stylesheets/rad_social/rad_screen.scss
754
775
  - app/controllers/admin/assets_controller.rb
755
776
  - app/controllers/admin/configuration_controller.rb
756
777
  - app/controllers/admin/extensions_controller.rb
@@ -762,13 +783,15 @@ files:
762
783
  - app/controllers/admin/preferences_controller.rb
763
784
  - app/controllers/admin/references_controller.rb
764
785
  - app/controllers/admin/resource_controller.rb
786
+ - app/controllers/admin/security_controller.rb
787
+ - app/controllers/admin/sessions_controller.rb
765
788
  - app/controllers/admin/sites_controller.rb
766
789
  - app/controllers/admin/snippets_controller.rb
790
+ - app/controllers/admin/two_factor_controller.rb
767
791
  - app/controllers/admin/users_controller.rb
768
792
  - app/controllers/application_controller.rb
769
793
  - app/controllers/page_status_controller.rb
770
794
  - app/controllers/site_controller.rb
771
- - app/controllers/social_mailer_controller.rb
772
795
  - app/helpers/admin/configuration_helper.rb
773
796
  - app/helpers/admin/export_helper.rb
774
797
  - app/helpers/admin/extensions_helper.rb
@@ -784,13 +807,11 @@ files:
784
807
  - app/helpers/admin/users_helper.rb
785
808
  - app/helpers/admin/welcome_helper.rb
786
809
  - app/helpers/application_helper.rb
787
- - app/helpers/rad_social_helper.rb
788
810
  - app/helpers/scoped_helper.rb
789
811
  - app/helpers/site_helper.rb
790
812
  - app/helpers/sites_helper.rb
791
813
  - app/mailers/application_mailer.rb
792
814
  - app/mailers/devise_mailer.rb
793
- - app/mailers/rad_social_mailer.rb
794
815
  - app/models/admins_site.rb
795
816
  - app/models/asset.rb
796
817
  - app/models/asset_type.rb
@@ -871,6 +892,8 @@ files:
871
892
  - app/views/admin/removed/_show_bucket_link.html.haml
872
893
  - app/views/admin/removed/_upload_to_page.html.haml
873
894
  - app/views/admin/removed/bucket/_iframe.html.haml
895
+ - app/views/admin/security/edit.html.haml
896
+ - app/views/admin/sessions/new.html.haml
874
897
  - app/views/admin/sites/_form.haml
875
898
  - app/views/admin/sites/edit.haml
876
899
  - app/views/admin/sites/index.haml
@@ -882,9 +905,9 @@ files:
882
905
  - app/views/admin/snippets/index.html.haml
883
906
  - app/views/admin/snippets/new.html.haml
884
907
  - app/views/admin/snippets/remove.html.haml
908
+ - app/views/admin/two_factor/show.html.haml
885
909
  - app/views/admin/users/_choose_site.html.haml
886
910
  - app/views/admin/users/_form.html.haml
887
- - app/views/admin/users/_password_fields.html.haml
888
911
  - app/views/admin/users/edit.html.haml
889
912
  - app/views/admin/users/index.html.haml
890
913
  - app/views/admin/users/new.html.haml
@@ -892,19 +915,14 @@ files:
892
915
  - app/views/admin/welcome/login.html.haml
893
916
  - app/views/devise/passwords/edit.html.haml
894
917
  - app/views/devise/passwords/new.html.haml
895
- - app/views/devise/sessions/new.html.haml
896
918
  - app/views/devise/shared/_links.html.haml
897
919
  - app/views/devise_mailer/reset_password_instructions.html.haml
898
920
  - app/views/layouts/application.html.haml
899
921
  - app/views/layouts/mail.html.haml
900
922
  - app/views/layouts/mailer.text.haml
901
923
  - app/views/layouts/trusty.html.haml
902
- - app/views/rad_social_mailer/social_mail.html.haml
903
- - app/views/rad_social_mailer/social_mail_form.html.haml
904
924
  - app/views/site/not_found.html.haml
905
925
  - app/views/site/show_page.html.haml
906
- - app/views/widget/_email_form.html.haml
907
- - app/views/widget/_horizontal_widget.html.haml
908
926
  - bin/rails
909
927
  - bin/trusty_cms
910
928
  - config.ru
@@ -915,6 +933,7 @@ files:
915
933
  - config/environments/development.rb
916
934
  - config/environments/production.rb
917
935
  - config/environments/test.rb
936
+ - config/initializers/active_record_encryption.rb
918
937
  - config/initializers/active_record_extensions.rb
919
938
  - config/initializers/assets.rb
920
939
  - config/initializers/devise.rb
@@ -981,6 +1000,7 @@ files:
981
1000
  - db/migrate/20250102212417_create_versions.rb
982
1001
  - db/migrate/20250103191133_create_version_associations.rb
983
1002
  - db/migrate/20250103191134_add_transaction_id_column_to_versions.rb
1003
+ - db/migrate/20250502162215_add_devise_two_factor_to_admins.rb
984
1004
  - db/schema.rb
985
1005
  - lib/active_record_extensions/active_record_extensions.rb
986
1006
  - lib/annotatable.rb
@@ -1,4 +0,0 @@
1
- /*! jQuery Validation Plugin - v1.13.0 - 7/1/2014
2
- * http://jqueryvalidation.org/
3
- * Copyright (c) 2014 Jörn Zaefferer; Licensed MIT */
4
- !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(b.target).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d;return c.settings.submitHandler?(c.submitButton&&(d=a("<input type='hidden'/>").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c;return a(this[0]).is("form")?b=this.validate().form():(b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b})),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(a,b){(9!==b.which||""!==this.elementValue(a))&&(a.name in this.submitted||a===this.lastElement)&&this.element(a)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!this.is(e.ignore)&&e[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']","focusin focusout keyup",b).validateDelegate("select, option, [type='radio'], [type='checkbox']","click",b),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue").removeAttr("aria-invalid")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?a("input[name='"+b.name+"']:checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a];return void 0},defaultMessage:function(b,c){return this.findDefined(this.customMessage(b.name,c),this.customDataMessage(b,c),!this.settings.ignoreTitle&&b.title||void 0,a.validator.messages[c],"<strong>Warning: No message defined for "+b.name+"</strong>")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id"),i?i.match(new RegExp("\b"+f+"\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(a){return this.checkable(a)&&(a=this.findByName(a.name).not(this.settings.ignore)[0]),a},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),/min|max/.test(c)&&(null===g||/number|range|text/.test(g))&&(d=Number(d)),d||0===d?e[c]=d:g===c&&"range"!==g&&(e[c]=!0);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b);for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),void 0!==d&&(e[c]=d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(b.min&&b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),b.minlength&&b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}}),a.format=function(){throw"$.format has been deprecated. Please use $.validator.format instead."};var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);return e.is(b)?d.apply(e,arguments):void 0})}})});
@@ -1,82 +0,0 @@
1
- function RadAjaxForm(form) {
2
- var self = this;
3
- this.submitWithoutValidation = function(onSuccess, onError, onComplete) {
4
- if (onError === undefined) {
5
- onError = function() {
6
- };
7
- }
8
- if (onComplete === undefined) {
9
- onComplete = function() {
10
- };
11
- }
12
-
13
- form.find(".loader").addClass('ajax-loader');
14
- form.find(".loader-small").addClass('ajax-loader-small');
15
- $.ajax({
16
- type: "POST",
17
- url: form.find('input[name=submit_url]').attr('value'),
18
- data: form.serialize(),
19
- beforeSend: function ( xhr ) {
20
- xhr.setRequestHeader("X-CSRF-Token", $('meta[name=csrf-token]').attr('content'));
21
- },
22
- success: function(data, status, xhr) {
23
- form.find(".loader").removeClass('ajax-loader');
24
- form.find(".loader-small").removeClass('ajax-loader-small');
25
- onSuccess(data, status, xhr);
26
- },
27
- error: function(data) {
28
- form.find(".loader").removeClass('ajax-loader');
29
- form.find(".loader-small").removeClass('ajax-loader-small');
30
- form.find('.continue').attr('disabled', false);
31
- onError(data);
32
- },
33
- complete: onComplete
34
- });
35
- form.find('.continue').attr('disabled', 'disabled');
36
- return true;
37
- };
38
-
39
- this.defaultSubmitWithoutValidation = function() {
40
- this.submitWithoutValidation(handleSuccess, handleFailure);
41
- };
42
-
43
- this.submit = function(onSuccess, onError, onComplete) {
44
- if (onComplete === undefined) {
45
- onComplete = function() {
46
- };
47
- }
48
-
49
- if (onError === undefined) {
50
- onError = handleFailure;
51
- }
52
-
53
- if (!form.valid()) {
54
- onComplete();
55
- return true;
56
- }
57
- return self.submitWithoutValidation(onSuccess, onError, onComplete);
58
- };
59
-
60
-
61
- function handleSuccess(data, status, xhr)
62
- {
63
- var url = xhr.getResponseHeader("BrowserRedirectTo");
64
- if (url) {
65
- location.href = url
66
- }
67
- }
68
-
69
- function handleFailure(xhr) {
70
- var errorMessage = xhr.getResponseHeader("ErrorMsg");
71
- var errorMessageDialog = new ModalDialog('', function(element) {
72
- return {
73
- autoOpen: false,
74
- minHeight: 20,
75
- title: "We're Sorry!",
76
- dialogClass: 'seat-error-dialog'
77
- };
78
- });
79
- errorMessageDialog.show(errorMessage);
80
- }
81
-
82
- }
@@ -1,5 +0,0 @@
1
- //= require jquery
2
- //= require 'rad_social/jquery.validate.min'
3
- //= require 'rad_social/rad_ajax_form'
4
- //= require 'rad_social/rad_email_validator'
5
- //= require 'rad_social/rad_email_form'