329 lines
10 KiB
JavaScript
329 lines
10 KiB
JavaScript
var prompt = require('prompt'),
|
|
fs = require('fs'),
|
|
path = require('path'),
|
|
api = require('./api'),
|
|
util = require('util'),
|
|
chalk = require('chalk'),
|
|
_when = require('when');
|
|
|
|
var auth = {
|
|
configFile: path.join(
|
|
(process.env.HOME || process.env.USERPROFILE),
|
|
'.firebaserc'
|
|
),
|
|
maxRetries: 3,
|
|
requireLogin: function(argv, callback) {
|
|
var that = this;
|
|
|
|
if (argv.email && argv.password) {
|
|
this._attemptLogin(argv, this.maxRetries, callback);
|
|
} else if ((this.email.length === 0) || (this.token.length === 0)) {
|
|
console.log('Please sign into your Firebase account to continue...');
|
|
this._attemptLogin(argv, this.maxRetries, callback);
|
|
} else {
|
|
this._validate(function(err) {
|
|
if (err) {
|
|
console.log('Please sign into your Firebase account to continue...');
|
|
that._attemptLogin(argv, that.maxRetries, callback);
|
|
} else {
|
|
setTimeout(callback, 0, null, that.email, that.token);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
_validate: function(callback) {
|
|
api.request(
|
|
'GET',
|
|
'/token/validate',
|
|
{
|
|
cli: require('./firebase').version
|
|
},
|
|
true,
|
|
function(statusCode, response) {
|
|
if (typeof(callback) === 'function') {
|
|
if (typeof(response.error) !== 'undefined') {
|
|
console.log(chalk.red(response.error.message) + ' - Please update to at ' +
|
|
'least v' + response.minCLI + ' by running ' +
|
|
chalk.cyan('npm update -g ' + require('./firebase').name));
|
|
process.exit(1);
|
|
} else if (response.valid) {
|
|
setTimeout(callback, 0, null);
|
|
} else {
|
|
setTimeout(callback, 0, new Error('Invalid Access Token'));
|
|
}
|
|
}
|
|
}
|
|
);
|
|
},
|
|
login: function(argv, callback) {
|
|
this._attemptLogin(argv, this.maxRetries, callback);
|
|
},
|
|
_attemptLogin: function(argv, tries, callback) {
|
|
var that = this;
|
|
if (tries > 0) {
|
|
if (tries !== this.maxRetries) {
|
|
if (argv.silent) {
|
|
console.log(chalk.red('Input Error') + ' - Email or password incorrect');
|
|
process.exit(1);
|
|
}
|
|
console.log('Email or password incorrect, please try again');
|
|
delete prompt.override.email;
|
|
delete prompt.override.password;
|
|
}
|
|
this._loginRequest(argv, function(err, email, token) {
|
|
if (err) {
|
|
that._attemptLogin(argv, tries - 1, callback);
|
|
} else {
|
|
setTimeout(callback, 0, null, email, token);
|
|
}
|
|
});
|
|
} else {
|
|
console.log(chalk.red('Login Unsuccessful'));
|
|
process.exit(1);
|
|
}
|
|
},
|
|
_loginRequest: function(argv, callback) {
|
|
var that = this,
|
|
schema = [
|
|
{
|
|
name: 'email',
|
|
description: 'Email:',
|
|
pattern: /@/,
|
|
message: 'Must be a valid email address',
|
|
required: true,
|
|
type: 'string'
|
|
},{
|
|
name: 'password',
|
|
description: 'Password:',
|
|
hidden: true,
|
|
required: true,
|
|
type: 'string'
|
|
}
|
|
];
|
|
|
|
if (this.email.length > 0) {
|
|
schema[0].default = this.email;
|
|
}
|
|
|
|
if (argv.silent) {
|
|
for (var i in schema) {
|
|
var item = schema[i];
|
|
if (!prompt.override[item.name] || (item.pattern && !item.pattern.test(prompt.override[item.name]))) {
|
|
console.log(chalk.red('Input Error') + ' - Not enough or invalid parameters specified while in silent mode');
|
|
console.log('Required ' + chalk.bold(item.name) + ' parameter missing or invalid');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
prompt.get(schema, function(err, result) {
|
|
if (err) {
|
|
if (typeof(callback) === 'function') {
|
|
setTimeout(callback, 0, new Error('Error Getting User Input'));
|
|
}
|
|
return;
|
|
}
|
|
that.email = result.email;
|
|
that._authenticate.bind(that)(result.email, result.password, callback);
|
|
});
|
|
},
|
|
_authenticate: function(email, password, callback) {
|
|
var data = {
|
|
email: email,
|
|
password: password,
|
|
rememberMe: true,
|
|
cli: require('./firebase').version
|
|
};
|
|
api.request(
|
|
'GET',
|
|
'/account/login',
|
|
data,
|
|
false,
|
|
this._handleLogin.bind(this, callback)
|
|
);
|
|
},
|
|
_handleLogin: function(callback, statusCode, response) {
|
|
var token = response.adminToken;
|
|
if (token) {
|
|
this.token = token;
|
|
this.saveConfig(callback);
|
|
} else if (typeof(response.error) !== 'undefined') {
|
|
if (typeof(response.minCLI) === 'undefined') {
|
|
if (typeof(callback) === 'function') {
|
|
setTimeout(callback, 0, new Error('Email or Password Invalid'));
|
|
}
|
|
} else {
|
|
console.log(chalk.red(response.error.message) + ' - Please update to at ' +
|
|
'least v' + response.minCLI + ' by running ' +
|
|
chalk.cyan('npm update -g ' + require('./firebase').name));
|
|
process.exit(1);
|
|
}
|
|
}
|
|
},
|
|
saveConfig: function(callback) {
|
|
var data = {
|
|
email: this.email,
|
|
token: this.token
|
|
};
|
|
var dataString = JSON.stringify(data, null, 2) + '\n';
|
|
try {
|
|
fs.writeFileSync(this.configFile, dataString);
|
|
} catch (err) {
|
|
if (typeof(callback) === 'function') {
|
|
setTimeout(callback, 0, new Error('Could Not Save Settings'));
|
|
}
|
|
return;
|
|
}
|
|
if (typeof(callback) === 'function') {
|
|
setTimeout(callback, 0, null, this.email, this.token);
|
|
}
|
|
},
|
|
logout: function(deleteSettings, callback) {
|
|
var that = this;
|
|
this._invalidateToken(function(err) {
|
|
if (err) {
|
|
setTimeout(callback, 0, err);
|
|
}
|
|
if (deleteSettings) {
|
|
try {
|
|
fs.unlinkSync(that.configFile);
|
|
} catch (e) {
|
|
setTimeout(callback, 0, e);
|
|
return;
|
|
}
|
|
setTimeout(callback, 0, null);
|
|
} else {
|
|
that.token = '';
|
|
that.saveConfig(callback);
|
|
}
|
|
});
|
|
},
|
|
_invalidateToken: function(callback) {
|
|
if (this.token.length > 0) {
|
|
var url = '/account/token';
|
|
api.request('DELETE', url, {}, true, function(statusCode, response) {
|
|
setTimeout(callback, 0, null);
|
|
});
|
|
} else {
|
|
if (typeof(callback) === 'function') {
|
|
setTimeout(callback, 0, null);
|
|
}
|
|
}
|
|
},
|
|
checkCanAccess: function(firebase, callback) {
|
|
var url = '/firebase/' + firebase + '/token';
|
|
api.request('GET', url, {}, true, function(statusCode, response) {
|
|
if (!response.error) {
|
|
setTimeout(callback, 0, null, response);
|
|
} else {
|
|
setTimeout(callback, 0, new Error('Permission Denied'));
|
|
}
|
|
});
|
|
},
|
|
updateRules: function(firebase, authToken, rules, callback) {
|
|
var rulesString;
|
|
if (rules) {
|
|
if (!fs.existsSync(rules)) {
|
|
console.log(chalk.red('Security Rules Error') + ' - specified security' +
|
|
' rules file does not exist');
|
|
process.exit(1);
|
|
}
|
|
try {
|
|
rulesString = fs.readFileSync(rules, 'utf8');
|
|
} catch (err) {
|
|
console.log(chalk.red('Security Rules Error') + ' - couldn\'t read security ' +
|
|
'rules');
|
|
process.exit(1);
|
|
}
|
|
if (rulesString.length === 0) {
|
|
console.log(chalk.red('Security Rules Error') + ' - couldn\'t read security ' +
|
|
'rules');
|
|
process.exit(1);
|
|
}
|
|
console.log('Updating security rules...');
|
|
api.setRules(firebase, rulesString, authToken, callback);
|
|
} else {
|
|
setTimeout(callback, 0, 200, {});
|
|
}
|
|
},
|
|
getFirebases: function(callback) {
|
|
api.request('GET', '/account', {}, true, function(statusCode, response) {
|
|
if (typeof(response.firebases) !== 'undefined') {
|
|
var firebases = [];
|
|
for (var firebase in response.firebases) {
|
|
if (response.firebases.hasOwnProperty(firebase)) {
|
|
firebases.push(firebase);
|
|
}
|
|
}
|
|
if (typeof(callback) !== 'undefined') {
|
|
setTimeout(callback, 0, null, firebases);
|
|
}
|
|
} else {
|
|
if (typeof(callback) !== 'undefined') {
|
|
setTimeout(callback, 0, new Error('Could not get list of Firebases'));
|
|
}
|
|
}
|
|
});
|
|
},
|
|
getConfig: function() {
|
|
var config = {};
|
|
var data = fs.readFileSync(this.configFile, 'utf8');
|
|
try {
|
|
config = JSON.parse(data);
|
|
} catch (e) {}
|
|
return config;
|
|
},
|
|
listFirebases: function(argv) {
|
|
return _when.promise(function(resolve, reject, notify) {
|
|
auth.requireLogin(argv, function(err) {
|
|
if (err) {
|
|
var error = new Error('Login Unsuccessful');
|
|
error.type = 'LOGIN';
|
|
reject(error);
|
|
} else {
|
|
auth.getFirebases(function(err, firebases) {
|
|
if (err) {
|
|
var error = new Error('Could Not List Firebases');
|
|
error.type = 'ACCOUNT';
|
|
reject(error);
|
|
} else {
|
|
resolve({
|
|
firebases: firebases,
|
|
showFirebases: function() {
|
|
console.log(chalk.yellow('----------------------------------------------------'));
|
|
console.log(chalk.yellow(util.format('Your Firebase Apps %s', auth.email)));
|
|
console.log(chalk.yellow('----------------------------------------------------'));
|
|
console.log(firebases.join('\n'));
|
|
console.log(chalk.yellow('----------------------------------------------------'));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
function initAuth() {
|
|
try {
|
|
var config = auth.getConfig();
|
|
if (typeof(config.token) === 'string') {
|
|
auth.token = config.token;
|
|
} else {
|
|
auth.token = '';
|
|
}
|
|
if (typeof(config.email) === 'string') {
|
|
auth.email = config.email;
|
|
} else {
|
|
auth.email = '';
|
|
}
|
|
} catch (err) {
|
|
auth.token = '';
|
|
auth.email = '';
|
|
}
|
|
}
|
|
|
|
initAuth();
|
|
|
|
module.exports = auth;
|