zendesk_apps_support 4.27.0 → 4.29.3
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/README.md +1 -1
- data/config/locales/en.yml +4 -1
- data/config/locales/translations/zendesk_apps_support.yml +4 -0
- data/lib/zendesk_apps_support/location.rb +3 -1
- data/lib/zendesk_apps_support/package.rb +23 -17
- data/lib/zendesk_apps_support/validations/manifest.rb +54 -33
- data/lib/zendesk_apps_support/validations/requests.rb +4 -54
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dba69f9baf26e1f28d4cd6538eb63d67f9f182b04469cb3ab6d9b02f69579081
|
4
|
+
data.tar.gz: 29a12f5b4f0dc4f24d9f92fe3654050ca2f20f3d3036353b411024053db94a86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf68d496dfb03184b5e2065e35e13d87c6baa932809d91963c72c836142eb23b3c487d74fb0a434a0fa4345563886e9b8dd456080ee3fd805e8b7d8a993d534d
|
7
|
+
data.tar.gz: 29d5b553e3df6fdae73ac4185c41023185c8a1cc52de1733faa0977ea90d0be481cd3f2a0c66152823ffacf35f6547516f8308018ddbe5e333349d6f798adb2d
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ This project uses Rspec, which can be run with `bundle exec rake`.
|
|
22
22
|
|
23
23
|
## Contribute
|
24
24
|
* Put up a PR into the master branch.
|
25
|
-
* CC and get two +1 from @zendesk/vegemite.
|
25
|
+
* CC and get two +1 from @zendesk/dingo, @zendesk/wattle, or @zendesk/vegemite.
|
26
26
|
|
27
27
|
## Bugs
|
28
28
|
Bugs can be reported as an issue here on github, or submitted to support@zendesk.com. By mentioning this project it will assigned to the right team.
|
data/config/locales/en.yml
CHANGED
@@ -62,7 +62,6 @@ en:
|
|
62
62
|
other: Unsupported MIME types detected in %{file_names}.
|
63
63
|
multiple_channel_integrations: Specifying multiple channel integrations
|
64
64
|
in requirements.json is not supported.
|
65
|
-
too_many_oauth_parameters: "Too many parameters with type 'oauth': one permitted"
|
66
65
|
invalid_cr_schema_keys:
|
67
66
|
one: 'Custom resources schema contains an invalid key: %{invalid_keys}'
|
68
67
|
other: 'Custom resources schema contains invalid keys: %{invalid_keys}'
|
@@ -78,6 +77,8 @@ en:
|
|
78
77
|
missing:
|
79
78
|
one: 'Missing required oauth field in manifest: %{missing_keys}'
|
80
79
|
other: 'Missing required oauth fields in manifest: %{missing_keys}'
|
80
|
+
too_many_oauth_parameters: 'Too many parameters with type ''oauth'': one
|
81
|
+
permitted'
|
81
82
|
missing_source: Could not find app.js
|
82
83
|
style_in_template: "<style> tag in %{template}. Use an app.css file instead."
|
83
84
|
no_code_for_ifo_notemplate: Javascripts, stylesheets, and templates are
|
@@ -139,6 +140,8 @@ en:
|
|
139
140
|
invalid_v1_location:
|
140
141
|
one: "%{invalid_locations} is an invalid location in framework v1."
|
141
142
|
other: "%{invalid_locations} are invalid locations in framework v1."
|
143
|
+
oauth_parameter_cannot_be_secure: oauth parameter cannot be set to be
|
144
|
+
secure.
|
142
145
|
warning:
|
143
146
|
app_build:
|
144
147
|
deprecated_version: You are targeting a deprecated version of the framework.
|
@@ -399,3 +399,7 @@ parts:
|
|
399
399
|
key: "txt.apps.admin.error.app_build.invalid_v1_location.other"
|
400
400
|
title: "The locations listed are not available in framework v1."
|
401
401
|
value: "%{invalid_locations} are invalid locations in framework v1."
|
402
|
+
- translation:
|
403
|
+
key: "txt.apps.admin.error.app_build.oauth_parameter_cannot_be_secure"
|
404
|
+
title: "oauth parameter cannot be set to be secure."
|
405
|
+
value: "oauth parameter cannot be set to be secure."
|
@@ -63,7 +63,9 @@ module ZendeskAppsSupport
|
|
63
63
|
Location.new(id: 21, name: 'dashboard', product_code: Product::SELL.code, visible: true),
|
64
64
|
Location.new(id: 22, name: 'note_editor', product_code: Product::SELL.code, visible: true),
|
65
65
|
Location.new(id: 23, name: 'call_log_editor', product_code: Product::SELL.code, visible: true),
|
66
|
-
Location.new(id: 24, name: 'email_editor', product_code: Product::SELL.code, visible: true)
|
66
|
+
Location.new(id: 24, name: 'email_editor', product_code: Product::SELL.code, visible: true),
|
67
|
+
Location.new(id: 25, name: 'top_bar', product_code: Product::SELL.code, visible: true),
|
68
|
+
Location.new(id: 26, name: 'visit_editor', product_code: Product::SELL.code, visible: true)
|
67
69
|
].freeze
|
68
70
|
end
|
69
71
|
end
|
@@ -16,7 +16,10 @@ module ZendeskAppsSupport
|
|
16
16
|
DEFAULT_SCSS = File.read(File.expand_path('../assets/default_styles.scss', __FILE__))
|
17
17
|
SRC_TEMPLATE = Erubis::Eruby.new(File.read(File.expand_path('../assets/src.js.erb', __FILE__)))
|
18
18
|
|
19
|
-
|
19
|
+
LOCATIONS_WITH_ICONS_PER_PRODUCT = {
|
20
|
+
Product::SUPPORT => %w[top_bar nav_bar system_top_bar ticket_editor].freeze,
|
21
|
+
Product::SELL => %w[top_bar].freeze
|
22
|
+
}.freeze
|
20
23
|
|
21
24
|
attr_reader :lib_root, :root, :warnings
|
22
25
|
|
@@ -37,10 +40,10 @@ module ZendeskAppsSupport
|
|
37
40
|
errors << Validations::Source.call(self)
|
38
41
|
errors << Validations::Translations.call(self, skip_marketplace_translations: skip_marketplace_translations)
|
39
42
|
errors << Validations::Requirements.call(self)
|
40
|
-
errors << Validations::Requests.call(self)
|
41
43
|
|
42
44
|
# only adds warnings
|
43
45
|
Validations::SecureSettings.call(self)
|
46
|
+
Validations::Requests.call(self)
|
44
47
|
|
45
48
|
unless manifest.requirements_only? || manifest.marketing_only? || manifest.iframe_only?
|
46
49
|
errors << Validations::Templates.call(self)
|
@@ -275,6 +278,24 @@ module ZendeskAppsSupport
|
|
275
278
|
end
|
276
279
|
end
|
277
280
|
|
281
|
+
def location_icons
|
282
|
+
Hash.new { |h, k| h[k] = {} }.tap do |location_icons|
|
283
|
+
manifest.location_options.each do |location_options|
|
284
|
+
# no location information in the manifest
|
285
|
+
next unless location_options.location
|
286
|
+
|
287
|
+
product = location_options.location.product
|
288
|
+
location_name = location_options.location.name
|
289
|
+
# the location on the product does not support icons
|
290
|
+
next unless LOCATIONS_WITH_ICONS_PER_PRODUCT.fetch(product, []).include?(location_name)
|
291
|
+
|
292
|
+
host = location_options.location.product.name
|
293
|
+
product_directory = manifest.products.count > 1 ? "#{host}/" : ''
|
294
|
+
location_icons[host][location_name] = build_location_icons_hash(location_name, product_directory)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
278
299
|
private
|
279
300
|
|
280
301
|
def generate_logo_hash(products)
|
@@ -318,21 +339,6 @@ module ZendeskAppsSupport
|
|
318
339
|
has_file?('assets/banner.png')
|
319
340
|
end
|
320
341
|
|
321
|
-
def location_icons
|
322
|
-
Hash.new { |h, k| h[k] = {} }.tap do |location_icons|
|
323
|
-
manifest.location_options.each do |location_options|
|
324
|
-
next unless location_options.location &&
|
325
|
-
LOCATIONS_WITH_ICONS.include?(location_options.location.name) &&
|
326
|
-
location_options.location.product == Product::SUPPORT
|
327
|
-
|
328
|
-
host = location_options.location.product.name
|
329
|
-
location = location_options.location.name
|
330
|
-
product_directory = manifest.products.count > 1 ? "#{host}/" : ''
|
331
|
-
location_icons[host][location] = build_location_icons_hash(location, product_directory)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
342
|
def build_location_icons_hash(location, product_directory)
|
337
343
|
inactive_png = "icon_#{location}_inactive.png"
|
338
344
|
if has_file?("assets/#{product_directory}icon_#{location}.svg")
|
@@ -33,51 +33,71 @@ module ZendeskAppsSupport
|
|
33
33
|
def collate_manifest_errors(package)
|
34
34
|
manifest = package.manifest
|
35
35
|
|
36
|
-
errors = [
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
errors = [
|
37
|
+
missing_keys_error(manifest),
|
38
|
+
type_checks(manifest),
|
39
|
+
oauth_error(manifest),
|
40
|
+
default_locale_error(manifest, package),
|
41
|
+
validate_parameters(manifest),
|
42
|
+
if manifest.requirements_only? || manifest.marketing_only?
|
43
|
+
[ ban_location(manifest),
|
44
|
+
ban_framework_version(manifest) ]
|
45
|
+
else
|
46
|
+
[ validate_location(package),
|
47
|
+
missing_framework_version(manifest),
|
48
|
+
invalid_version_error(manifest) ]
|
49
|
+
end,
|
50
|
+
ban_no_template(manifest)
|
51
|
+
]
|
52
|
+
errors.flatten.compact
|
53
|
+
end
|
41
54
|
|
55
|
+
def validate_location(package)
|
56
|
+
manifest = package.manifest
|
57
|
+
[
|
58
|
+
missing_location_error(package),
|
59
|
+
invalid_location_error(package),
|
60
|
+
invalid_v1_location(package),
|
61
|
+
location_framework_mismatch(manifest)
|
62
|
+
]
|
63
|
+
end
|
64
|
+
|
65
|
+
def validate_parameters(manifest)
|
42
66
|
if manifest.marketing_only?
|
43
|
-
|
67
|
+
marketing_only_errors(manifest)
|
44
68
|
else
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
69
|
+
[
|
70
|
+
parameters_error(manifest),
|
71
|
+
invalid_hidden_parameter_error(manifest),
|
72
|
+
invalid_type_error(manifest),
|
73
|
+
too_many_oauth_parameters(manifest),
|
74
|
+
oauth_cannot_be_secure(manifest),
|
75
|
+
name_as_parameter_name_error(manifest)
|
76
|
+
]
|
50
77
|
end
|
78
|
+
end
|
51
79
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
errors << invalid_location_error(package)
|
58
|
-
errors << invalid_v1_location(package)
|
59
|
-
errors << missing_framework_version(manifest)
|
60
|
-
errors << location_framework_mismatch(manifest)
|
61
|
-
errors << invalid_version_error(manifest)
|
80
|
+
def oauth_cannot_be_secure(manifest)
|
81
|
+
manifest.parameters.map do |parameter|
|
82
|
+
if parameter.type == 'oauth' && parameter.secure
|
83
|
+
return ValidationError.new('oauth_parameter_cannot_be_secure')
|
84
|
+
end
|
62
85
|
end
|
63
|
-
|
64
|
-
errors << ban_no_template(manifest) if manifest.iframe_only?
|
65
|
-
|
66
|
-
errors.flatten.compact
|
67
86
|
end
|
68
87
|
|
69
88
|
def marketing_only_errors(manifest)
|
70
|
-
[
|
71
|
-
|
72
|
-
|
73
|
-
|
89
|
+
[
|
90
|
+
ban_parameters(manifest),
|
91
|
+
private_marketing_app_error(manifest)
|
92
|
+
]
|
74
93
|
end
|
75
94
|
|
76
95
|
def type_checks(manifest)
|
77
|
-
errors = [
|
78
|
-
|
79
|
-
|
80
|
-
|
96
|
+
errors = [
|
97
|
+
boolean_error(manifest),
|
98
|
+
string_error(manifest),
|
99
|
+
no_template_format_error(manifest)
|
100
|
+
]
|
81
101
|
unless manifest.experiments.is_a?(Hash)
|
82
102
|
errors << ValidationError.new(
|
83
103
|
:unacceptable_hash,
|
@@ -152,6 +172,7 @@ module ZendeskAppsSupport
|
|
152
172
|
end
|
153
173
|
|
154
174
|
def ban_no_template(manifest)
|
175
|
+
return unless manifest.iframe_only?
|
155
176
|
no_template_migration_link = 'https://developer.zendesk.com/apps/docs/apps-v2/manifest#location'
|
156
177
|
if manifest.no_template? || !manifest.no_template_locations.empty?
|
157
178
|
ValidationError.new(:no_template_deprecated_in_v2, link: no_template_migration_link)
|
@@ -7,62 +7,25 @@ module ZendeskAppsSupport
|
|
7
7
|
module Validations
|
8
8
|
module Requests
|
9
9
|
class << self
|
10
|
-
IP_ADDRESS = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/
|
11
|
-
|
12
10
|
def call(package)
|
13
|
-
errors = []
|
14
11
|
files = package.js_files + package.html_files
|
15
|
-
private_app = package.manifest.private?
|
16
12
|
|
17
13
|
files.each do |file|
|
18
14
|
file_content = file.read
|
19
15
|
|
20
16
|
http_protocol_urls = find_address_containing_http(file_content)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
)
|
26
|
-
end
|
27
|
-
|
28
|
-
ip_addresses = file_content.scan(IP_ADDRESS)
|
29
|
-
next unless ip_addresses.any?
|
30
|
-
|
31
|
-
ip_validation_messages = ip_validation_messages(
|
32
|
-
file.relative_path,
|
33
|
-
ip_addresses,
|
34
|
-
private_app
|
17
|
+
next unless http_protocol_urls.any?
|
18
|
+
package.warnings << insecure_http_requests_warning(
|
19
|
+
http_protocol_urls,
|
20
|
+
file.relative_path
|
35
21
|
)
|
36
|
-
|
37
|
-
validation_group = private_app ? package.warnings : errors
|
38
|
-
validation_group << ip_validation_messages
|
39
22
|
end
|
40
23
|
|
41
24
|
package.warnings.flatten!
|
42
|
-
errors
|
43
25
|
end
|
44
26
|
|
45
27
|
private
|
46
28
|
|
47
|
-
def ip_validation_messages(file_path, ip_addresses, private_app)
|
48
|
-
ip_addresses.each_with_object([]) do |ip_address, messages|
|
49
|
-
ip_type_string = ip_type_string(ip_address)
|
50
|
-
next unless ip_type_string
|
51
|
-
|
52
|
-
string_params = {
|
53
|
-
type: ip_type_string, uri: ip_address, file: file_path
|
54
|
-
}
|
55
|
-
validation_message =
|
56
|
-
if private_app
|
57
|
-
I18n.t('txt.apps.admin.error.app_build.blocked_request', string_params)
|
58
|
-
else
|
59
|
-
ValidationError.new(:blocked_request, string_params)
|
60
|
-
end
|
61
|
-
|
62
|
-
messages << validation_message
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
29
|
def insecure_http_requests_warning(http_protocol_urls, relative_path)
|
67
30
|
http_protocol_urls = http_protocol_urls.join(
|
68
31
|
I18n.t('txt.apps.admin.error.app_build.listing_comma')
|
@@ -75,19 +38,6 @@ module ZendeskAppsSupport
|
|
75
38
|
)
|
76
39
|
end
|
77
40
|
|
78
|
-
def ip_type_string(ip_address)
|
79
|
-
block_type =
|
80
|
-
case IPAddress.parse(ip_address)
|
81
|
-
when proc(&:private?) then 'private'
|
82
|
-
when proc(&:loopback?) then 'loopback'
|
83
|
-
when proc(&:link_local?) then 'link_local'
|
84
|
-
end
|
85
|
-
|
86
|
-
block_type && I18n.t("txt.apps.admin.error.app_build.blocked_request_#{block_type}")
|
87
|
-
rescue ArgumentError
|
88
|
-
nil # Ignore numbers which are not an IP address
|
89
|
-
end
|
90
|
-
|
91
41
|
def find_address_containing_http(file_content)
|
92
42
|
file_content.scan(URI.regexp(['http'])).map(&:compact).map(&:last)
|
93
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zendesk_apps_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.29.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James A. Rosen
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2020-07-15 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: i18n
|
@@ -319,8 +319,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
319
|
- !ruby/object:Gem::Version
|
320
320
|
version: 1.3.6
|
321
321
|
requirements: []
|
322
|
-
|
323
|
-
rubygems_version: 2.7.10
|
322
|
+
rubygems_version: 3.0.6
|
324
323
|
signing_key:
|
325
324
|
specification_version: 4
|
326
325
|
summary: Support to help you develop Zendesk Apps.
|