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 +4 -4
- data/app/views/delayed_jobs/_index.html.haml +3 -3
- data/app/views/delayed_jobs/_show.html.haml +1 -1
- data/lib/app/controllers/concerns/core_delayed_jobs_controller.rb +1 -1
- data/lib/app/models/concerns/aws_configuration.rb +6 -3
- data/lib/app/models/concerns/core_system_configuration.rb +15 -0
- data/lib/app/models/concerns/ses_configuration.rb +45 -0
- data/lib/app/models/email_notification.rb +41 -48
- data/lib/web47core/version.rb +1 -1
- data/lib/web47core.rb +1 -0
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7147715aefdef70511603bf5ddb8afa017da40ef51c54d4c14e10edd7c15d21d
|
4
|
+
data.tar.gz: 0fca6d931d158a0900121ed7f22983fc13322375fc1e3acccd18fd2062a2cdfe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(:
|
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(:
|
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.
|
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,
|
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
|
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
|
-
|
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
|
-
|
74
|
-
mail.from = address
|
75
|
-
self.from = address
|
82
|
+
mail.from = from
|
76
83
|
# Set the sender line
|
77
|
-
|
78
|
-
mail.sender = address
|
79
|
-
self.sender = address
|
84
|
+
mail.sender = sender
|
80
85
|
# Set the reply to
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
#
|
data/lib/web47core/version.rb
CHANGED
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.
|
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:
|
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
|