@feathersjs/authentication-local
Version:
Local authentication strategy for @feathers/authentication
114 lines • 5.63 kB
JavaScript
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
;