fat_free_crm 0.13.0 → 0.13.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.

Potentially problematic release.


This version of fat_free_crm might be problematic. Click here for more details.

Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Capfile +1 -4
  3. data/Gemfile.lock +0 -1
  4. data/README.md +1 -0
  5. data/app/assets/javascripts/lists.js.coffee +1 -2
  6. data/app/controllers/application_controller.rb +27 -25
  7. data/app/controllers/emails_controller.rb +1 -30
  8. data/app/controllers/entities/contacts_controller.rb +1 -1
  9. data/app/controllers/entities/opportunities_controller.rb +1 -1
  10. data/app/controllers/entities_controller.rb +0 -1
  11. data/app/controllers/home_controller.rb +0 -4
  12. data/app/controllers/passwords_controller.rb +3 -3
  13. data/app/controllers/tasks_controller.rb +17 -10
  14. data/app/controllers/users_controller.rb +23 -46
  15. data/app/helpers/application_helper.rb +0 -3
  16. data/app/helpers/campaigns_helper.rb +0 -1
  17. data/app/helpers/leads_helper.rb +0 -11
  18. data/app/helpers/opportunities_helper.rb +0 -1
  19. data/app/helpers/tags_helper.rb +0 -8
  20. data/app/helpers/versions_helper.rb +1 -1
  21. data/app/models/entities/account_contact.rb +1 -1
  22. data/app/models/entities/campaign.rb +3 -3
  23. data/app/models/entities/contact.rb +3 -3
  24. data/app/models/entities/lead.rb +5 -5
  25. data/app/models/entities/opportunity.rb +1 -3
  26. data/app/models/fields/field_group.rb +1 -0
  27. data/app/models/list.rb +2 -1
  28. data/app/models/polymorphic/avatar.rb +1 -1
  29. data/app/models/polymorphic/task.rb +7 -4
  30. data/app/models/setting.rb +0 -3
  31. data/app/models/users/ability.rb +13 -2
  32. data/app/models/users/user.rb +4 -1
  33. data/app/views/home/index.html.haml +0 -4
  34. data/app/views/layouts/application.html.haml +7 -5
  35. data/app/views/leads/_contact.html.haml +0 -3
  36. data/app/views/lists/_personal_sidebar.html.haml +2 -2
  37. data/app/views/lists/_sidebar.html.haml +2 -2
  38. data/config/application.rb +2 -2
  39. data/config/environments/development.rb +2 -0
  40. data/config/environments/production.rb +2 -3
  41. data/config/initializers/secret_token.rb +25 -1
  42. data/config/locales/en-US_fat_free_crm.yml +1 -1
  43. data/config/routes.rb +27 -32
  44. data/config/settings.default.yml +3 -4
  45. data/lib/development_tasks/rspec.rake +1 -5
  46. data/lib/fat_free_crm.rb +11 -1
  47. data/lib/fat_free_crm/fields.rb +1 -1
  48. data/lib/fat_free_crm/gem_ext/rails/text_helper.rb +1 -2
  49. data/lib/fat_free_crm/secret_token_generator.rb +59 -0
  50. data/lib/fat_free_crm/version.rb +1 -1
  51. data/spec/controllers/admin/users_controller_spec.rb +1 -3
  52. data/spec/controllers/home_controller_spec.rb +0 -7
  53. data/spec/controllers/passwords_controller_spec.rb +23 -5
  54. data/spec/controllers/users_controller_spec.rb +45 -17
  55. data/spec/lib/secret_token_generator_spec.rb +55 -0
  56. data/spec/models/users/abilities/user_ability_spec.rb +58 -0
  57. data/spec/routing/emails_routing_spec.rb +13 -14
  58. data/spec/spec_helper.rb +2 -1
  59. metadata +5 -2
@@ -302,7 +302,6 @@ module ApplicationHelper
302
302
  args = { :class => 'gravatar', :size => :large }.merge(args)
303
303
 
304
304
  if model.respond_to?(:avatar) and model.avatar.present?
305
- Avatar
306
305
  image_tag(model.avatar.image.url(args[:size]), args)
307
306
  else
308
307
  args = Avatar.size_from_style!(args) # convert size format :large => '75x75'
@@ -400,7 +399,6 @@ module ApplicationHelper
400
399
  check_box_tag("#{name}[]", value, checked, :id => value, :onclick => onclick)
