2016-01-11 19:58:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Copyright 2016 Resin.io
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2015-08-20 19:54:42 +00:00
|
|
|
(function() {
|
2016-01-12 14:44:11 +00:00
|
|
|
var Promise, _, chalk, form, messages, resin, validation, visuals;
|
2015-08-20 19:54:42 +00:00
|
|
|
|
|
|
|
_ = require('lodash');
|
|
|
|
|
|
|
|
Promise = require('bluebird');
|
|
|
|
|
|
|
|
form = require('resin-cli-form');
|
|
|
|
|
|
|
|
visuals = require('resin-cli-visuals');
|
|
|
|
|
|
|
|
resin = require('resin-sdk');
|
|
|
|
|
2015-10-06 22:51:17 +00:00
|
|
|
chalk = require('chalk');
|
|
|
|
|
2015-10-21 17:28:51 +00:00
|
|
|
validation = require('./validation');
|
2015-08-20 19:54:42 +00:00
|
|
|
|
2016-01-12 14:44:11 +00:00
|
|
|
messages = require('./messages');
|
|
|
|
|
2016-01-12 13:07:15 +00:00
|
|
|
exports.authenticate = function(options) {
|
|
|
|
return form.run([
|
|
|
|
{
|
|
|
|
message: 'Email:',
|
|
|
|
name: 'email',
|
|
|
|
type: 'input',
|
|
|
|
validate: validation.validateEmail
|
|
|
|
}, {
|
|
|
|
message: 'Password:',
|
|
|
|
name: 'password',
|
|
|
|
type: 'password'
|
|
|
|
}
|
|
|
|
], {
|
|
|
|
override: options
|
|
|
|
}).then(resin.auth.login).then(resin.auth.twoFactor.isPassed).then(function(isTwoFactorAuthPassed) {
|
|
|
|
if (isTwoFactorAuthPassed) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return form.ask({
|
|
|
|
message: 'Two factor auth challenge:',
|
|
|
|
name: 'code',
|
|
|
|
type: 'input'
|
2016-03-17 19:25:21 +00:00
|
|
|
}).then(resin.auth.twoFactor.challenge)["catch"](function(error) {
|
2016-01-12 13:07:15 +00:00
|
|
|
return resin.auth.logout().then(function() {
|
2016-03-17 19:25:21 +00:00
|
|
|
if (error.name === 'ResinRequestError' && error.statusCode === 401) {
|
|
|
|
throw new Error('Invalid two factor authentication code');
|
|
|
|
}
|
|
|
|
throw error;
|
2016-01-12 13:07:15 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.askLoginType = function() {
|
|
|
|
return form.ask({
|
|
|
|
message: 'How would you like to login?',
|
|
|
|
name: 'loginType',
|
|
|
|
type: 'list',
|
|
|
|
choices: [
|
|
|
|
{
|
|
|
|
name: 'Web authorization (recommended)',
|
|
|
|
value: 'web'
|
|
|
|
}, {
|
|
|
|
name: 'Credentials',
|
|
|
|
value: 'credentials'
|
|
|
|
}, {
|
|
|
|
name: 'Authentication token',
|
|
|
|
value: 'token'
|
2016-01-13 04:25:31 +00:00
|
|
|
}, {
|
|
|
|
name: 'I don\'t have a Resin account!',
|
|
|
|
value: 'register'
|
2016-01-12 13:07:15 +00:00
|
|
|
}
|
|
|
|
]
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-08-20 19:54:42 +00:00
|
|
|
exports.selectDeviceType = function() {
|
|
|
|
return resin.models.device.getSupportedDeviceTypes().then(function(deviceTypes) {
|
|
|
|
return form.ask({
|
|
|
|
message: 'Device Type',
|
|
|
|
type: 'list',
|
|
|
|
choices: deviceTypes
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.confirm = function(yesOption, message) {
|
|
|
|
return Promise["try"](function() {
|
|
|
|
if (yesOption) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return form.ask({
|
|
|
|
message: message,
|
|
|
|
type: 'confirm',
|
|
|
|
"default": false
|
|
|
|
});
|
|
|
|
}).then(function(confirmed) {
|
|
|
|
if (!confirmed) {
|
|
|
|
throw new Error('Aborted');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-11-11 19:00:02 +00:00
|
|
|
exports.selectApplication = function(filter) {
|
2015-09-29 15:10:33 +00:00
|
|
|
return resin.models.application.hasAny().then(function(hasAnyApplications) {
|
|
|
|
if (!hasAnyApplications) {
|
|
|
|
throw new Error('You don\'t have any applications');
|
|
|
|
}
|
2015-11-11 19:00:02 +00:00
|
|
|
return resin.models.application.getAll();
|
|
|
|
}).filter(filter || _.constant(true)).then(function(applications) {
|
|
|
|
return form.ask({
|
|
|
|
message: 'Select an application',
|
|
|
|
type: 'list',
|
2015-11-23 13:23:08 +00:00
|
|
|
choices: _.map(applications, function(application) {
|
|
|
|
return {
|
|
|
|
name: application.app_name + " (" + application.device_type + ")",
|
|
|
|
value: application.app_name
|
|
|
|
};
|
|
|
|
})
|
2015-09-29 15:10:33 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.selectOrCreateApplication = function() {
|
2015-08-20 19:54:42 +00:00
|
|
|
return resin.models.application.hasAny().then(function(hasAnyApplications) {
|
|
|
|
if (!hasAnyApplications) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return resin.models.application.getAll().then(function(applications) {
|
2015-11-23 13:23:08 +00:00
|
|
|
applications = _.map(applications, function(application) {
|
|
|
|
return {
|
|
|
|
name: application.app_name + " (" + application.device_type + ")",
|
|
|
|
value: application.app_name
|
|
|
|
};
|
|
|
|
});
|
2015-08-20 19:54:42 +00:00
|
|
|
applications.unshift({
|
|
|
|
name: 'Create a new application',
|
|
|
|
value: null
|
|
|
|
});
|
|
|
|
return form.ask({
|
|
|
|
message: 'Select an application',
|
|
|
|
type: 'list',
|
|
|
|
choices: applications
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}).then(function(application) {
|
|
|
|
if (application != null) {
|
|
|
|
return application;
|
|
|
|
}
|
|
|
|
return form.ask({
|
|
|
|
message: 'Choose a Name for your new application',
|
2015-10-19 14:56:02 +00:00
|
|
|
type: 'input',
|
2015-10-21 13:37:25 +00:00
|
|
|
validate: validation.validateApplicationName
|
2015-08-20 19:54:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
exports.awaitDevice = function(uuid) {
|
|
|
|
return resin.models.device.getName(uuid).then(function(deviceName) {
|
2015-10-07 15:38:59 +00:00
|
|
|
var poll, spinner;
|
|
|
|
spinner = new visuals.Spinner("Waiting for " + deviceName + " to come online");
|
|
|
|
poll = function() {
|
|
|
|
return resin.models.device.isOnline(uuid).then(function(isOnline) {
|
|
|
|
if (isOnline) {
|
|
|
|
spinner.stop();
|
2016-01-25 12:59:09 +00:00
|
|
|
console.info("The device **" + deviceName + "** is online!");
|
2015-10-07 15:38:59 +00:00
|
|
|
} else {
|
|
|
|
spinner.start();
|
|
|
|
return Promise.delay(3000).then(poll);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2015-08-20 19:54:42 +00:00
|
|
|
console.info("Waiting for " + deviceName + " to connect to resin...");
|
|
|
|
return poll()["return"](uuid);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2016-04-25 12:32:58 +00:00
|
|
|
exports.inferOrSelectDevice = function(applicationName) {
|
|
|
|
return Promise["try"](function() {
|
|
|
|
if (applicationName != null) {
|
|
|
|
return resin.models.device.getAllByApplication(applicationName);
|
|
|
|
}
|
|
|
|
return resin.models.device.getAll();
|
2016-07-07 15:47:02 +00:00
|
|
|
}).filter(function(device) {
|
|
|
|
return device.is_online;
|
2016-04-25 12:32:58 +00:00
|
|
|
}).then(function(devices) {
|
|
|
|
if (_.isEmpty(devices)) {
|
|
|
|
throw new Error('You don\'t have any devices');
|
|
|
|
}
|
|
|
|
if (devices.length === 1) {
|
|
|
|
return _.first(devices).uuid;
|
|
|
|
}
|
|
|
|
return form.ask({
|
|
|
|
message: 'Select a device',
|
|
|
|
type: 'list',
|
|
|
|
choices: _.map(devices, function(device) {
|
|
|
|
return {
|
|
|
|
name: (device.name || 'Untitled') + " (" + (device.uuid.slice(0, 7)) + ")",
|
|
|
|
value: device.uuid
|
|
|
|
};
|
|
|
|
})
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2015-10-06 22:51:17 +00:00
|
|
|
exports.printErrorMessage = function(message) {
|
2016-01-12 12:31:40 +00:00
|
|
|
console.error(chalk.red(message));
|
2016-01-12 14:44:11 +00:00
|
|
|
return console.error(chalk.red("\n" + messages.getHelp + "\n"));
|
2015-10-06 22:51:17 +00:00
|
|
|
};
|
|
|
|
|
2015-08-20 19:54:42 +00:00
|
|
|
}).call(this);
|