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 +4 -4
- data/lib/fastlane/plugin/polidea/actions/polidea_store.rb +1 -1
- data/lib/fastlane/plugin/polidea/actions/s3.rb +18 -21
- data/lib/fastlane/plugin/polidea/helper/page_generator.rb +69 -0
- data/lib/fastlane/plugin/polidea/templates/installation_template.erb +1 -1
- data/lib/fastlane/plugin/polidea/templates/secure_installation_template.erb +134 -0
- data/lib/fastlane/plugin/polidea/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78b98a3b34d8fbc94f0c870b5d8fce2067a54288
|
4
|
+
data.tar.gz: 1da8c0688b0d59deed751304710b4945ec174c52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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=#{
|
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
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
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
|
-
|
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 %>"
|
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>
|
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.
|
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-
|
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:
|