@greenpress/auth
Version:
Express Passport authentication service
164 lines (163 loc) • 5.83 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mongoose_1 = __importDefault(require("mongoose"));
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
const bcryptjs_1 = __importDefault(require("bcryptjs"));
const config = __importStar(require("../../config"));
const tokens_1 = require("../services/tokens");
// define the User model schema
const UserSchema = new mongoose_1.default.Schema({
tenant: {
type: String,
index: true,
default: '0',
},
email: {
type: String,
required: true,
},
password: String,
name: String,
salt: String,
roles: {
type: [String],
validate(roles) {
const notValidRole = roles.find((role) => !config.roles.includes(role));
if (notValidRole) {
return Promise.reject({
message: 'role not valid',
role: notValidRole,
});
}
return Promise.resolve();
},
},
tokens: [
{
kind: {
type: String,
enum: ['cookie', 'oauth'],
default: config.defaultAuthType,
},
metadata: {
type: mongoose_1.default.Schema.Types.Mixed,
default: () => ({}),
},
tokenIdentifier: String,
},
],
created: {
type: Date,
default: Date.now,
},
});
UserSchema.index({ tenant: 1, email: 1 }, { unique: true });
/**
* Compare the passed password with the value in the database. A model method.
*
* @param {string} password
* @param {function} callback
* @returns {object} callback
*/
UserSchema.methods.comparePassword = function comparePassword(password, callback) {
bcryptjs_1.default.compare(password, this.password, callback);
};
UserSchema.methods.getToken = function getToken(authType, expiresIn) {
let tokenIdentifier;
if (authType === 'cookie') {
tokenIdentifier = (0, tokens_1.getUniqueId)();
this.tokens.push({
kind: authType,
tokenIdentifier,
});
}
return (0, tokens_1.getSignedToken)(this, tokenIdentifier, expiresIn).token;
};
UserSchema.methods.getRefreshToken = function getRefreshToken(relatedToken) {
const tokenIdentifier = (0, tokens_1.getUniqueId)();
this.tokens.push({
kind: 'oauth',
tokenIdentifier,
metadata: { relatedToken },
});
return jsonwebtoken_1.default.sign({
sub: this._id,
tenant: this.tenant,
tokenIdentifier,
}, config.refreshTokenSecret, { expiresIn: config.refreshTokenExpiration });
};
UserSchema.methods.updateToken = function updateToken(authType, currentIdentifier, newIdentifier, relatedToken) {
this.tokens = this.tokens.filter((token) => !(token.kind === authType && token.tokenIdentifier === currentIdentifier));
const token = { kind: authType, tokenIdentifier: newIdentifier };
if (relatedToken) {
token.metadata = { relatedToken };
}
this.tokens.push(token);
return this.save();
};
UserSchema.methods.deleteToken = function deleteToken(authType, tokenIdentifier) {
this.tokens = this.tokens.filter((token) => token.kind === authType && token.tokenIdentifier === tokenIdentifier);
return this.save();
};
UserSchema.methods.getTokenByRelatedTokens = function getTokenByRelatedTokens(authType, tokenIdentifier) {
const token = this.tokens.find((token) => token.kind === authType &&
token.metadata.toString().includes(tokenIdentifier));
return token ? token.tokenIdentifier : tokenIdentifier;
};
/**
* The pre-save hook method.
*/
UserSchema.pre('save', function saveHook(next) {
const user = this;
// define role for new user
if (!user.roles || user.roles.length === 0) {
user.roles = [config.defaultRole];
}
if (!this.salt) {
this.salt = bcryptjs_1.default.genSaltSync();
}
// proceed further only if the password is modified or the user is new
if (!user.isModified('password'))
return next();
return bcryptjs_1.default.genSalt((saltError, salt) => {
if (saltError) {
return next(saltError);
}
return bcryptjs_1.default.hash(user.password, salt, (hashError, hash) => {
if (hashError) {
return next(hashError);
}
// replace a password string with hash value
user.password = hash;
return next();
});
});
});
const User = mongoose_1.default.model('User', UserSchema);
exports.default = User;