401
400
  end
402
401
 
403
-
404
402
  # Create a column in the 'asset_attributes' table.
405
403
  #----------------------------------------------------------------------------
406
404
  def col(title, value, last = false, email = false)
@@ -493,5 +491,4 @@ module ApplicationHelper
493
491
  end
494
492
  end
495
493
 
496
-
497
494
  end
@@ -33,4 +33,3 @@ module CampaignsHelper
33
33
  "#{t(campaign.status)}, " << [ status, metrics ].map { |str| strip_tags(str) }.join(' ').gsub("\n", '')
34
34
  end
35
35
  end
36
-
@@ -53,16 +53,6 @@ module LeadsHelper
53
53
  end
54
54
  end
55
55
 
56
- # Returns default permissions intro for leads.
57
- #----------------------------------------------------------------------------
58
- def get_lead_default_permissions_intro(access)
59
- case access
60
- when "Private" then t(:lead_permissions_intro_private, t(:opportunity_small))
61
- when "Public" then t(:lead_permissions_intro_public, t(:opportunity_small))
62
- when "Shared" then t(:lead_permissions_intro_shared, t(:opportunity_small))
63
- end
64
- end
65
-
66
56
  # Do not offer :converted status choice if we are creating a new lead or
67
57
  # editing existing lead that hasn't been converted before.
68
58
  #----------------------------------------------------------------------------
@@ -93,4 +83,3 @@ module LeadsHelper
93
83
  summary.join(', ')
94
84
  end
95
85
  end
96
-
@@ -31,4 +31,3 @@ module OpportunitiesHelper
31
31
  summary.compact.join(', ')
32
32
  end
33
33
  end
34
-
@@ -28,12 +28,4 @@ module TagsHelper
28
28
  end.html_safe
29
29
  end
30
30
 
31
- # Generate tag links for the asset landing page (shown on a sidebar).
32
- #----------------------------------------------------------------------------
33
- def tags_for_show(model)
34
- model.tag_list.inject([]) do |arr, tag|
35
- arr << link_to(tag, url_for(:action => "tagged", :id => tag), :title => tag)
36
- end.join(" ").html_safe
37
- end
38
-
39
31
  end
@@ -8,7 +8,7 @@ module VersionsHelper
8
8
  # Parse the changes for each version
9
9
  #----------------------------------------------------------------------------
10
10
  def parse_version(attr_name, change)
11
- if attr_name =~ /^cf_/ and (field = CustomField.where(:name => attr_name).first).present?
11
+ if attr_name =~ /\Acf_/ and (field = CustomField.where(:name => attr_name).first).present?
12
12
  label = field.label
13
13
  first = field.render(change.first)
14
14
  second = field.render(change.second)
@@ -21,7 +21,7 @@ class AccountContact < ActiveRecord::Base
21
21
 
22
22
  has_paper_trail :meta => { :related => :contact }, :ignore => [ :id, :created_at, :updated_at, :contact_id ]
23
23
 
24
- validates :account_id, :presence => true
24
+ validates_presence_of :account_id, :contact_id
25
25
 
26
26
  ActiveSupport.run_load_hooks(:fat_free_crm_account_contact, self)
27
27
  end
@@ -32,7 +32,7 @@
32
32
  class Campaign < ActiveRecord::Base
33
33
  belongs_to :user
34
34
  belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to
35
- has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
35
+ has_many :tasks, :as => :asset, :dependent => :destroy
36
36
  has_many :leads, :dependent => :destroy, :order => "id DESC"
37
37
  has_many :opportunities, :dependent => :destroy, :order => "id DESC"
38
38
  has_many :emails, :as => :mediator
@@ -42,8 +42,8 @@ class Campaign < ActiveRecord::Base
42
42
  scope :state, ->(filters) {
43
43
  where('status IN (?)' + (filters.delete('other') ? ' OR status IS NULL' : ''), filters)
44
44
  }
45
- scope :created_by, ->(user) { where('user_id = ?' , user.id) }
46
- scope :assigned_to, ->(user) { where('assigned_to = ?', user.id) }
45
+ scope :created_by, ->(user) { where( user_id: user.id ) }
46
+ scope :assigned_to, ->(user) { where( assigned_to: user.id ) }
47
47
 
