UNPKG

@greenpress/auth

Version:

Express Passport authentication service

164 lines (163 loc) 5.83 kB
"use strict"; 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;