Files
discord.js/lib/Util/TokenCacher.js
2016-08-05 08:11:45 +09:00

158 lines
4.9 KiB
JavaScript

"use strict";
/* global process */
exports.__esModule = true;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _fs = require("fs");
var _fs2 = _interopRequireDefault(_fs);
var _events = require("events");
var _events2 = _interopRequireDefault(_events);
var _crypto = require("crypto");
var _crypto2 = _interopRequireDefault(_crypto);
var savePaths = [process.env.APPDATA || (process.platform == "darwin" ? process.env.HOME + "Library/Preferences" : "/var/local"), process.env[process.platform == "win32" ? "USERPROFILE" : "HOME"], process.cwd(), "/tmp"];
var algo = "aes-256-ctr";
function secureEmail(email, password) {
return new Buffer(_crypto2["default"].createHash("sha256").update(email + password, "utf8").digest()).toString("hex");
}
function exists(path) {
// Node deprecated the `fs.exists` method apparently...
try {
_fs2["default"].accessSync(path);
return true;
} catch (e) {
return false;
}
}
var TokenCacher = (function (_EventEmitter) {
_inherits(TokenCacher, _EventEmitter);
function TokenCacher(client, options) {
_classCallCheck(this, TokenCacher);
_EventEmitter.call(this);
this.client = client;
this.savePath = null;
this.error = false;
this.done = false;
this.data = {};
}
TokenCacher.prototype.setToken = function setToken() {
var email = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0];
var password = arguments.length <= 1 || arguments[1] === undefined ? "" : arguments[1];
var token = arguments.length <= 2 || arguments[2] === undefined ? "" : arguments[2];
email = secureEmail(email, password);
var cipher = _crypto2["default"].createCipher(algo, password);
var crypted = cipher.update("valid" + token, "utf8", "hex");
crypted += cipher.final("hex");
this.data[email] = crypted;
this.save();
};
TokenCacher.prototype.save = function save() {
_fs2["default"].writeFile(this.savePath, JSON.stringify(this.data));
};
TokenCacher.prototype.getToken = function getToken() {
var email = arguments.length <= 0 || arguments[0] === undefined ? "" : arguments[0];
var password = arguments.length <= 1 || arguments[1] === undefined ? "" : arguments[1];
email = secureEmail(email, password);
if (this.data[email]) {
try {
var decipher = _crypto2["default"].createDecipher(algo, password);
var dec = decipher.update(this.data[email], "hex", "utf8");
dec += decipher.final("utf8");
return dec.indexOf("valid") === 0 ? dec.substr(5) : false;
} catch (e) {
// not a valid token
return null;
}
} else {
return null;
}
};
TokenCacher.prototype.init = function init(ind) {
var _this = this;
var self = this;
var savePath = savePaths[ind];
// Use one async function at the beginning, so the entire function is async,
// then later use only sync functions to increase readability
_fs2["default"].stat(savePath, function (err, dirStats) {
// Directory does not exist.
if (err) error(err);else {
try {
var storeDirPath = savePath + "/.discordjs";
var filePath = storeDirPath + "/tokens.json";
if (!exists(storeDirPath)) {
// First, make sure the directory exists, otherwise the next
// call will fail.
_fs2["default"].mkdirSync(storeDirPath);
}
if (!exists(filePath)) {
// This will create an empty file if the file doesn't exist, and error
// if it does exist. We previously checked that it doesn't exist so we
// can do this safely.
_fs2["default"].closeSync(_fs2["default"].openSync(filePath, 'wx'));
}
var data = _fs2["default"].readFileSync(filePath);
try {
_this.data = JSON.parse(data);
_this.savePath = filePath;
_this.emit('ready');
_this.done = true;
} catch (e) {
// not valid JSON, make it valid and then write
_fs2["default"].writeFileSync(filePath, '{}');
_this.savePath = filePath;
_this.emit("ready");
_this.done = true;
}
} catch (e) {
error(e);
}
}
});
function error(e) {
ind++;
if (!savePaths[ind]) {
self.emit("error");
self.error = e;
self.done = true;
} else {
self.init(ind);
}
}
};
return TokenCacher;
})(_events2["default"]);
exports["default"] = TokenCacher;
module.exports = exports["default"];