%PDF- %PDF-
Direktori : /proc/thread-self/root/lib/node_modules/pm2/lib/API/pm2-plus/ |
Current File : //proc/thread-self/root/lib/node_modules/pm2/lib/API/pm2-plus/PM2IO.js |
'use strict' var cst = require('../../../constants.js'); const chalk = require('chalk'); const path = require('path'); const fs = require('fs'); const Table = require('cli-tableau'); const pkg = require('../../../package.json') const IOAPI = require('@pm2/js-api') const promptly = require('promptly') var CLIStrategy = require('./auth-strategies/CliAuth') var WebStrategy = require('./auth-strategies/WebAuth') const exec = require('child_process').exec const OAUTH_CLIENT_ID_WEB = '138558311' const OAUTH_CLIENT_ID_CLI = '0943857435' module.exports = class PM2ioHandler { static usePM2Client (instance) { this.pm2 = instance } static strategy () { switch (process.platform) { case 'darwin': { return new WebStrategy({ client_id: OAUTH_CLIENT_ID_WEB }) } case 'win32': { return new WebStrategy({ client_id: OAUTH_CLIENT_ID_WEB }) } case 'linux': { const isDesktop = process.env.XDG_CURRENT_DESKTOP || process.env.XDG_SESSION_DESKTOP || process.env.DISPLAY const isSSH = process.env.SSH_TTY || process.env.SSH_CONNECTION if (isDesktop && !isSSH) { return new WebStrategy({ client_id: OAUTH_CLIENT_ID_WEB }) } else { return new CLIStrategy({ client_id: OAUTH_CLIENT_ID_CLI }) } } default: { return new CLIStrategy({ client_id: OAUTH_CLIENT_ID_CLI }) } } } static init () { this._strategy = this.strategy() /** * If you are using a local backend you should give those options : * { * services: { * API: 'http://localhost:3000', * OAUTH: 'http://localhost:3100' * } * } */ this.io = new IOAPI().use(this._strategy) } static launch (command, opts) { // first init the strategy and the io client this.init() switch (command) { case 'connect' : case 'login' : case 'register' : case undefined : case 'authenticate' : { this.authenticate() break } case 'validate' : { this.validateAccount(opts) break } case 'help' : case 'welcome': { var dt = fs.readFileSync(path.join(__dirname, './pres/welcome')); console.log(dt.toString()); return process.exit(0) } case 'logout': { this._strategy.isAuthenticated().then(isConnected => { // try to kill the agent anyway this.pm2.killAgent(err => {}) if (isConnected === false) { console.log(`${cst.PM2_IO_MSG} Already disconnected`) return process.exit(0) } this._strategy._retrieveTokens((err, tokens) => { if (err) { console.log(`${cst.PM2_IO_MSG} Successfully disconnected`) return process.exit(0) } this._strategy.deleteTokens(this.io).then(_ => { console.log(`${cst.PM2_IO_MSG} Successfully disconnected`) return process.exit(0) }).catch(err => { console.log(`${cst.PM2_IO_MSG_ERR} Unexpected error: ${err.message}`) return process.exit(1) }) }) }).catch(err => { console.error(`${cst.PM2_IO_MSG_ERR} Failed to logout: ${err.message}`) console.error(`${cst.PM2_IO_MSG_ERR} You can also contact us to get help: contact@pm2.io`) }) break } case 'create': { this._strategy.isAuthenticated().then(res => { // if the user isn't authenticated, we make them do the whole flow if (res !== true) { this.authenticate() } else { this.createBucket(this.createBucketHandler.bind(this)) } }).catch(err => { console.error(`${cst.PM2_IO_MSG_ERR} Failed to create to the bucket: ${err.message}`) console.error(`${cst.PM2_IO_MSG_ERR} You can also contact us to get help: contact@pm2.io`) }) break } case 'web': { this._strategy.isAuthenticated().then(res => { // if the user isn't authenticated, we make them do the whole flow if (res === false) { console.error(`${cst.PM2_IO_MSG_ERR} You need to be authenticated to do that, please use: pm2 plus login`) return process.exit(1) } this._strategy._retrieveTokens(() => { return this.openUI() }) }).catch(err => { console.error(`${cst.PM2_IO_MSG_ERR} Failed to open the UI: ${err.message}`) console.error(`${cst.PM2_IO_MSG_ERR} You can also contact us to get help: contact@pm2.io`) }) break } default : { console.log(`${cst.PM2_IO_MSG_ERR} Invalid command ${command}, available : login,register,validate,connect or web`) process.exit(1) } } } static openUI () { this.io.bucket.retrieveAll().then(res => { const buckets = res.data if (buckets.length === 0) { return this.createBucket((err, bucket) => { if (err) { console.error(`${cst.PM2_IO_MSG_ERR} Failed to connect to the bucket: ${err.message}`) if (bucket) { console.error(`${cst.PM2_IO_MSG_ERR} You can retry using: pm2 plus link ${bucket.secret_id} ${bucket.public_id}`) } console.error(`${cst.PM2_IO_MSG_ERR} You can also contact us to get help: contact@pm2.io`) return process.exit(0) } const targetURL = `https://app.pm2.io/#/bucket/${bucket._id}` console.log(`${cst.PM2_IO_MSG} Please follow the popup or go to this URL :`, '\n', ' ', targetURL) this.open(targetURL) return process.exit(0) }) } var table = new Table({ style : {'padding-left' : 1, head : ['cyan', 'bold'], compact : true}, head : ['Bucket name', 'Plan type'] }) buckets.forEach(function(bucket) { table.push([bucket.name, bucket.credits.offer_type]) }) console.log(table.toString()) console.log(`${cst.PM2_IO_MSG} If you don't want to open the UI to a bucket, type 'none'`) const choices = buckets.map(bucket => bucket.name) choices.push('none') promptly.choose(`${cst.PM2_IO_MSG} Type the name of the bucket you want to connect to :`, choices, (err, value) => { if (value === 'none') process.exit(0) const bucket = buckets.find(bucket => bucket.name === value) if (bucket === undefined) return process.exit(0) const targetURL = `https://app.pm2.io/#/bucket/${bucket._id}` console.log(`${cst.PM2_IO_MSG} Please follow the popup or go to this URL :`, '\n', ' ', targetURL) this.open(targetURL) return process.exit(0) }) }) } static validateAccount (token) { this.io.auth.validEmail(token) .then(res => { console.log(`${cst.PM2_IO_MSG} Email succesfully validated.`) console.log(`${cst.PM2_IO_MSG} You can now proceed and use: pm2 plus connect`) return process.exit(0) }).catch(err => { if (err.status === 401) { console.error(`${cst.PM2_IO_MSG_ERR} Invalid token`) return process.exit(1) } else if (err.status === 301) { console.log(`${cst.PM2_IO_MSG} Email succesfully validated.`) console.log(`${cst.PM2_IO_MSG} You can now proceed and use: pm2 plus connect`) return process.exit(0) } const msg = err.data ? err.data.error_description || err.data.msg : err.message console.error(`${cst.PM2_IO_MSG_ERR} Failed to validate your email: ${msg}`) console.error(`${cst.PM2_IO_MSG_ERR} You can also contact us to get help: contact@pm2.io`) return process.exit(1) }) } static createBucketHandler (err, bucket) { if (err) { console.trace(`${cst.PM2_IO_MSG_ERR} Failed to connect to the bucket: ${err.message}`) if (bucket) { console.error(`${cst.PM2_IO_MSG_ERR} You can retry using: pm2 plus link ${bucket.secret_id} ${bucket.public_id}`) } console.error(`${cst.PM2_IO_MSG_ERR} You can also contact us to get help: contact@pm2.io`) return process.exit(0) } if (bucket === undefined) { return process.exit(0) } console.log(`${cst.PM2_IO_MSG} Successfully connected to bucket ${bucket.name}`) var targetURL = `https://app.pm2.io/#/bucket/${bucket._id}` console.log(`${cst.PM2_IO_MSG} You can use the web interface over there: ${targetURL}`) this.open(targetURL) return process.exit(0) } static createBucket (cb) { console.log(`${cst.PM2_IO_MSG} By default we allow you to trial PM2 Plus for 14 days without any credit card.`) this.io.bucket.create({ name: 'PM2 Plus Monitoring' }).then(res => { const bucket = res.data.bucket console.log(`${cst.PM2_IO_MSG} Successfully created the bucket`) this.pm2.link({ public_key: bucket.public_id, secret_key: bucket.secret_id, pm2_version: pkg.version }, (err) => { if (err) { return cb(new Error('Failed to connect your local PM2 to your bucket'), bucket) } else { return cb(null, bucket) } }) }).catch(err => { return cb(new Error(`Failed to create a bucket: ${err.message}`)) }) } /** * Connect the local agent to a specific bucket * @param {Function} cb */ static connectToBucket (cb) { this.io.bucket.retrieveAll().then(res => { const buckets = res.data if (buckets.length === 0) { return this.createBucket(cb) } var table = new Table({ style : {'padding-left' : 1, head : ['cyan', 'bold'], compact : true}, head : ['Bucket name', 'Plan type'] }) buckets.forEach(function(bucket) { table.push([bucket.name, bucket.payment.offer_type]) }) console.log(table.toString()) console.log(`${cst.PM2_IO_MSG} If you don't want to connect to a bucket, type 'none'`) const choices = buckets.map(bucket => bucket.name) choices.push('none') promptly.choose(`${cst.PM2_IO_MSG} Type the name of the bucket you want to connect to :`, choices, (err, value) => { if (value === 'none') return cb() const bucket = buckets.find(bucket => bucket.name === value) if (bucket === undefined) return cb() this.pm2.link({ public_key: bucket.public_id, secret_key: bucket.secret_id, pm2_version: pkg.version }, (err) => { return err ? cb(err) : cb(null, bucket) }) }) }) } /** * Authenticate the user with either of the strategy * @param {Function} cb */ static authenticate () { this._strategy._retrieveTokens((err, tokens) => { if (err) { const msg = err.data ? err.data.error_description || err.data.msg : err.message console.log(`${cst.PM2_IO_MSG_ERR} Unexpected error : ${msg}`) return process.exit(1) } console.log(`${cst.PM2_IO_MSG} Successfully authenticated`) this.io.user.retrieve().then(res => { const user = res.data this.io.user.retrieve().then(res => { const tmpUser = res.data console.log(`${cst.PM2_IO_MSG} Successfully validated`) this.connectToBucket(this.createBucketHandler.bind(this)) }) }) }) } static open (target, appName, callback) { let opener const escape = function (s) { return s.replace(/"/g, '\\"') } if (typeof (appName) === 'function') { callback = appName appName = null } switch (process.platform) { case 'darwin': { opener = appName ? `open -a "${escape(appName)}"` : `open` break } case 'win32': { opener = appName ? `start "" ${escape(appName)}"` : `start ""` break } default: { opener = appName ? escape(appName) : `xdg-open` break } } if (process.env.SUDO_USER) { opener = 'sudo -u ' + process.env.SUDO_USER + ' ' + opener } return exec(`${opener} "${escape(target)}"`, callback) } }