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 +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:
|