48
48
  scope :text_search, ->(query) { search('name_cont' => query).result }
49
49
 
@@ -45,7 +45,7 @@ class Contact < ActiveRecord::Base
45
45
  has_one :account, :through => :account_contact
46
46
  has_many :contact_opportunities, :dependent => :destroy
47
47
  has_many :opportunities, :through => :contact_opportunities, :uniq => true, :order => "opportunities.id DESC"
48
- has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
48
+ has_many :tasks, :as => :asset, :dependent => :destroy
49
49
  has_one :business_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type = 'Business'"
50
50
  has_many :addresses, :dependent => :destroy, :as => :addressable, :class_name => "Address" # advanced search uses this
51
51
  has_many :emails, :as => :mediator
@@ -59,8 +59,8 @@ class Contact < ActiveRecord::Base
59
59
 
60
60
  accepts_nested_attributes_for :business_address, :allow_destroy => true, :reject_if => proc {|attributes| Address.reject_address(attributes)}
61
61
 
62
- scope :created_by, ->(user) { where("user_id = ?", user.id) }
63
- scope :assigned_to, ->(user) { where("assigned_to = ?", user.id) }
62
+ scope :created_by, ->(user) { where( user_id: user.id ) }
63
+ scope :assigned_to, ->(user) { where( assigned_to: user.id ) }
64
64
 
