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.
- checksums.yaml +4 -4
- data/Capfile +1 -4
- data/Gemfile.lock +0 -1
- data/README.md +1 -0
- data/app/assets/javascripts/lists.js.coffee +1 -2
- data/app/controllers/application_controller.rb +27 -25
- data/app/controllers/emails_controller.rb +1 -30
- data/app/controllers/entities/contacts_controller.rb +1 -1
- data/app/controllers/entities/opportunities_controller.rb +1 -1
- data/app/controllers/entities_controller.rb +0 -1
- data/app/controllers/home_controller.rb +0 -4
- data/app/controllers/passwords_controller.rb +3 -3
- data/app/controllers/tasks_controller.rb +17 -10
- data/app/controllers/users_controller.rb +23 -46
- data/app/helpers/application_helper.rb +0 -3
- data/app/helpers/campaigns_helper.rb +0 -1
- data/app/helpers/leads_helper.rb +0 -11
- data/app/helpers/opportunities_helper.rb +0 -1
- data/app/helpers/tags_helper.rb +0 -8
- data/app/helpers/versions_helper.rb +1 -1
- data/app/models/entities/account_contact.rb +1 -1
- data/app/models/entities/campaign.rb +3 -3
- data/app/models/entities/contact.rb +3 -3
- data/app/models/entities/lead.rb +5 -5
- data/app/models/entities/opportunity.rb +1 -3
- data/app/models/fields/field_group.rb +1 -0
- data/app/models/list.rb +2 -1
- data/app/models/polymorphic/avatar.rb +1 -1
- data/app/models/polymorphic/task.rb +7 -4
- data/app/models/setting.rb +0 -3
- data/app/models/users/ability.rb +13 -2
- data/app/models/users/user.rb +4 -1
- data/app/views/home/index.html.haml +0 -4
- data/app/views/layouts/application.html.haml +7 -5
- data/app/views/leads/_contact.html.haml +0 -3
- data/app/views/lists/_personal_sidebar.html.haml +2 -2
- data/app/views/lists/_sidebar.html.haml +2 -2
- data/config/application.rb +2 -2
- data/config/environments/development.rb +2 -0
- data/config/environments/production.rb +2 -3
- data/config/initializers/secret_token.rb +25 -1
- data/config/locales/en-US_fat_free_crm.yml +1 -1
- data/config/routes.rb +27 -32
- data/config/settings.default.yml +3 -4
- data/lib/development_tasks/rspec.rake +1 -5
- data/lib/fat_free_crm.rb +11 -1
- data/lib/fat_free_crm/fields.rb +1 -1
- data/lib/fat_free_crm/gem_ext/rails/text_helper.rb +1 -2
- data/lib/fat_free_crm/secret_token_generator.rb +59 -0
- data/lib/fat_free_crm/version.rb +1 -1
- data/spec/controllers/admin/users_controller_spec.rb +1 -3
- data/spec/controllers/home_controller_spec.rb +0 -7
- data/spec/controllers/passwords_controller_spec.rb +23 -5
- data/spec/controllers/users_controller_spec.rb +45 -17
- data/spec/lib/secret_token_generator_spec.rb +55 -0
- data/spec/models/users/abilities/user_ability_spec.rb +58 -0
- data/spec/routing/emails_routing_spec.rb +13 -14
- data/spec/spec_helper.rb +2 -1
- 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
|
data/app/helpers/leads_helper.rb
CHANGED
@@ -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
|
-
|
data/app/helpers/tags_helper.rb
CHANGED
@@ -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 =~
|
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
|
-
|
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
|
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(
|
46
|
-
scope :assigned_to, ->(user) { where(
|
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
|
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(
|
63
|
-
scope :assigned_to, ->(user) { where(
|
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
|
data/app/models/entities/lead.rb
CHANGED
@@ -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
|
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,
|
57
|
-
scope :for_campaign, ->(id)
|
58
|
-
scope :created_by,
|
59
|
-
scope :assigned_to,
|
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
|
-
|
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
|
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(
|
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(:
|
50
|
-
scope :assigned_to, ->(user) { where(:
|
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)
|
data/app/models/setting.rb
CHANGED
@@ -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)
|
data/app/models/users/ability.rb
CHANGED
@@ -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
|
-
|
16
|
-
can :
|
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
|
data/app/models/users/user.rb
CHANGED
@@ -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
|
|
@@ -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
|
|
data/config/application.rb
CHANGED
@@ -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
|
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
|
14
|
-
config.consider_all_requests_local =
|
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
|
-
|
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
|