@unicoderns/cerberus
Version:
Auth secure library
291 lines • 12.9 kB
JavaScript
;
////////////////////////////////////////////////////////////////////////////////////////////
// The MIT License (MIT) //
// //
// Copyright (C) 2016 Unicoderns SA - info@unicoderns.com - unicoderns.com //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy //
// of this software and associated documentation files (the "Software"), to deal //
// in the Software without restriction, including without limitation the rights //
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //
// copies of the Software, and to permit persons to whom the Software is //
// furnished to do so, subject to the following conditions: //
// //
// The above copyright notice and this permission notice shall be included in all //
// copies or substantial portions of the Software. //
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //
// SOFTWARE. //
////////////////////////////////////////////////////////////////////////////////////////////
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bcrypt = __importStar(require("bcryptjs"));
const jwt = __importStar(require("jsonwebtoken"));
const users = __importStar(require("../models/db/usersModel"));
const sessions = __importStar(require("../models/db/sessionsModel"));
const responses_1 = __importDefault(require("../responses/responses"));
let ip = require("ip");
/**
* Sessions Operations
*/
class Sessions {
constructor(config, vault) {
this.emailRegex = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
/**
* Sign JWT token and response.
*
* @param data Session and user ids.
* @return Response
*/
this.sign = (data) => {
const config = this.config;
const token = jwt.sign(data, config.token, {
expiresIn: config.settings.expiration
});
return responses_1.default.TokenCreated(token);
};
/**
* Get auth token.
*
* @param req { Request } The request object.
* @param res { Response } The response object.
* @return json
*/
this.create = (login) => {
let email = login.email;
let password = login.password;
let config = this.config;
let unsafeUsersTable = this.unsafeUsersTable;
let sessionTable = this.sessionsTable;
let sign = this.sign;
// Create promise
const p = new Promise((resolve, reject) => {
if (!this.emailRegex.test(email)) {
reject(responses_1.default.InvalidEmail);
}
else {
unsafeUsersTable.get({
where: { email: email, active: 1 }
}).then((user) => {
if (typeof user === "undefined") {
reject(responses_1.default.WrongUserAndPassword);
}
else {
bcrypt.compare(password, user.password).then(function (match) {
if (match) {
if (config.settings.session == "stateful") {
const temp = {
ip: ip.address(),
user: user.id
};
sessionTable.insert(temp).then((data) => {
resolve(sign({
session: data.insertId,
user: user.id
}));
}).catch(err => {
reject(responses_1.default.SessionCreationProblem);
});
}
else {
resolve(sign(JSON.parse(JSON.stringify(user))));
}
}
else {
reject(responses_1.default.WrongUserAndPassword);
}
});
}
}).catch(err => {
reject(responses_1.default.DBSelectError(err));
});
}
;
});
return p;
};
/**
* Get new auth token.
*
* @param req { Request } The request object.
* @param res { Response } The response object.
* @return json
*/
this.renew = (user) => {
// Clean old data
delete user.iat;
delete user.exp;
return this.sign(user);
};
/**
* Revoke a token for a stateful session.
*
* @param req { Request } The request object.
* @param res { Response } The response object.
* @return json
*/
this.revoke = (user) => {
let vault = this.vault;
let config = this.config;
// Create promise
const p = new Promise((resolve, reject) => {
if (config.settings.session == "stateful") {
this.sessionsTable.delete({ user: user }).then((done) => {
// Remove cached user
vault.removeUser(user);
resolve(responses_1.default.SessionRevoked);
}).catch(err => {
reject(responses_1.default.DBDeleteError(err));
});
}
else {
reject(responses_1.default.StatelessRevokeError);
}
});
return p;
};
/**
* Get context user
*
* @param req {Request} The request object.
* @param res {Response} The response object.
* @param next Callback.
*/
this.get = (token) => {
let vault = this.vault;
let config = this.config;
let sessionsTable = this.sessionsTable;
const p = new Promise((resolve, reject) => {
if (token) {
// Decode token
jwt.verify(token, config.token, function (err, decoded) {
if (err) {
reject(responses_1.default.InvalidToken(err));
}
else {
if (config.settings.session == "stateful") {
sessionsTable.get({
where: {
id: decoded.session,
user: decoded.user
}
}).then((session) => {
if (typeof session === "undefined") {
reject(responses_1.default.SessionNotFound);
}
else {
vault.getUser(decoded.user).then((user) => {
resolve(responses_1.default.GetUser(user));
}).catch(err => {
responses_1.default.VaultError(err);
});
}
}).catch(err => {
reject(responses_1.default.DBSelectError(err));
});
}
else {
resolve(responses_1.default.GetUser(decoded));
}
}
});
}
else {
reject(responses_1.default.NoToken);
}
});
return p;
};
/**
* Force an update context user
*
* @param req {Request} The request object.
* @param res {Response} The response object.
* @param next Callback.
*/
this.getUpdated = (token) => {
let config = this.config;
let vault = this.vault;
const p = new Promise((resolve, reject) => {
// Verifies secret and checks exp
jwt.verify(token, config.token, function (err, decoded) {
if (err) {
reject(responses_1.default.InvalidToken(err));
}
else {
vault.getUser(decoded.user, false).then((user) => {
resolve(responses_1.default.UserUpdated);
}).catch((err) => {
responses_1.default.VaultError(err);
});
}
});
});
return p;
};
/**
* Get all sessions.
*
* @param req { Request } The request object.
* @param res { Response } The response object.
* @return array
*/
this.listAll = () => {
// Create promise
const p = new Promise((resolve, reject) => {
this.sessionsTable.join([{
keyField: this.sessionsTable.user,
fields: ["username", "email", "firstName", "lastName"],
kind: "LEFT"
}]).getAll({}).then((data) => {
resolve(data);
}).catch(err => {
reject(responses_1.default.DBSelectError(err));
});
});
return p;
};
/**
* Get some sessions.
*
* @param req { Request } The request object.
* @param res { Response } The response object.
* @return array
*/
this.listSome = (where) => {
// Create promise
const p = new Promise((resolve, reject) => {
this.sessionsTable.join([{
keyField: this.sessionsTable.user,
fields: ["username", "email", "firstName", "lastName"],
kind: "LEFT"
}]).getSome({ where: where }).then((data) => {
resolve(data);
}).catch(err => {
reject(responses_1.default.DBSelectError(err));
});
});
return p;
};
this.config = config;
this.vault = vault;
this.sessionsTable = new sessions.Sessions(config.DB);
this.unsafeUsersTable = new users.Users(config.DB, "unsafe");
}
}
exports.default = Sessions;
//# sourceMappingURL=sessions.js.map