UNPKG

@experium/nest-bruteforce-guard

Version:
174 lines (173 loc) 7.91 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BruteforceGuardService = void 0; const date_fns_1 = require("date-fns"); const typeorm_1 = require("typeorm"); const escapeStringRegexp = require("escape-string-regexp"); const common_1 = require("@nestjs/common"); const typeorm_2 = require("@nestjs/typeorm"); const login_attempt_entity_1 = require("./entity/login-attempt.entity"); const constants_1 = require("./constants"); const bruteforce_detection_exception_1 = require("./exception/bruteforce-detection.exception"); const exception_catcher_registry_1 = require("./catcher/exception-catcher.registry"); let BruteforceGuardService = class BruteforceGuardService { constructor(repository, config, registry) { this.repository = repository; this.config = config; this.registry = registry; } canLogin(context) { return __awaiter(this, void 0, void 0, function* () { const login = this.getLoginByContext(context); const ip = context.switchToHttp().getRequest().ip; const loginAttemptsCount = yield this.getAttemptsCountByLogin(login); const ipAttemptsCount = yield this.getAttemptsCountByIP(ip); if (login && loginAttemptsCount < this.config.attemptCountByLogin && ipAttemptsCount < this.config.attemptCountByIp) { return true; } yield this.repository.save(new login_attempt_entity_1.LoginAttempt(login, ip, true, true)); throw new bruteforce_detection_exception_1.BruteforceDetectionException(); }); } saveErrorAttempt(context, exception) { return __awaiter(this, void 0, void 0, function* () { const login = this.getLoginByContext(context); const ip = context.switchToHttp().getRequest().ip; let loginAttempt = null; for (const catcher of this.registry.getAll()) { loginAttempt = catcher.handle(exception, context); if (!!loginAttempt) { break; } } if (!loginAttempt) { loginAttempt = new login_attempt_entity_1.LoginAttempt(login, ip, false); } yield this.repository.save(loginAttempt); }); } findByFilter(filter) { return __awaiter(this, void 0, void 0, function* () { return this.repository.createEntityCursor(yield this.getDefaultQuery(filter)); }); } getDefaultQuery(filter) { return __awaiter(this, void 0, void 0, function* () { const query = {}; if ('login' in filter && filter.login) { query.login = { $regex: new RegExp(escapeStringRegexp(filter.login)), $options: 'i', }; } if ('ip' in filter && filter.ip) { query.ip = { $regex: new RegExp(escapeStringRegexp(filter.ip)), $options: 'i', }; } if ('attemptBlocked' in filter && typeof filter.attemptBlocked === 'boolean') { query.attemptBlocked = filter.attemptBlocked; } if ('loginFailure' in filter && typeof filter.loginFailure === 'boolean') { query.loginFailure = filter.loginFailure; } if ('userDisabled' in filter && typeof filter.userDisabled === 'boolean') { query.userDisabled = filter.userDisabled; } if ('badPassword' in filter && typeof filter.badPassword === 'boolean') { query.badPassword = filter.badPassword; } if ('dateFrom' in filter && filter.dateFrom) { query.$and = query.$and || []; query.$and = [ ...query.$and, { date: { $gte: new Date(filter.dateFrom), }, }, ]; } if ('dateTo' in filter && filter.dateTo) { query.$and = query.$and || []; query.$and = [ ...query.$and, { date: { $lte: new Date(filter.dateTo), }, }, ]; } return query; }); } saveSuccessAttempt(context) { return __awaiter(this, void 0, void 0, function* () { const login = this.getLoginByContext(context); const ip = context.switchToHttp().getRequest().ip; yield this.repository.save(new login_attempt_entity_1.LoginAttempt(login, ip)); }); } save(entity) { return __awaiter(this, void 0, void 0, function* () { return yield this.repository.save(entity); }); } getAttemptsCountByLogin(login) { return __awaiter(this, void 0, void 0, function* () { return yield this.repository.count({ login, date: { $gt: date_fns_1.addMinutes(new Date(), -this.config.attemptMinutesByLogin), }, loginFailure: true, }); }); } getAttemptsCountByIP(ip) { return __awaiter(this, void 0, void 0, function* () { return yield this.repository.count({ ip, date: { $gt: date_fns_1.addMinutes(new Date(), -this.config.attemptMinutesByIp), }, loginFailure: true, }); }); } getLoginByContext(context) { const loginField = this.config.loginField; return context.switchToHttp().getRequest().body[loginField]; } }; BruteforceGuardService = __decorate([ __param(0, typeorm_2.InjectRepository(login_attempt_entity_1.LoginAttempt)), __param(1, common_1.Inject(constants_1.BRUTEFORCE_GUARD_OPTIONS_PROVIDER)), __metadata("design:paramtypes", [typeorm_1.MongoRepository, Object, exception_catcher_registry_1.ExceptionCatcherRegistry]) ], BruteforceGuardService); exports.BruteforceGuardService = BruteforceGuardService;