web47core 2.2.20 → 2.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f9305a37f231981bf61fa093709aa13bfda35fde37df2cdee660f6ba219ca46
4
- data.tar.gz: 48757e73cfdc337e0c5bf3480401161bf2983e56270a1fd31341ee33000f653b
3
+ metadata.gz: 7147715aefdef70511603bf5ddb8afa017da40ef51c54d4c14e10edd7c15d21d
4
+ data.tar.gz: 0fca6d931d158a0900121ed7f22983fc13322375fc1e3acccd18fd2062a2cdfe
5
5
  SHA512:
6
- metadata.gz: 1a03cfb814a6ad378787599aeace957ebf0b8c35777e156e157a3ad4a6e6d86149dca91d24b1efa4cf380007d3fb953d55df202f490490240c7ab51bfab53a66
7
- data.tar.gz: 307bb6fbc9d022e56cf06e0dd3fa2ace89403c281107c3aa1f0f294896f799f8ca59974dc2aecc8641eecd0fa5872f53893a5f23f48491244675db578e132288
6
+ metadata.gz: 05d7ded51da1a605dadd22666a988a2cd77dea9c320a187fa57ab7259d345a1f9910fdf31d674b8b0dac511895f721313e3ef068e0be9b7ae745b37b426fb122
7
+ data.tar.gz: ffc6a842ae0142f3cd4c0ba63813e4fb685a21208a84aba45a79dd5fe9b65507f6318ffdb6b74a81d28fdca8b06cccde584df7fea7fa1cd647b776e4a84654a8
@@ -17,12 +17,12 @@
17
17
  data: {confirm: t('confirm_destroy_all')}}
18
18
  %i.material-icons
19
19
  delete