65
65
  scope :text_search, ->(query) {
66
66
  t = Contact.arel_table
@@ -41,7 +41,7 @@ class Lead < ActiveRecord::Base
41
41
  belongs_to :campaign
42
42
  belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to
43
43
  has_one :contact, :dependent => :nullify # On destroy keep the contact, but nullify its lead_id
44
- has_many :tasks, :as => :asset, :dependent => :destroy#, :order => 'created_at DESC'
44
+ has_many :tasks, :as => :asset, :dependent => :destroy
45
45
  has_one :business_address, :dependent => :destroy, :as => :addressable, :class_name => "Address", :conditions => "address_type='Business'"
46
46
  has_many :addresses, :dependent => :destroy, :as => :addressable, :class_name => "Address" # advanced search uses this
47
47
  has_many :emails, :as => :mediator
@@ -53,10 +53,10 @@ class Lead < ActiveRecord::Base
53
53
  scope :state, ->(filters) {
54
54
  where([ 'status IN (?)' + (filters.delete('other') ? ' OR status IS NULL' : ''), filters ])
55
55
  }
56
- scope :converted, -> { where(:status => 'converted') }
57
- scope :for_campaign, ->(id) { where('campaign_id = ?', id) }
58
- scope :created_by, ->(user) { where('user_id = ?' , user.id) }
59
- scope :assigned_to, ->(user) { where('assigned_to = ?' , user.id) }
56
+ scope :converted, -> { where( status: 'converted' ) }
57
+ scope :for_campaign, ->(id) { where( campaign_id: id ) }
58
+ scope :created_by, ->(user) { where( user_id: user.id ) }
59
+ scope :assigned_to, ->(user) { where( assigned_to: user.id ) }
60
60
 
61
61
  scope :text_search, ->(query) { search('first_name_or_last_name_or_company_or_email_cont' => query).result }
62
62
 
@@ -51,9 +51,7 @@ class Opportunity < ActiveRecord::Base
51
51
 
52
52
  # Search by name OR id
53
53
  scope :text_search, ->(query) {
54
- # postgresql does not like to compare string to integer field
55
- if query =~ /^\d+$/
56
- query = query.gsub(/[^\w\s\-\.'\p{L}]/u, '').strip
54
+ if query =~ /\A\d+\z/
57
55
  where('upper(name) LIKE upper(:name) OR opportunities.id = :id', :name => "%#{query}%", :id => query)
58
56
  else
59
57
  search('name_cont' => query).result
@@ -46,6 +46,7 @@ class FieldGroup < ActiveRecord::Base
46
46
  end
47
47
 
48
48
  private
49
+
49
50
  # Can't delete default field group
50
51
  def not_default_field_group
51
52
  name != "custom_fields"
data/app/models/list.rb CHANGED
@@ -9,7 +9,8 @@ class List < ActiveRecord::Base
9
9
 
10
10
  # Parses the controller from the url
11
11
  def controller
12
- (url || "").sub(/^\//,'').split(/\/|\?/).first
12
+ (url || "").sub(/\A\//,'').split(/\/|\?/).first
13
13
  end
14
+
14
15
  ActiveSupport.run_load_hooks(:fat_free_crm_list, self)
15
16
  end
@@ -45,7 +45,7 @@ class Avatar < ActiveRecord::Base
45
45
  if options[:width] && options[:height]
46
46
  options[:size] = [:width, :height].map{|d| options[d]}.join("x")
47
47
  elsif Avatar::STYLES.keys.include?(options[:size])
48
- options[:size] = Avatar::STYLES[options[:size]].sub(/\#$/,'')
48
+ options[:size] = Avatar::STYLES[options[:size]].sub(/\#\z/,'')
49
49
  end
50
50
  options
51
51
  end
@@ -27,6 +27,7 @@
27
27
 
28
28
  class Task < ActiveRecord::Base
29
29
  attr_accessor :calendar
30
+ ALLOWED_VIEWS = %w(pending assigned completed)
30
31
 
31
32
  belongs_to :user
32
33
  belongs_to :assignee, :class_name => "User", :foreign_key => :assigned_to
@@ -46,8 +47,8 @@ class Task < ActiveRecord::Base
46
47
  limit(options[:limit]) # nil selects all records
47
48
  }
48
49
 
49
- scope :created_by, ->(user) { where(:user_id => user.id) }
50
- scope :assigned_to, ->(user) { where(:assigned_to => user.id) }
50
+ scope :created_by, ->(user) { where( user_id: user.id ) }
51
+ scope :assigned_to, ->(user) { where( assigned_to: user.id ) }
51
52
 
52
53
  # Tasks assigned by the user to others. That's what we see on Tasks/Assigned.
53
54
  scope :assigned_by, ->(user) {
@@ -62,8 +63,8 @@ class Task < ActiveRecord::Base
62
63
  where('user_id = ? OR assigned_to = ?', user.id, user.id)
63
64
  }
64
65
 
66
+ # Show opportunities which either belong to the user and are unassigned, or are assigned to the user
65
67
  scope :visible_on_dashboard, ->(user) {
66
- # Show opportunities which either belong to the user and are unassigned, or are assigned to the user
67
68
  where('(user_id = :user_id AND assigned_to IS NULL) OR assigned_to = :user_id', :user_id => user.id).where('completed_at IS NULL')
68
69
  }
69
70
 
@@ -171,6 +172,7 @@ class Task < ActiveRecord::Base
171
172
  # Returns list of tasks grouping them by due date as required by tasks/index.
172
173
  #----------------------------------------------------------------------------
173
174
  def self.find_all_grouped(user, view)
175
+ return {} unless ALLOWED_VIEWS.include?(view)
174
176
  settings = (view == "completed" ? Setting.task_completed : Setting.task_bucket)
175
177
  Hash[
176
178
  settings.map do |key, value|
@@ -182,7 +184,7 @@ class Task < ActiveRecord::Base
182
184
  # Returns bucket if it's empty (i.e. we have to hide it), nil otherwise.
183
185
  #----------------------------------------------------------------------------
184
186
  def self.bucket_empty?(bucket, user, view = "pending")
185
- return false if bucket.blank?
187
+ return false if bucket.blank? or !ALLOWED_VIEWS.include?(view)
186
188
  if view == "assigned"
187
189
  assigned_by(user).send(bucket).pending.count
188
190
  else
@@ -193,6 +195,7 @@ class Task < ActiveRecord::Base
193
195
  # Returns task totals for each of the views as needed by tasks sidebar.
194
196
  #----------------------------------------------------------------------------
195
197
  def self.totals(user, view = "pending")
198
+ return {} unless ALLOWED_VIEWS.include?(view)
196
199
  settings = (view == "completed" ? Setting.task_completed : Setting.task_bucket)
197
200
  settings.inject({ :all => 0 }) do |hash, key|
198
201
  hash[key] = (view == "assigned" ? assigned_by(user).send(key).pending.count : my(user).send(key).send(view).count)
@@ -71,7 +71,6 @@ class Setting < ActiveRecord::Base
71
71
  end
72
72
  end
73
73
 
74
-
75
74
  # Set setting value
76
75
  #-------------------------------------------------------------------
77
76
  def []=(name, value)
@@ -82,7 +81,6 @@ class Setting < ActiveRecord::Base
82
81
  cache[name] = value
83
82
  end
84
83
 
85
-
86
84
  # Unrolls [ :one, :two ] settings array into [[ "One", :one ], [ "Two", :two ]]
87
85
  # picking symbol translations from locale. If setting is not a symbol but
88
86
  # string it gets copied without translation.
@@ -98,7 +96,6 @@ class Setting < ActiveRecord::Base
98
96
  table_exists? rescue false
99
97
  end
100
98
 
101
-
102
99
  # Loads settings from YAML files
103
100
  def load_settings_from_yaml(file)
104
101
  settings = YAML.load_file(file)
@@ -9,11 +9,22 @@ class Ability
9
9
  include CanCan::Ability
10
10
 
11
11
  def initialize(user)
12
+
13
+ # handle signup
14
+ can(:create, User) if User.can_signup?
15
+
12
16
  if user.present?
13
17
  entities = [Account, Campaign, Contact, Lead, Opportunity]
14
18
 
15
- can :create, :all
16
- can :read, [User] # for search autocomplete
19
+ # User
20
+ can :manage, User, id: user.id # can do any action on themselves
21
+
22
+ # Tasks
23
+ can :create, Task
24
+ can :manage, Task, user: user.id
25
+ can :manage, Task, assigned_to: user.id
26
+
27
+ # Entities
17
28
  can :manage, entities, :access => 'Public'
18
29
  can :manage, entities + [Task], :user_id => user.id
19
30
  can :manage, entities + [Task], :assigned_to => user.id
@@ -61,7 +61,6 @@ class User < ActiveRecord::Base
61
61
 
62
62
  has_paper_trail :ignore => [:last_request_at, :perishable_token]
63
63
 
64
- # For some reason this does not play nice with has_paper_trail when set as default scope
65
64
  scope :by_id, -> { order('id DESC') }
66
65
  scope :except, ->(user) { where('id != ?', user.id).by_name }
67
66
  scope :by_name, -> { order('first_name, last_name, email') }
@@ -188,6 +187,10 @@ class User < ActiveRecord::Base
188
187
  Ability.new(User.current_user)
189
188
  end
190
189
 
190
+ def can_signup?
191
+ [ :allowed, :needs_approval ].include? Setting.user_signup
192
+ end
193
+
191
194
  end
192
195
 
193
196
  ActiveSupport.run_load_hooks(:fat_free_crm_user, self)
@@ -44,7 +44,3 @@
44
44
 
45
45
 
46
46
  #export= render "shared/export"
47
- /
48
- Check out HTML source to view the output of the hook if you have sample plugin installed
49
- http://github.com/michaeldv/crm_sample_plugin/tree/master
50
- = hook(:home_view, self, :hello => "world!", :welcome => "home")
@@ -21,13 +21,15 @@
21
21
 
22
22
  :javascript
23
23
  crm.language = "#{I18n.locale}"
24
- #{yield :javascript}
25
- var _ffcrm_users = [
26
- #{User.all.map{|u| "\"#{u.full_name} (@#{u.username})\"" }.join(",\n")}
27
- ];
28
-
29
24
  window.controller = "#{controller.controller_name}"
30
25
 
26
+ - if current_user.present?
27
+ :javascript
28
+ #{yield :javascript}
29
+ var _ffcrm_users = [
30
+ #{User.all.map{|u| "\"#{u.full_name} (@#{u.username})\"" }.join(",\n")}
31
+ ];
32
+
31
33
  <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
32
34
  <link rel="icon" href="/favicon.ico" type="image/x-icon">
33
35
 
@@ -33,6 +33,3 @@
33
33
  .check_box
34
34
  = f.check_box :do_not_call, {}, true
35
35
  #{t :do_not_call}
36
-
37
-
38
-
@@ -8,8 +8,8 @@
8
8
  - else
9
9
  - @personal_lists.sort.each_with_index do |list, i|
10
10
  %li[list]{ :class => i < @personal_lists.size - 1 ? "" : "last" }
11
- %dt= link_to(truncate(list.name, :length => 25), list.url, :title => list.name)
12
- %tt
11
+ %dt= link_to(truncate(list.name, :length => 25), h(list.url), :title => list.name)
12
+ %tt
13
13
  = link_to(url_for(list), :method => :delete, :confirm => 'Are you sure?', :remote => true, :class => "list_icon delete_on_hover") do
14
14
  %i.fa{:"data-controller" => list.controller, class: get_icon(list.controller)}
15
15
 
@@ -8,8 +8,8 @@
8
8
  - else
9
9
  - @global_lists.sort.each_with_index do |list, i|
10
10
  %li[list]{ :class => i < @global_lists.size - 1 ? "" : "last" }
11
- %dt= link_to(truncate(list.name, :length => 25), list.url, :title => list.name)
12
- %tt
11
+ %dt= link_to(truncate(list.name, :length => 25), h(list.url), :title => list.name)
12
+ %tt
13
13
  = link_to(url_for(list), :method => :delete, :confirm => 'Are you sure?', :remote => true, :class => "list_icon delete_on_hover") do
14
14
  %i.fa{:"data-controller" => list.controller, class: get_icon(list.controller)}
15
15
 
@@ -28,7 +28,7 @@ module FatFreeCRM
28
28
  config.autoload_paths += Dir[Rails.root.join("app/models/**")] +
29
29
  Dir[Rails.root.join("app/controllers/entities")]
30
30
 
31
- # Prevent Field class from being reloading more than once as this clears registered customfields
31
+ # Prevent Field class from being reloaded more than once as this clears registered customfields
32
32
  config.autoload_once_paths += [File.expand_path("../app/models/fields/field.rb", __FILE__)]
33
33
 
34
34
  # Activate observers that should always be running.
@@ -62,7 +62,7 @@ module FatFreeCRM
62
62
  config.encoding = "utf-8"
63
63
 
64
64
  # Configure sensitive parameters which will be filtered from the log file.
65
- config.filter_parameters += [:password]
65
+ config.filter_parameters += [:password, :password_hash, :password_salt, :password_confirmation]
66
66
 
67
67
  # Use SQL instead of Active Record's schema dumper when creating the database.
68
68
  # This is necessary if your schema can't be completely dumped by the schema dumper,
@@ -19,6 +19,8 @@ if defined?(FatFreeCRM::Application)
19
19
  config.consider_all_requests_local = true
20
20
  config.action_controller.perform_caching = false
21
21
 
22
+ config.action_mailer.delivery_method = :file
23
+
22
24
  # Don't care if the mailer can't send
23
25
  config.action_mailer.raise_delivery_errors = true
24
26
 
@@ -10,9 +10,8 @@ if defined?(FatFreeCRM::Application)
10
10
  # Code is not reloaded between requests
11
11
  config.cache_classes = true
12
12
 
13
- # Full error reports are enabled, since this is an internal application.
14
- config.consider_all_requests_local = true
15
- # Caching is turned on
13
+ # Full error reports are disabled and caching is turned on.
14
+ config.consider_all_requests_local = false
16
15
  config.action_controller.perform_caching = true
17
16
 
18
17
  # Disable Rails's static asset server (Apache or nginx will already do this)
@@ -1 +1,25 @@
1
- FatFreeCRM::Application.config.secret_token = 'be17625f6b1d92df0ed33a3ea57905ed321ef6089c213f23b2dff44a9b236d836b854451068ae030741b182d29ac25c5dbd075c993cabfd624d825e66e073071'
1
+ # Copyright (c) 2008-2013 Michael Dvorkin and contributors.
2
+ #
3
+ # Fat Free CRM is freely distributable under the terms of MIT license.
4
+ # See MIT-LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+
7
+ # Be sure to restart your server when you modify this file.
8
+
9
+ # Your secret key is used for verifying the integrity of signed cookies.
10
+ # If you change this key, all old signed cookies will become invalid!
11
+
12
+ # Make sure the secret is at least 30 characters and all random,
13
+ # no regular words or you'll be exposed to dictionary attacks.
14
+ # You can use `rake secret` to generate a secure secret key.
15
+
16
+ # Make sure your secret_key_base is kept private
17
+ # if you're sharing your code publicly.
18
+
19
+ #
20
+ # We should setup a secret token if FFCRM is running in application mode but NOT in engine mode.
21
+ # This functionality has been extracted to lib so it can be tested.
22
+ if FatFreeCRM.application?
23
+ require 'fat_free_crm/secret_token_generator'
24
+ FatFreeCRM::SecretTokenGenerator.setup!
25
+ end