web47core 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 623ae80309063bdc6c27dee1668a86ae4473da7db27a6ffedb9bd75df3b83d40
4
- data.tar.gz: e39e28438fb5247ddb2cc65c9dd3b5c8edb8a98d9079921b3dc07d511b587ecb
3
+ metadata.gz: 97cb8fc1a923a3c6a911a319404529ef67ad9de4d1f20d6c90b088f99d8e366a
4
+ data.tar.gz: 53ce4e9da8a4279b4bc4eb3ffb7a0f58b9ec1844c6f1f42adeed9d3e572f3f7e
5
5
  SHA512:
6
- metadata.gz: db0cd4d93d34398cf6e3a4739016db9fd63337e048917403ea9ec624ee5f516ecdb8a9ac278925f8f329dde34c3a42af16b856530ae976c5cc9534eca0999143
7
- data.tar.gz: b5304422a552e6ec81a9e188000533a8a4652e66d3e6e8096b81abaf45d5e4646cc5ed5b7591265c5639f56225e977ba26cb68351eda9e1c20743d70b81b3580
6
+ metadata.gz: e3598aefea3e3b1411e4e4c60c1096129ba90fc5d33ae2c0907762d223ce234f3a4c56e50d28b2dc218a82544a51e9003bc20e0bf4f68bff70d0e767667887ad
7
+ data.tar.gz: 773f67eac21317c9da0c286c1071383f864b42f4a1d36dcef624bf3968dedf40d96452f9a3eb252057fb805dd6ce66c4302746e72838a4fcd856d30c23e95563
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- web47core (0.0.9)
4
+ web47core (0.0.10)
5
5
  activesupport (~> 5.0)
6
6
  aws-sdk-ec2 (> 1.140, <= 1.160)
7
7
  delayed_job_mongoid (~> 2.3)
8
+ email_format
8
9
  haml
9
10
  jwt
10
11
  liquid
@@ -13,6 +14,8 @@ PATH
13
14
  redis (~> 4.1)
14
15
  redis-rails (> 5, < 6)
15
16
  rest-client (>= 0, <= 2.1.0)
17
+ twilio-ruby (>= 3.0, <= 4.13)
18
+ tzinfo
16
19
 
17
20
  GEM
18
21
  remote: https://rubygems.org/
@@ -63,7 +66,7 @@ GEM
63
66
  ansi (1.5.0)
64
67
  arel (9.0.0)
65
68
  aws-eventstream (1.0.3)
66
- aws-partitions (1.288.0)
69
+ aws-partitions (1.289.0)
67
70
  aws-sdk-core (3.92.0)
68
71
  aws-eventstream (~> 1.0, >= 1.0.2)
69
72
  aws-partitions (~> 1, >= 1.239.0)
@@ -99,6 +102,10 @@ GEM
99
102
  docile (1.3.2)
100
103
  domain_name (0.5.20190701)
101
104
  unf (>= 0.0.5, < 1.0.0)
105
+ email_format (1.0.0)
106
+ activemodel
107
+ email_regex
108
+ email_regex (0.0.1)
102
109
  erubi (1.9.0)
103
110
  factory_bot (5.1.1)
104
111
  activesupport (>= 4.2.0)
@@ -119,7 +126,7 @@ GEM
119
126
  concurrent-ruby (~> 1.0)
120
127
  jmespath (1.4.0)
121
128
  json (2.3.0)
122
- jwt (2.2.1)
129
+ jwt (1.5.6)
123
130
  liquid (4.0.3)
124
131
  listen (3.2.1)
125
132
  rb-fsevent (~> 0.10, >= 0.10.3)
@@ -167,6 +174,7 @@ GEM
167
174
  mongoid-compatibility (0.5.1)
168
175
  activesupport
169
176
  mongoid (>= 2.0)
177
+ multi_json (1.14.1)
170
178
  netrc (0.11.0)
171
179
  nio4r (2.5.2)
172
180
  nokogiri (1.10.9)
@@ -252,6 +260,10 @@ GEM
252
260
  thor (1.0.1)
253
261
  thread_safe (0.3.6)
254
262
  tilt (2.0.10)
263
+ twilio-ruby (4.13.0)
264
+ builder (>= 2.1.2)
265
+ jwt (~> 1.0)
266
+ multi_json (>= 1.3.0)
255
267
  tzinfo (1.2.6)
256
268
  thread_safe (~> 0.1)
257
269
  unf (0.1.4)
@@ -284,7 +296,7 @@ DEPENDENCIES
284
296
  minitest-reporters
285
297
  mocha
286
298
  shoulda (= 3.6.0)