20
- %a.btn.yellow.darken-3{href: class_action_path(:resubmit_all, failed_only:true),
20
+ %a.btn.yellow.darken-3{href: class_action_path(:resbumit_all, failed_only:true),
21
21
  title: t('.resubmit_failed'),
22
22
  data: {confirm: t('.confirm_resubmit_failed')}}
23
23
  %i.material-icons
24
24
  restore
25
- %a.btn.red{href: class_action_path(:resubmit_all, failed_only:false),
25
+ %a.btn.red{href: class_action_path(:resbumit_all, failed_only:false),
26
26
  title: t('.resubmit_all'),
27
27
  data: {confirm: t('.confirm_resubmit_all')}}
28
28
  %i.material-icons
@@ -40,7 +40,7 @@
40
40
  %tbody
41
41
  - @delayed_jobs.each do |delayed_job|
42
42
  %tr
43
- %td=current_user.local_time(delayed_job.run_at)
43
+ %td=current_user.local_time(delayed_job.created_at)
44
44
  %td.name=link_to(delayed_job.display_name, model_path(delayed_job))
45
45
  %td=delayed_job.priority
46
46
  %td=delayed_job.status_description
@@ -57,4 +57,4 @@
57
57
  .card-action
58
58
  .row
59
59
  .col.s6.center-align= delete_button_tag(@delayed_job, model_path(@delayed_job))
60
- .col.s6.center-align= replay_button_tag(@delayed_job, model_action_path(@delayed_job, :resubmit))
60
+ .col.s6.center-align= replay_button_tag(@delayed_job, model_path(@delayed_job))
@@ -46,7 +46,7 @@ module CoreDelayedJobsController
46
46
 
47
47
  job.resubmit
48
48
  end
49
- flash.now[:info] = 'All Delayed Jobs has been resubmitted'
49
+ flash.now[:info] = 'All DelayJobs has been resubmitted'
50
50
  redirect_to index_path
51
51
  rescue StandardError => error
52
52
  log_controller_error error, true
@@ -40,15 +40,18 @@ module AwsConfiguration
40
40
  aws_configured? && aws_auto_scaling_group_name.present?
41
41
  end
42
42
 
43
+ def aws_credentials
44
+ @aws_credentials ||= Aws::Credentials.new(aws_access_key_id,
45
+ aws_secret_access_key)
46
+ end
47
+
43
48
  #
44
49
  # AWS client.
45
50
  #
46
51
  def aws_ec2_client
47
52
  return nil unless aws_configured?
48
53
 
49
- @aws_ec2_client ||= Aws::EC2::Client.new(region: aws_region,
50
- credentials: Aws::Credentials.new(aws_access_key_id,
51
- aws_secret_access_key))
54
+ @aws_ec2_client ||= Aws::EC2::Client.new(region: aws_region, credentials: aws_credentials);
52
55
  end
53
56
 
54
57
  #
@@ -14,6 +14,11 @@
14
14
  #
15
15
  module CoreSystemConfiguration
16
16
  extend ActiveSupport::Concern
17
+ EMAIL_PROVIDER_SMTP_TYPE = 'smtp'.freeze unless defined? EMAIL_PROVIDER_SMTP_TYPE
18
+ EMAIL_PROVIDER_SES_TYPE = 'ses'.freeze unless defined? EMAIL_PROVIDER_SES_TYPE
19
+ unless defined? ALL_EMAIL_PROVIDER_TYPES
20
+ ALL_EMAIL_PROVIDER_TYPES = [EMAIL_PROVIDER_SMTP_TYPE, EMAIL_PROVIDER_SES_TYPE].freeze
21
+ end
17
22
 
18
23
  def self.included(base)
19
24
  base.class_eval do
@@ -30,6 +35,7 @@ module CoreSystemConfiguration
30
35
  field :short_cache, { type: Integer, default: 1 }
31
36
  field :medium_cache, { type: Integer, default: 5 }
32
37
  field :long_cache, { type: Integer, default: 15 }
38
+ field :stack_email_provider, type: String, default: EMAIL_PROVIDER_SMTP_TYPE
33
39
  # URLs
34
40
  field :base_url, type: String
35
41
  field :cdn_url, type: String
@@ -43,6 +49,7 @@ module CoreSystemConfiguration
43
49
  #
44
50
  validates :environment, presence: true, uniqueness: true
45
51
  validates :default_time_zone, presence: true
52
+ validates :stack_email_provider, inclusion: { in: ALL_EMAIL_PROVIDER_TYPES }
46
53
  end
47
54
  base.extend ClassMethods
48
55
  end
@@ -75,6 +82,14 @@ module CoreSystemConfiguration
75
82
  end
76
83
  end
77
84
 
85
+ def stack_ses_provider?
86
+ EMAIL_PROVIDER_SES_TYPE.eql?(stack_email_provider)
87
+ end
88
+
89
+ def stack_smtp_provider?
90
+ EMAIL_PROVIDER_SMTP_TYPE.eql?(stack_email_provider)
91
+ end
92
+
78
93
  #
79
94
  # Cache times in minutes
80
95
  #
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # AWS SES SSO Configuration
5
+ #
6
+ module SesConfiguration
7
+ extend ActiveSupport::Concern
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ #
12
+ # Fields
13
+ #
14
+ field :ses_source, type: String
15
+ field :ses_source_arn_prefix, type: String
16
+ field :ses_bounce_queue_name, type: String
17
+ field :ses_region, type: String
18
+ end
19
+ end
20
+
21
+ #
22
+ # Determine if AWS is configured
23
+ #
24
+ def ses_configured?
25
+ aws_configured? &&
26
+ ses_source.present? &&
27
+ ses_source_arn_prefix.present? &&
28
+ (ses_region.present? || aws_region.present?)
29
+ end
30
+
31
+ def ses_source_arn(source = ses_source)
32
+ [ses_source_arn_prefix, source].compact.join('/')
33
+ end
34
+
35
+ #
36
+ # SES Client
37
+ #
38
+ def aws_ses_client
39
+ return nil unless ses_configured?
40
+
41
+ # We want this to remake itself each time because it is possible that the
42
+ # => user would change the access keys in between actions. Huh?
43
+ @aws_ses_client ||= Aws::SES::Client.new(region: ses_region.presence || aws_region, credentials: aws_credentials)
44
+ end
45
+ end
@@ -36,60 +36,63 @@ class EmailNotification < Notification
36
36
  field :cc, type: String
37
37
  # The subject
38
38
  field :subject, type: String
39
+ field :message_id, type: String
39
40
  #
40
41
  # Validations
41
42
  #
42
43
  validates :subject, presence: true
43
44
  validates :to, presence: true
44
-
45
- # has_many :attachments, class_name: 'EmailNotificationAttachment', dependent: :destroy
45
+ # Callbacks
46
+ before_save :ensure_headers
46
47
 
47
48
  def from_template(template_name, locals = {})
48
49
  super
49
50
  self.subject = subject_from_template(template_name, locals)
50
51
  end
51
52
 
52
- #
53
- # Add a file as an attachment to this email notification.
54
- #
55
- # Expecting a path to the file, not the file or data itself.
56
- # TODO consider how to handle a file object or data object.
57
- #
58
- # Once you have called this method, the file is stored via PaperClip and
59
- # does not need to stay persistant through email delivery.
60
- # You can delete it after telling the EmailNotification to send
61
- # the notification.
62
- #
63
- # def add_file(file)
64
- # # Make sure we are saved
65
- # save! unless persisted?
66
- # attachment = EmailNotificationAttachment.new email_notification: self
67
- # attachment.file = open(file)
68
- # attachment.save!
69
- # end
70
53
  def deliver_message!
54
+ if account.present? && account.fetch_smtp_configuration.use?
55
+ deliver_smtp_message!
56
+ elsif SystemConfiguration.stack_smtp_provider?
57
+ deliver_smtp_message!
58
+ elsif SystemConfiguration.ses_configured?
59
+ deliver_ses_message!
60
+ else
61
+ fail "Invalid configuration in stack for sending emails"
62
+ end
63
+ end
64
+
65
+ def deliver_ses_message!
66
+ config = SystemConfiguration.configuration
67
+ client = config.aws_ses_client
68
+ payload = { destination: { to_addresses: [to] },
69
+ message: {
70
+ body: { html: { data: build_message } },
71
+ subject: { data: subject } },
72
+ source: from,
73
+ source_arn: config.ses_source_arn(from) }
74
+ payload[:reply_to_addresses] = [reply_to] if reply_to.present?
75
+ resp = client.send_email(payload)
76
+ self.message_id = resp[:message_id]
77
+ end
78
+
79
+ def deliver_smtp_message!
71
80
  mail = Mail.new
72
81
  # Set the from line
73
- address = from_address
74
- mail.from = address
75
- self.from = address
82
+ mail.from = from
76
83
  # Set the sender line
77
- address = sender_address
78
- mail.sender = address
79
- self.sender = address
84
+ mail.sender = sender
80
85
  # Set the reply to
81
- address = reply_to_address
82
- if address.present?
83
- self.reply_to = address
84
- mail.reply_to = address
85
- mail.sender = address
86
+ if reply_to_address.present?
87
+ mail.reply_to = reply_to_address
88
+ mail.sender = reply_to_address
86
89
  end
87
90
 
88
91
  # Set the to address
89
92
  mail.to = to
90
93
 
91
94
  # Set the cc line
92
- mail.cc = cc unless cc.nil?
95
+ mail.cc = cc if cc.present?
93
96
 
94
97
  # Set the subject line
95
98
  mail.subject = subject
@@ -101,9 +104,6 @@ class EmailNotification < Notification
101
104
  body html_message
102
105
  end
103
106
 
104
- # Add the attachments, if there are any. If not, none are added.
105
- add_attachments(attachments) if defined?(attachments)
106
-
107
107
  # Setup the delivery method for this message only.
108
108
  if 'test'.eql?(ENV['RAILS_ENV'])
109
109
  mail.delivery_method :test
@@ -121,19 +121,12 @@ class EmailNotification < Notification
121
121
  FileUtils.remove_entry_secure(tmp_dir) if defined?(tmp_dir) && tmp_dir.present?
122
122
  end
123
123
 
124
- def add_attachments(attachments = nil)
125
- tmp_dir = Dir.mktmpdir
126
- attachments.each do |attachment|
127
- # Create a temp directory, it'll get cleaned up in the rescue.
128
- tmp_file_path = "#{tmp_dir}/#{attachment.file_file_name}"
129
- File.open(tmp_file_path, 'w') do |f|
130
- f.write(URI.parse(attachment.file_url).open.read.force_encoding('utf-16').encode)
131
- end
132
- mail.attachments[attachment.file_file_name] = {
133
- mime_type: attachment.file_content_type,
134
- content: File.open(tmp_file_path).read.force_encoding('utf-16').encode
135
- }
136
- end
124
+ # @abstract Ensure the headers of the message are set regardless if we are using
125
+ # ses or smtp
126
+ def ensure_headers
127
+ self.from = from_address
128
+ self.sender = sender_address
129
+ self.reply_to = reply_to_address
137
130
  end
138
131
 
139
132
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Web47core
4
- VERSION = '2.2.20'
4
+ VERSION = '2.3.0'
5
5
  end
data/lib/web47core.rb CHANGED
@@ -10,6 +10,7 @@ require 'app/models/concerns/delayed_job_configuration'
10
10
  require 'app/models/concerns/email_able'
11
11
  require 'app/models/concerns/encrypted_password'
12
12
  require 'app/models/concerns/google_sso_configuration'
13
+ require 'app/models/concerns/ses_configuration'
13
14
  require 'app/models/concerns/search_able'
14
15
  require 'app/models/concerns/role_able'
15
16
  require 'app/models/concerns/time_zone_able'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web47core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.20
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Schroeder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-28 00:00:00.000000000 Z
11
+ date: 2023-09-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -58,6 +58,26 @@ dependencies:
58
58
  - - "<"
59
59
  - !ruby/object:Gem::Version
60
60
  version: '2'
61
+ - !ruby/object:Gem::Dependency
62
+ name: aws-sdk-ses
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '1.55'
68
+ - - "<"
69
+ - !ruby/object:Gem::Version
70
+ version: '2'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '1.55'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '2'
61
81
  - !ruby/object:Gem::Dependency
62
82
  name: cancancan
63
83
  requirement: !ruby/object:Gem::Requirement
@@ -767,6 +787,7 @@ files:
767
787
  - lib/app/models/concerns/search_able.rb
768
788
  - lib/app/models/concerns/secure_fields.rb
769
789
  - lib/app/models/concerns/server_process_able.rb
790
+ - lib/app/models/concerns/ses_configuration.rb
770
791
  - lib/app/models/concerns/slack_configuration.rb
771
792
  - lib/app/models/concerns/standard_model.rb
772
793
  - lib/app/models/concerns/switchboard_able.rb