forked from electron/osx-sign
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil-provisioning-profiles.js
180 lines (166 loc) · 6.15 KB
/
util-provisioning-profiles.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
* @module util-provisioning-profiles
*/
'use strict'
const path = require('path')
const Promise = require('bluebird')
const plist = require('plist')
const util = require('./util')
const debuglog = util.debuglog
const debugwarn = util.debugwarn
const getAppContentsPath = util.getAppContentsPath
const flatList = util.flatList
const copyFileAsync = util.copyFileAsync
const execFileAsync = util.execFileAsync
const lstatAsync = util.lstatAsync
const readdirAsync = util.readdirAsync
/**
* @constructor
* @param {string} filePath - Path to provisioning profile.
* @param {Object} message - Decoded message in provisioning profile.
*/
var ProvisioningProfile = module.exports.ProvisioningProfile = function (filePath, message) {
this.filePath = filePath
this.message = message
}
Object.defineProperty(ProvisioningProfile.prototype, 'name', {
get: function () {
return this.message['Name']
}
})
Object.defineProperty(ProvisioningProfile.prototype, 'platforms', {
get: function () {
if ('ProvisionsAllDevices' in this.message) return ['darwin'] // Developer ID
else if (this.type === 'distribution') return ['mas'] // Mac App Store
else return ['darwin', 'mas'] // Mac App Development
}
})
Object.defineProperty(ProvisioningProfile.prototype, 'type', {
get: function () {
if ('ProvisionedDevices' in this.message) return 'development' // Mac App Development
else return 'distribution' // Developer ID or Mac App Store
}
})
/**
* Returns a promise resolving to a ProvisioningProfile instance based on file.
* @function
* @param {string} filePath - Path to provisioning profile.
* @param {string} keychain - Keychain to use when unlocking provisioning profile.
* @returns {Promise} Promise.
*/
var getProvisioningProfileAsync = module.exports.getProvisioningProfileAsync = function (filePath, keychain = null) {
var securityArgs = [
'cms',
'-D', // Decode a CMS message
'-i', filePath // Use infile as source of data
]
if (keychain) {
securityArgs.push('-k', keychain)
}
return execFileAsync('security', securityArgs)
.then(function (result) {
var provisioningProfile = new ProvisioningProfile(filePath, plist.parse(result))
debuglog('Provisioning profile:', '\n',
'> Name:', provisioningProfile.name, '\n',
'> Platforms:', provisioningProfile.platforms, '\n',
'> Type:', provisioningProfile.type, '\n',
'> Path:', provisioningProfile.filePath, '\n',
'> Message:', provisioningProfile.message)
return provisioningProfile
})
}
/**
* Returns a promise resolving to a list of suitable provisioning profile within the current working directory.
* @function
* @param {Object} opts - Options.
* @returns {Promise} Promise.
*/
var findProvisioningProfilesAsync = module.exports.findProvisioningProfilesAsync = function (opts) {
return Promise.map([
process.cwd() // Current working directory
], function (dirPath) {
return readdirAsync(dirPath)
.map(function (name) {
var filePath = path.join(dirPath, name)
return lstatAsync(filePath)
.then(function (stat) {
if (stat.isFile()) {
switch (path.extname(filePath)) {
case '.provisionprofile':
return filePath
}
}
return undefined
})
})
})
.then(flatList)
.map(function (filePath) {
return getProvisioningProfileAsync(filePath)
.then(function (provisioningProfile) {
if (provisioningProfile.platforms.indexOf(opts.platform) >= 0 && provisioningProfile.type === opts.type) return provisioningProfile
debugwarn('Provisioning profile above ignored, not for ' + opts.platform + ' ' + opts.type + '.')
return undefined
})
})
.then(flatList)
}
/**
* Returns a promise embedding the provisioning profile in the app Contents folder.
* @function
* @param {Object} opts - Options.
* @returns {Promise} Promise.
*/
module.exports.preEmbedProvisioningProfile = function (opts) {
function embedProvisioningProfile () {
if (opts['provisioning-profile']) {
debuglog('Looking for existing provisioning profile...')
var embeddedFilePath = path.join(getAppContentsPath(opts), 'embedded.provisionprofile')
return lstatAsync(embeddedFilePath)
.then(function (stat) {
debuglog('Found embedded provisioning profile:', '\n',
'* Please manually remove the existing file if not wanted.', '\n',
'* Current file at:', embeddedFilePath)
})
.catch(function (err) {
if (err.code === 'ENOENT') {
// File does not exist
debuglog('Embedding provisioning profile...')
return copyFileAsync(opts['provisioning-profile'].filePath, embeddedFilePath)
} else throw err
})
}
}
if (opts['provisioning-profile']) {
// User input provisioning profile
debuglog('`provisioning-profile` passed in arguments.')
if (opts['provisioning-profile'] instanceof ProvisioningProfile) {
return embedProvisioningProfile()
} else {
return getProvisioningProfileAsync(opts['provisioning-profile'], opts['keychain'])
.then(function (provisioningProfile) {
opts['provisioning-profile'] = provisioningProfile
})
.then(embedProvisioningProfile)
}
} else {
// Discover provisioning profile
debuglog('No `provisioning-profile` passed in arguments, will find in current working directory and in user library...')
return findProvisioningProfilesAsync(opts)
.then(function (provisioningProfiles) {
if (provisioningProfiles.length > 0) {
// Provisioning profile(s) found
if (provisioningProfiles.length > 1) {
debuglog('Multiple provisioning profiles found, will use the first discovered.')
} else {
debuglog('Found 1 provisioning profile.')
}
opts['provisioning-profile'] = provisioningProfiles[0]
} else {
// No provisioning profile found
debuglog('No provisioning profile found, will not embed profile in app contents.')
}
})
.then(embedProvisioningProfile)
}
}