fastlane-plugin-polidea 0.3.5 → 0.4.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
  SHA1:
3
- metadata.gz: d4d878ea2de616d3e04e82bcd6894449375aa5cc
4
- data.tar.gz: 628e99f4d6d61a430bfdd980a89bfce97f7a1c5e
3
+ metadata.gz: 78b98a3b34d8fbc94f0c870b5d8fce2067a54288
4
+ data.tar.gz: 1da8c0688b0d59deed751304710b4945ec174c52
5
5
  SHA512:
6
- metadata.gz: 7214697866060b8b1f6b37d01aedaa48d14ac881ad92d6bb1bfa33eda25da33e08f02c0b9da38756a9897dcc799fcda853712cfe038a639b38ad51dd35cec944
7
- data.tar.gz: bad8d331f467ccfc4f77c856c5396077a44b3b3f9a1787f755fdba590f2ccf8d9ac0581de4b5f6b67563291aa55427ffd65966d401e718f8cc4397306d7e8114
6
+ metadata.gz: d7c32aedd8a994017cf83c9a18451146ad2fcf3afcca44960f3212d32f1eda40087ca0409f0bca2895b40f2db7e78c4f237222010f340356d8d6ee57b7ab05aa
7
+ data.tar.gz: 39555a300cc4e9805ab037cbe9707c9a870ded3fee2704e29b096d167d5a796878aeaab96f850a18e516344c4aef2a723c7d36208fc7616031e6f86cd9d1885a
@@ -227,7 +227,7 @@ module Fastlane
227
227
  private_class_method :create_request
228
228
 
229
229
  def self.itms_href(plist_url)
230
- "itms-services://?action=download-manifest&url=#{CGI.escape(plist_url)}"
230
+ "itms-services://?action=download-manifest&url=#{URI.encode_www_form_component(plist_url)}"
231
231
  end
232
232
  private_class_method :itms_href
233
233
 
@@ -3,6 +3,7 @@
3
3
  # rubocop:disable Metrics/ClassLength
4
4
  require 'fastlane/erb_template_helper'
5
5
  require 'ostruct'
6
+ require 'securerandom'
6
7
 
7
8
  module Fastlane
8
9
  module Actions
@@ -49,6 +50,7 @@ module Fastlane
49
50
  params[:version_template_path] = config[:version_template_path]
50
51
  params[:version_file_name] = config[:version_file_name]
51
52
  params[:acl] = config[:acl]
53
+ params[:installation_password] = config[:installation_password]
52
54
 
53
55
  case platform
54
56
  when :ios
@@ -71,6 +73,7 @@ module Fastlane
71
73
  icon_file = params[:icon]
72
74
  dsym_file = params[:dsym]
73
75
  acl = params[:acl]
76
+ installation_password = params[:installation_password]
74
77
 
75
78
  validate(params)
76
79
  UI.user_error!("No IPA file path given, pass using `ipa: 'ipa path'`") unless ipa_file.to_s.length > 0
@@ -88,7 +91,6 @@ module Fastlane
88
91
  url_part = get_url_part(app_name, "ios", bundle_version, build_number)
89
92
 
90
93
  plist_template_path = params[:plist_template_path]
91
- html_template_path = params[:html_template_path]
92
94
  html_file_name = params[:html_file_name]
93
95
  version_template_path = params[:version_template_path]
94
96
  version_file_name = params[:version_file_name]
@@ -147,8 +149,8 @@ module Fastlane
147
149
  plist_render = eth.render(plist_template, {
148
150
  url: ipa_url,
149
151
  ipa_url: ipa_url,
152
+ app_version: bundle_id,
150
153
  build_number: build_number,
151
- bundle_id: bundle_id,
152
154
  bundle_version: bundle_version,
153
155
  title: app_name
154
156
  })
@@ -157,13 +159,9 @@ module Fastlane
157
159
  icon_url = self.upload_icon(icon_file, url_part, bucket, acl)
158
160
 
159
161
  # Creates html from template
