Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-25318] (6_3_X) Improved provisioning profile validation #9463

Merged
merged 3 commits into from
Sep 21, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 77 additions & 17 deletions iphone/cli/commands/_build.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ var appc = require('node-appc'),
parallel = appc.async.parallel,
series = appc.async.series,
version = appc.version;

var platformsRegExp = /^(android|ios|iphone|ipad|mobileweb|blackberry|windows|tizen)$/;
const pemCertRegExp = /(^-----BEGIN CERTIFICATE-----)|(-----END CERTIFICATE-----.*$)|\n/g;

function iOSBuilder() {
Builder.apply(this, arguments);
Expand Down Expand Up @@ -191,6 +191,35 @@ iOSBuilder.prototype.assertIssue = function assertIssue(issues, name) {
}
};

/**
* Retrieves the certificate information by name.
*
* @param {String} name - The cert name.
* @param {String} [type] - The type of cert to scan (developer or distribution).
* @returns {Object|null}
* @access private
*/
iOSBuilder.prototype.findCertificate = function findCertificate(name, type) {
/* eslint-disable max-depth */
if (name && this.iosInfo) {
for (const keychain of Object.keys(this.iosInfo.certs.keychains)) {
const scopes = this.iosInfo.certs.keychains[keychain];
const types = type ? [ type ] : Object.keys(scopes);
for (const scope of types) {
if (scopes[scope]) {
for (const cert of scopes[scope]) {
if (cert.name === name) {
return cert;
}
}
}
}
}
}

return null;
};

/**
* Determines the valid list of devices or simulators. This is used for prompting
* and validation.
Expand Down Expand Up @@ -966,15 +995,16 @@ iOSBuilder.prototype.configOptionPPuuid = function configOptionPPuuid(order) {
hint: 'uuid',
order: order,
prompt: function (callback) {
var provisioningProfiles = {},
appId = cli.tiapp.id,
maxAppId = 0,
pp;
const provisioningProfiles = {};
const appId = cli.tiapp.id;
const target = cli.argv.target;
let maxAppId = 0;
let pp;

function prep(a) {
function prep(a, cert) {
return a.filter(function (p) {
if (!p.expired && !p.managed) {
var re = new RegExp(p.appId.replace(/\./g, '\\.').replace(/\*/g, '.*'));
if (!p.expired && !p.managed && (!cert || p.certs.indexOf(cert) !== -1)) {
const re = new RegExp(p.appId.replace(/\./g, '\\.').replace(/\*/g, '.*')); // eslint-disable-line security/detect-non-literal-regexp
if (re.test(appId)) {
var label = p.name;
if (label.indexOf(p.appId) === -1) {
Expand All @@ -990,13 +1020,24 @@ iOSBuilder.prototype.configOptionPPuuid = function configOptionPPuuid(order) {
});
}

if (cli.argv.target === 'device') {
let cert;
if (target === 'device') {
cert = _t.findCertificate(cli.argv['developer-name'], 'developer');
} else {
cert = _t.findCertificate(cli.argv['distribution-name'], 'distribution');
}

if (target === 'device') {
if (iosInfo.provisioning.development.length) {
pp = prep(iosInfo.provisioning.development);
pp = prep(iosInfo.provisioning.development, cert.pem.replace(pemCertRegExp, ''));
if (pp.length) {
provisioningProfiles[__('Available Development UUIDs:')] = pp;
} else {
logger.error(__('Unable to find any non-expired development provisioning profiles that match the app id "%s"', appId) + '\n');
if (cert) {
logger.error(__('Unable to find any non-expired development provisioning profiles that match the app id "%s" and the "%s" certificate.', appId, cert.name) + '\n');
} else {
logger.error(__('Unable to find any non-expired development provisioning profiles that match the app id "%s".', appId) + '\n');
}
logger.log(__('You will need to log in to %s with your Apple Developer account, then create, download, and install a profile.',
'http://appcelerator.com/ios-dev-certs'.cyan) + '\n');
process.exit(1);
Expand All @@ -1008,9 +1049,9 @@ iOSBuilder.prototype.configOptionPPuuid = function configOptionPPuuid(order) {
process.exit(1);
}

} else if (cli.argv.target === 'dist-appstore') {
} else if (target === 'dist-appstore') {
if (iosInfo.provisioning.distribution.length) {
pp = prep(iosInfo.provisioning.distribution);
pp = prep(iosInfo.provisioning.distribution, cert.pem.replace(pemCertRegExp, ''));
if (pp.length) {
provisioningProfiles[__('Available App Store Distribution UUIDs:')] = pp;
} else {
Expand All @@ -1026,10 +1067,10 @@ iOSBuilder.prototype.configOptionPPuuid = function configOptionPPuuid(order) {
process.exit(1);
}

} else if (cli.argv.target === 'dist-adhoc') {
} else if (target === 'dist-adhoc') {
if (iosInfo.provisioning.adhoc.length || iosInfo.provisioning.enterprise.length) {
pp = prep(iosInfo.provisioning.adhoc);
var valid = pp.length;
pp = prep(iosInfo.provisioning.adhoc, cert.pem.replace(pemCertRegExp, ''));
let valid = pp.length;
if (pp.length) {
provisioningProfiles[__('Available Ad Hoc UUIDs:')] = pp;
}
Expand Down Expand Up @@ -1081,9 +1122,12 @@ iOSBuilder.prototype.configOptionPPuuid = function configOptionPPuuid(order) {
}));
},
validate: function (value, callback) {
if (cli.argv.target === 'simulator') {
const target = cli.argv.target;

if (target === 'simulator') {
return callback(null, value);
}

if (value) {
var p = _t.provisioningProfileLookup[value.toLowerCase()];
if (!p) {
Expand All @@ -1095,8 +1139,21 @@ iOSBuilder.prototype.configOptionPPuuid = function configOptionPPuuid(order) {
if (p.expired) {
return callback(new Error(__('Specified provisioning profile UUID "%s" is expired', value)));
}

let cert;
if (target === 'device') {
cert = _t.findCertificate(cli.argv['developer-name'], 'developer');
} else {
cert = _t.findCertificate(cli.argv['distribution-name'], 'distribution');
}

if (cert && p.certs.indexOf(cert.pem.replace(pemCertRegExp, '')) === -1) {
return callback(new Error(__('Specified provisioning profile UUID "%s" does not include the "%s" certificate', value, cert.name)));
}

return callback(null, p.uuid);
}

callback(true);
}
};
Expand Down Expand Up @@ -3055,6 +3112,9 @@ iOSBuilder.prototype.createXcodeProject = function createXcodeProject(next) {
showEnvVarsInLog: 0
};
xobjs.PBXShellScriptBuildPhase[buildPhaseUuid + '_comment'] = '"' + name + '"';
} else if (this.target === 'device') {
buildSettings.CODE_SIGN_IDENTITY = '"iPhone Developer: ' + this.certDeveloperName + '"';
buildSettings.CODE_SIGN_STYLE = 'Manual';
}

// inject the team id and app groups
Expand Down