web47core 2.2.20 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|