160
- if html_template_path && File.exist?(html_template_path)
161
- html_template = eth.load_from_path(html_template_path)
162
- else
163
- html_template = eth.load_from_path("#{__dir__}/../templates/installation_template.erb")
164
- end
165
- html_render = eth.render(html_template, {
166
- url: "itms-services://?action=download-manifest&url=#{plist_url}",
162
+ html_render = PageGenerator.generate({
163
+ url: "itms-services://?action=download-manifest&url=#{URI.encode_www_form_component(plist_url)}",
164
+ installation_password: installation_password,
167
165
  app_version: bundle_version,
168
166
  build_number: build_number,
169
167
  title: app_name,
@@ -228,6 +226,7 @@ module Fastlane
228
226
  apk_file = params[:apk]
229
227
  icon_file = params[:icon]
230
228
  acl = params[:acl]
229
+ installation_password = params[:installation_password]
231
230
 
232
231
  validate(params)
233
232
  UI.user_error!("No APK file path given, pass using `apk: 'apk path'`") unless apk_file.to_s.length > 0
@@ -242,7 +241,6 @@ module Fastlane
242
241
  app_version = manifest.version_name
243
242
  url_part = get_url_part(app_name, "android", app_version, build_number)
244
243
 
245
- html_template_path = params[:html_template_path]
246
244
  html_file_name = params[:html_file_name]
247
245
 
248
246
  apk_file_basename = File.basename(apk_file)
@@ -266,20 +264,13 @@ module Fastlane
266
264
  html_file_name ||= "#{url_part}index.html"
267
265
  html_resources_name = "#{url_part}installation-page"
268
266
 
269
- # grabs module
270
- eth = Fastlane::ErbTemplateHelper
271
-
272
267
  # Gets icon from ipa and uploads it
273
268
  icon_url = self.upload_icon(icon_file, url_part, bucket, acl)
274
269
 
275
270
  # Creates html from template
276
- if html_template_path && File.exist?(html_template_path)
277
- html_template = eth.load_from_path(html_template_path)
278
- else
279
- html_template = eth.load_from_path("#{__dir__}/../templates/installation_template.erb")
280
- end
281
- html_render = eth.render(html_template, {
271
+ html_render = PageGenerator.generate({
282
272
  url: apk_url,
273
+ installation_password: installation_password,
283
274
  app_version: app_version,
284
275
  build_number: build_number,
285
276
  title: app_name,
@@ -314,7 +305,8 @@ module Fastlane
314
305
  end
315
306
 
316
307
  def self.get_url_part(app_name, platform, app_version, build_number)
317
- "#{app_name}/#{platform}/#{app_version}_#{build_number}/"
308
+ random_part = SecureRandom.hex(10)
309
+ "#{app_name}/#{platform}/#{app_version}_#{build_number}/#{random_part}/"
318
310
  end
319
311
 
320
312
  def self.get_bucket(s3_access_key, s3_secret_access_key, s3_region, s3_bucket)
@@ -507,7 +499,12 @@ module Fastlane
507
499
  env_name: "S3_ACL",
508
500
  description: "Uploaded object permissions e.g public_read (default), private, public_read_write, authenticated_read ",
509
501
  optional: true,
510
- default_value: "public_read")
502
+ default_value: "public_read"),
503
+ FastlaneCore::ConfigItem.new(key: :installation_password,
504
+ env_name: "INSTALLATION_PASSWORD",
505
+ description: "Password for installation page",
506
+ optional: true,
507
+ default_value: nil)
511
508
  ]
512
509
  end
513
510
 
@@ -0,0 +1,69 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+ require 'json'
4
+
5
+ module Fastlane
6
+ module PageGenerator
7
+ def self.generate(config)
8
+ if config[:installation_password]
9
+ generate_private(config)
10
+ else
11
+ generate_public(config)
12
+ end
13
+ end
14
+
15
+ def self.generate_private(config)
16
+ UI.message("Generating private installation page with password `#{config[:installation_password]}`...")
17
+ eth = Fastlane::ErbTemplateHelper
18
+ html_template = eth.load_from_path("#{__dir__}/../templates/secure_installation_template.erb")
19
+ installation_link, salt, iv = encrypt(config[:url], config[:installation_password])
20
+ eth.render(html_template, {
21
+ url: installation_link,
22
+ salt: salt,
23
+ iv: iv,
24
+ app_version: config[:bundle_version],
25
+ build_number: config[:build_number],
26
+ title: config[:app_name],
27
+ app_icon: config[:icon_url],
28
+ platform: config[:platform]
29
+ })
30
+ end
31
+ private_class_method :generate_private
32
+
33
+ def self.generate_public(config)
34
+ UI.message("Generating public installation page...")
35
+ eth = Fastlane::ErbTemplateHelper
36
+ html_template = eth.load_from_path("#{__dir__}/../templates/installation_template.erb")
37
+ eth.render(html_template, {
38
+ url: config[:url],
39
+ app_version: config[:bundle_version],
40
+ build_number: config[:build_number],
41
+ title: config[:app_name],
42
+ app_icon: config[:icon_url],
43
+ platform: config[:platform]
44
+ })
45
+ end
46
+ private_class_method :generate_public
47
+
48
+ def self.encrypt(url, password)
49
+ salt = OpenSSL::Random.random_bytes(32)
50
+ iter = 128
51
+ key_len = 32
52
+ key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(password, salt, iter, key_len)
53
+
54
+ cipher = OpenSSL::Cipher::AES256.new(:CBC)
55
+ cipher.encrypt
56
+ cipher.key = key
57
+
58
+ random_iv = cipher.random_iv
59
+ iv = Base64.encode64(random_iv).delete "\n"
60
+ to_json = { url: url.to_s }.to_json
61
+ var = cipher.update(to_json.to_s) + cipher.final
62
+
63
+ installation_link = Base64.encode64(var).delete "\n"
64
+ salt = Base64.encode64(salt).delete "\n"
65
+ return installation_link, salt, iv
66
+ end
67
+ private_class_method :encrypt
68
+ end
69
+ end
@@ -35,7 +35,7 @@
35
35
  </div>
36
36
  </div>
37
37
  <div class="small-12 medium-4 medium-offset-2 columns inner-element">
38
- <a class="install-button expand" href="<%= url %>" onclick="document.getElementById('finished').id = '';">Install</a>
38
+ <a class="install-button expand" href="<%= url %>">Install</a>
39
39
  </div>
40
40
  </div>
41
41
  </div>
@@ -0,0 +1,134 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head lang="en">
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Install <%= title %></title>
7
+
8
+ <link href='//fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
9
+ <link rel="stylesheet" href="installation-page/css/installation-page.css" type="text/css">
10
+ </head>
11
+ <body class="background">
12
+ <div class="row section top-section">
13
+ <div class="small-12 columns">
14
+ <object type="image/svg+xml" data="/release-resources/img/logo.svg"></object>
15
+ </div>
16
+ </div>
17
+
18
+ <div class="row section">
19
+ <div class="small-12 columns">
20
+ <div id="installation-panel">
21
+ <div class="row">
22
+ <div class="small-2 medium-2 columns inner-element">
23
+ <% if app_icon %>
24
+ <img src="<%= app_icon %>" class="no-resize icon-margin"/>
25
+ <% else %>
26
+ <object type="image/svg+xml" data="/release-resources/img/logo_square.svg"
27
+ class="app-icon no-resize inner-element icon-margin"></object>
28
+ <% end %>
29
+ </div>
30
+ <div class="small-10 columns inner-element" id="app-name">
31
+ <div class="app-name-wrapper">
32
+ <span class="title text-left"><%= title %></span><br>
33
+ <span class="version text-left">Version: <%= app_version %>(<%= build_number %>)</span>
34
+ <span class="version text-left">Platform: <%= platform %></span>
35
+ </div>
36
+ </div>
37
+
38
+ <div class="small-12 columns password-inner-element" id="password">
39
+ <form data-abide="ajax" id="myForm">
40
+ <div>
41
+ <label>Password <small>required</small>
42
+ <input type="password" required data-abide-validator="passwordValidator" id="password-textfield">
43
+ <small class="error" id="nameError">Password incorrect.</small>
44
+ </label>
45
+ </div>
46
+ <button type="submit" class="password-button">Submit</button>
47
+ </form>
48
+ </div>
49
+
50
+ <div class="small-12 medium-4 medium-offset-2 columns inner-element" hidden id="install-button">
51
+ <a class="install-button expand" id="installation-link">Install</a>
52
+ </div>
53
+
54
+
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </div>
59
+
60
+ <% if release_notes && release_notes.count > 0 %>
61
+ <div class="row section">
62
+ <div class="small-12 columns">
63
+ <span class="whats-new">What's new:</span>
64
+ <ul>
65
+ <% for @item in @notes %>
66
+ <li><%= @item %></li>
67
+ <% end %>
68
+ </ul>
69
+ </div>
70
+ </div>
71
+ <% end %>
72
+
73
+ <script src="installation-page/js/vendor/pbkdf2.js"></script>
74
+ <script src="installation-page/js/vendor/enc-base64-min.js"></script>
75
+ <script src="installation-page/js/vendor/aes.js"></script>
76
+ <script src="installation-page/js/vendor/jquery.js"></script>
77
+ <script src="installation-page/js/vendor/fastclick.js"></script>
78
+ <script src="installation-page/js/foundation.min.js"></script>
79
+ <script src="installation-page/js/foundation/foundation.abide.js"></script>
80
+ <script>
81
+ $(document).foundation({
82
+ abide: {
83
+ live_validate : false,
84
+ focus_on_invalid: false,
85
+ validators: {
86
+ passwordValidator: function (el, required, parent) {
87
+ var salt = CryptoJS.enc.Base64.parse("<%= salt %>");
88
+ var iv = CryptoJS.enc.Base64.parse("<%= iv %>");
89
+ var pass = $(el).val();
90
+
91
+ var key = CryptoJS.PBKDF2(pass, salt, { keySize: 256 / 32, iterations: 128 });
92
+ var data = CryptoJS.enc.Base64.parse("<%= url %>");
93
+
94
+ var aesDecryptor = CryptoJS.algo.AES.createDecryptor(key, { iv: iv, mode: CryptoJS.mode.CBC});
95
+ var decrypted = aesDecryptor.process(data);
96
+ var finalized = aesDecryptor.finalize();
97
+
98
+ try {
99
+ var message = decrypted.concat(finalized).toString(CryptoJS.enc.Utf8);
100
+ console.log(message);
101
+
102
+ var json = jQuery.parseJSON(message);
103
+ console.log(json);
104
+
105
+ if (json['url']) {
106
+ $('#installation-link').attr("href", json['url']);
107
+ return true;
108
+ }
109
+ }
110
+ catch (err) {
111
+ return false;
112
+ }
113
+
114
+ return false;
115
+ }
116
+ }
117
+ }
118
+ });
119
+
120
+ $("#myForm").on("valid.fndtn.abide invalid.fndtn.abide submit.fndtn.abide", function (g) {
121
+ g.stopPropagation();
122
+ g.preventDefault();
123
+ if (g.type === "valid") {
124
+ console.log(g.type);
125
+
126
+ $('#install-button').show();
127
+ $('#password').hide();
128
+ $('#app-name').attr("class", "small-10 medium-4 columns inner-element");
129
+ }
130
+ return false;
131
+ });
132
+ </script>
133
+ </body>
134
+ </html>
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Polidea
3
- VERSION = "0.3.5"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-polidea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotrek Dubiel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-06 00:00:00.000000000 Z
11
+ date: 2016-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: plist
@@ -142,6 +142,20 @@ dependencies:
142
142
  - - ">="
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: pry
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
145
159
  - !ruby/object:Gem::Dependency
146
160
  name: rubocop
147
161
  requirement: !ruby/object:Gem::Requirement
@@ -189,6 +203,7 @@ files:
189
203
  - lib/fastlane/plugin/polidea/actions/polidea_store.rb
190
204
  - lib/fastlane/plugin/polidea/actions/release_notes.rb
191
205
  - lib/fastlane/plugin/polidea/actions/s3.rb
206
+ - lib/fastlane/plugin/polidea/helper/page_generator.rb
192
207
  - lib/fastlane/plugin/polidea/helper/qr_generator.rb
193
208
  - lib/fastlane/plugin/polidea/templates/images/icon-placeholder.png
194
209
  - lib/fastlane/plugin/polidea/templates/images/logo.png
@@ -283,6 +298,7 @@ files:
283
298
  - lib/fastlane/plugin/polidea/templates/installation-page/sass/normalize.scss
284
299
  - lib/fastlane/plugin/polidea/templates/installation_template.erb
285
300
  - lib/fastlane/plugin/polidea/templates/mailgun_template.erb
301
+ - lib/fastlane/plugin/polidea/templates/secure_installation_template.erb
286
302
  - lib/fastlane/plugin/polidea/version.rb
287
303
  homepage:
288
304
  licenses: