fastlane-plugin-polidea 0.3.5 → 0.4.0

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