287
- shoulda-matchers (= 3.1.2)
299
+ shoulda-matchers
288
300
  simplecov (= 0.16.1)
289
301
  test-unit
290
302
  vcr
data/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # web47core
2
2
  Core components used commonly among all web apps for both App47 and RedMonocle
3
3
 
4
+ ## We don't need no sticking badges
5
+
6
+ * [![Codacy Badge](https://api.codacy.com/project/badge/Grade/acc591f31c214849959f71e210e7edbd)](https://www.codacy.com?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=App47/web47core&amp;utm_campaign=Badge_Grade)
7
+ * [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/acc591f31c214849959f71e210e7edbd)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=App47/web47core&utm_campaign=Badge_Coverage)
8
+
4
9
  ## Requirements
5
10
 
6
11
  * Ruby 2.4.1
@@ -27,62 +32,62 @@ bundle install --path vendor
27
32
  ```
28
33
  The `--path vendor` simply puts all gem files in a `vendor` directory.
29
34
 
30
- # Development
35
+ ## Development
31
36
 
32
37
  Your `RubyMine` environment should be setup now, however to verify all is well, please run the test suite
33
38
  ```
34
39
  bundle exec rake test
35
40
  ```
36
41
 
37
- # Deployment
42
+ ## Deployment
38
43
  The `web47core` project is a gem that will be deployed via [Ruby Gems](https://rubygems.org). When an update is ready, the following steps should be followed
39
44
 
40
- 1. Build the gem `gem build web47core.gemspec`
41
- 1. Push the new gem to [Ruby Gems](https://rubygems.org) `gem push web47core-<<version>>.gem`
42
- 1. There may be a delay when using the gem file
45
+ 1. Build the gem `gem build web47core.gemspec`
46
+ 2. Push the new gem to [Ruby Gems](https://rubygems.org) `gem push web47core-version.gem`
47
+ 3. There may be a delay when using the gem file
43
48
 
44
- # Usage
45
- ## Importing the gem
49
+ ## Usage
50
+ ### Importing the gem
46
51
  To use the `app47core` gem in a project, first add the gem to your Gemfile in one of two ways
47
52
 
48
53
  Using the gem from [Ruby Gems](https://rubygems.org)
49
- ```
54
+ ```rbenv-gemsets
50
55
  gem 'web47core'
51
56
  ```
52
57
 
53
58
  If you need the gem immediately or need to pull from development branch, you can use the git repo
54
- ```
59
+ ```rbenv-gemsets
55
60
  gem 'web47core', git: 'git@github.com:App47/web47core.git', branch: :master
56
61
  ```
57
62
  or from the develop branch
58
- ```
63
+ ```rbenv-gemsets
59
64
  gem 'web47core', git: 'git@github.com:App47/web47core.git', branch: :develop
60
65
  ```
61
66
 
62
67
  _Please do not ship to production code using the git repo, as the production servers will not have keys to pull from the web47core repo_
63
68
 
64
- ## Remove the following files
65
- 1. `StandardModel` - Includes the common set of includes, Mongoid, Auditable, AutoClearCache, etc.
66
- 1. `CdnUrl` - Provide CDN URLs of your classes URLs when cdn_url is configured in system configuration
67
- 1. `AutoClearCache` - Clears your objects cache out of Rails.cache using the object's id
68
- 1. `Formable` - Consolidated into StandardModel, was used to provide common form operations for mongoid documents
69
- 1. `EmailNotification`
70
- 1. `EmailTemplate`
71
- 1. `Notification`
72
- 1. `NotificationTemplate`
73
- 1. `SlackNotification`
74
- 1. `SmsNotification`
75
- 1. `Template`
76
-
77
- ### Models
78
- #### Concerns
79
- 1. `StandardModel` - Includes the common set of includes, Mongoid, etc.
80
- 1. `CoreSystemConfiguration` - Base system configuration to be included in the app's SystemConfiguration Object
81
- 1. `CoreAccount` - Base account object that is related to notifications and the ilk.
82
- #### System Configuration
69
+ ### Remove the following files
70
+ 1. `StandardModel` - Includes the common set of includes, Mongoid, Auditable, AutoClearCache, etc.
71
+ 2. `CdnUrl` - Provide CDN URLs of your classes URLs when cdn_url is configured in system configuration
72
+ 3. `AutoClearCache` - Clears your objects cache out of Rails.cache using the object's id
73
+ 4. `Formable` - Consolidated into StandardModel, was used to provide common form operations for mongoid documents
74
+ 5. `EmailNotification`
75
+ 6. `EmailTemplate`
76
+ 7. `Notification`
77
+ 8. `NotificationTemplate`
78
+ 9. `SlackNotification`
79
+ 10. `SmsNotification`
80
+ 11. `Template`
81
+
82
+ #### Models
83
+ ##### Concerns
84
+ 1. `StandardModel` - Includes the common set of includes, Mongoid, etc.
85
+ 2. `CoreSystemConfiguration` - Base system configuration to be included in the app's SystemConfiguration Object
86
+ 3. `CoreAccount` - Base account object that is related to notifications and the ilk.
87
+ ##### System Configuration
83
88
  Define a `SystemConfiguration` class in your project and import the core concern.
84
89
 
85
- ```
90
+ ```ruby
86
91
  class SystemConfiguration
87
92
  include StandardModel
88
93
  include CoreSystemConfiguration
@@ -91,10 +96,10 @@ class SystemConfiguration
91
96
  field :google_sso_client_id, type: String
92
97
  end
93
98
  ```
94
- #### Account
99
+ ##### Account
95
100
  Define a `Account` class in your project and import the core concern.
96
101
 
97
- ```
102
+ ```ruby
98
103
  class Account
99
104
  include StandardModel
100
105
  include CoreAccount
@@ -103,4 +108,3 @@ class Account
103
108
  has_many :users
104
109
  end
105
110
  ```
106
-
@@ -0,0 +1,11 @@
1
+ en:
2
+ time:
3
+ formats:
4
+ long: '%Y-%m-%d %H:%M:%ss (%Z)'
5
+ medium: '%Y-%m-%d %H:%M (%Z)'
6
+ short: '%m/%d/%Y'
7
+ date:
8
+ formats:
9
+ long: '%B %d, %Y'
10
+ medium: '%b %d, %Y'
11
+ short: '%m/%d/%Y'
@@ -63,7 +63,7 @@ module App47Logger
63
63
 
64
64
  max_frame = -1 if ENV['RACK_ENV'].eql?('test')
65
65
  log_message(level, exception.message)
66
- exception.backtrace[0..max_frame].each { |frame| log_message(level, frame) } unless exception.backtrace.blank?
66
+ exception.backtrace[0..max_frame].each { |frame| log_message(level, frame) } if exception.backtrace.present?
67
67
  end
68
68
 
69
69
  #
@@ -117,6 +117,10 @@ module CoreSystemConfiguration
117
117
  def respond_to?(method_name, _include_private = false)
118
118
  SystemConfiguration.fields.include?(method_name)
119
119
  end
120
+
121
+ def respond_to_missing?(method_name, _include_private = false)
122
+ SystemConfiguration.fields.include?(method_name)
123
+ end
120
124
  # rubocop:enable Style/MethodMissingSuper
121
125
  end
122
126
 
@@ -208,7 +212,7 @@ module CoreSystemConfiguration
208
212
  config = SystemConfiguration.configuration
209
213
  path = if config.zendesk_configured? && user.present?
210
214
  time_now = Time.now.to_i
211
- jti = "#{time_now}/#{rand(36 ** 64).to_s(36)}"
215
+ jti = "#{time_now}/#{rand(36**64).to_s(36)}"
212
216
  payload = { jwt: JWT.encode({ iat: time_now, # Seconds since epoch, determine when this token is stale
213
217
  jti: jti, # Unique token identifier, helps prevent replay attacks
214
218
  name: user.name,
@@ -0,0 +1,84 @@
1
+ #
2
+ # Objects that emails can be sent too...
3
+ #
4
+ module EmailAble
5
+ extend ActiveSupport::Concern
6
+ include App47Logger
7
+
8
+ def self.included(base)
9
+ base.class_eval do
10
+ field :email, type: String
11
+ field :email_bounced_at, type: Time
12
+ field :email_bounce_reason, type: String
13
+ field :unconfirmed_email, type: String
14
+ field :email_enabled, type: Boolean, default: true
15
+ #
16
+ # Validations
17
+ #
18
+ validates :email, presence: true, email_format: { strict: true }
19
+ #
20
+ # Callbacks
21
+ #
22
+ before_validation :downcase_email
23
+ end
24
+ end
25
+
26
+ #
27
+ # Support legacy apps with old name
28
+ #
29
+ def email_bounce_date(date = nil)
30
+ self.email_bounced_at = date if date.present?
31
+ email_bounced_at
32
+ end
33
+
34
+ #
35
+ # Is this a valid email to send to?
36
+ #
37
+ def valid_email?
38
+ email_enabled? && !email_bounced?
39
+ end
40
+
41
+ #
42
+ # Has the email bounced?
43
+ #
44
+ def email_bounced?
45
+ email_bounced_at.present?
46
+ end
47
+
48
+ #
49
+ # Set the email to a bounced status with the given reason
50
+ #
51
+ def bounced(reason)
52
+ set email_bounced_at: Time.now.utc, email_bounce_reason: reason
53
+ end
54
+
55
+ #
56
+ # Reset the bounced email
57
+ #
58
+ def reset_bounce_status
59
+ return unless SystemConfiguration.mailgun_configured? && email_bounced?
60
+
61
+ reset_url = "https://api.mailgun.net/v3/#{SystemConfiguration.smtp_domain}/bounces/#{CGI.escape(email)}"
62
+ RestClient.delete(reset_url, user: 'api', password: SystemConfiguration.mailgun_api_key)
63
+ rescue RestClient::Exception => error
64
+ log_error "Unable to reset email bounce status: #{inspect}", error
65
+ ensure
66
+ set email_bounced_at: nil, email_bounce_reason: nil
67
+ end
68
+
69
+ #
70
+ # Return the gravatar URL based on email address
71
+ #
72
+ def gravatar_url(size = '32', default = 'mm')
73
+ "https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(email)}?s=#{size}&d=#{default}"
74
+ end
75
+
76
+ private
77
+
78
+ #
79
+ # Make sure emails are always downcased
80
+ #
81
+ def downcase_email
82
+ self.email = email.strip.downcase if email.present?
83
+ end
84
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Public: Add search and sort text to an object
5
+ #
6
+ module SearchAble
7
+ extend ActiveSupport::Concern
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ #
12
+ # Fields
13
+ #
14
+ field :search_text, type: String
15
+ field :sort_text, type: String
16
+ #
17
+ # Call backs
18
+ #
19
+ before_validation :update_search_and_sort_text
20
+ end
21
+ end
22
+
23
+ #
24
+ # Public: Add to class methods a way to search for records with matching
25
+ # search text.
26
+ #
27
+ # Examples
28
+ #
29
+ # Model.matching_search_text('some text')
30
+ # # => <Mongoid::critera>
31
+ #
32
+ module ClassMethods
33
+ def matching_search_text(search_text = nil)
34
+ (search_text.blank? ? all : where(search_text: /#{search_text.downcase}/)).order(sort_order)
35
+ end
36
+
37
+ def sort_order
38
+ new.sort_fields.collect { |field| [field, 1] }
39
+ end
40
+ end
41
+
42
+ #
43
+ # Internal: Update the search and sort text
44
+ #
45
+ # Call before validation to update, changes are persisted with the object.
46
+ #
47
+ def update_search_and_sort_text
48
+ return if destroyed?
49
+
50
+ update_text(search_fields, :search_text)
51
+ update_text(sort_fields, :sort_text)
52
+ end
53
+
54
+ #
55
+ # Internal: Update the search text
56
+ #
57
+ # Examples
58
+ #
59
+ # update_search_text
60
+ #
61
+ def update_text(fields, field_to_update)
62
+ items = fields.reject { |field| send(field.to_sym).blank? }.collect do |field|
63
+ value = send(field.to_sym)
64
+ if value.is_a? String
65
+ value.downcase
66
+ elsif value.is_a? Array
67
+ value.empty? ? nil : value.join(' ').downcase
68
+ end
69
+ end
70
+ send "#{field_to_update}=", items.compact.join(' ')
71
+ end
72
+
73
+ #
74
+ # Internal: Which fields to add to search text
75
+ #
76
+ # Examples
77
+ #
78
+ # search_fields
79
+ # # => ['name', 'email', 'code']
80
+ #
81
+ # Return which fields should be added to search
82
+ #
83
+ def search_fields
84
+ %w[name]
85
+ end
86
+
87
+ #
88
+ # Internal: Which fields to add to sort on
89
+ #
90
+ # Examples
91
+ #
92
+ # sort_fields
93
+ # # => ['name', 'email']
94
+ #
95
+ # Return which fields should be added to sort
96
+ #
97
+ def sort_fields
98
+ search_fields
99
+ end
100
+ end
@@ -101,7 +101,7 @@ module StandardModel
101
101
  super(remove_blank_secure_fields(params))
102
102
  end
103
103
 
104
- alias :update_attributes :update
104
+ alias update_attributes update
105
105
 
106
106
  #
107
107
  # Remove updates for secure fields that come across as blank to start with and get removed on update
@@ -110,7 +110,7 @@ module StandardModel
110
110
  super(remove_blank_secure_fields(params))
111
111
  end
112
112
 
113
- alias :update_attributes! :update!
113
+ alias update_attributes! update!
114
114
 
115
115
  #
116
116
  # List of secure fields, to add fields in concrete class, simply override this method