UNPKG

@feathersjs/authentication-local

Version:

Local authentication strategy for @feathers/authentication

114 lines 5.63 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LocalStrategy = void 0; const bcryptjs_1 = __importDefault(require("bcryptjs")); const get_1 = __importDefault(require("lodash/get")); const omit_1 = __importDefault(require("lodash/omit")); const debug_1 = __importDefault(require("debug")); const errors_1 = require("@feathersjs/errors"); const authentication_1 = require("@feathersjs/authentication"); const debug = debug_1.default('@feathersjs/authentication-local/strategy'); class LocalStrategy extends authentication_1.AuthenticationBaseStrategy { verifyConfiguration() { const config = this.configuration; ['usernameField', 'passwordField'].forEach(prop => { if (typeof config[prop] !== 'string') { throw new Error(`'${this.name}' authentication strategy requires a '${prop}' setting`); } }); } get configuration() { const authConfig = this.authentication.configuration; const config = super.configuration || {}; return Object.assign({ hashSize: 10, service: authConfig.service, entity: authConfig.entity, entityId: authConfig.entityId, errorMessage: 'Invalid login', entityPasswordField: config.passwordField, entityUsernameField: config.usernameField }, config); } getEntityQuery(query, _params) { return __awaiter(this, void 0, void 0, function* () { return Object.assign({ $limit: 1 }, query); }); } findEntity(username, params) { return __awaiter(this, void 0, void 0, function* () { const { entityUsernameField, errorMessage } = this.configuration; if (!username) { // don't query for users without any condition set. throw new errors_1.NotAuthenticated(errorMessage); } const query = yield this.getEntityQuery({ [entityUsernameField]: username }, params); const findParams = Object.assign({}, params, { query }); const entityService = this.entityService; debug('Finding entity with query', params.query); const result = yield entityService.find(findParams); const list = Array.isArray(result) ? result : result.data; if (!Array.isArray(list) || list.length === 0) { debug(`No entity found`); throw new errors_1.NotAuthenticated(errorMessage); } const [entity] = list; return entity; }); } getEntity(result, params) { return __awaiter(this, void 0, void 0, function* () { const entityService = this.entityService; const { entityId = entityService.id, entity } = this.configuration; if (!entityId || result[entityId] === undefined) { throw new errors_1.NotAuthenticated('Could not get local entity'); } if (!params.provider) { return result; } return entityService.get(result[entityId], Object.assign(Object.assign({}, params), { [entity]: result })); }); } comparePassword(entity, password) { return __awaiter(this, void 0, void 0, function* () { const { entityPasswordField, errorMessage } = this.configuration; // find password in entity, this allows for dot notation const hash = get_1.default(entity, entityPasswordField); if (!hash) { debug(`Record is missing the '${entityPasswordField}' password field`); throw new errors_1.NotAuthenticated(errorMessage); } debug('Verifying password'); const result = yield bcryptjs_1.default.compare(password, hash); if (result) { return entity; } throw new errors_1.NotAuthenticated(errorMessage); }); } hashPassword(password, _params) { return __awaiter(this, void 0, void 0, function* () { return bcryptjs_1.default.hash(password, this.configuration.hashSize); }); } authenticate(data, params) { return __awaiter(this, void 0, void 0, function* () { const { passwordField, usernameField, entity } = this.configuration; const username = data[usernameField]; const password = data[passwordField]; const result = yield this.findEntity(username, omit_1.default(params, 'provider')); yield this.comparePassword(result, password); return { authentication: { strategy: this.name }, [entity]: yield this.getEntity(result, params) }; }); } } exports.LocalStrategy = LocalStrategy; //# sourceMappingURL=strategy.js.map