feat: Logins log for Fail2Ban (#986)

* login logs and output

* fix(merge)

* fix(wiston) unistall

* fix(winston) installation in api

* fix(logger) new module
This commit is contained in:
Marco Beretta 2023-09-24 18:18:10 +02:00 committed by GitHub
parent 7c0379ba51
commit 1bf6c259b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 198 additions and 27 deletions

View file

@ -61,6 +61,7 @@
"sharp": "^0.32.5",
"tiktoken": "^1.0.10",
"ua-parser-js": "^1.0.36",
"winston": "^3.10.0",
"zod": "^3.22.2"
},
"devDependencies": {

View file

@ -1,7 +1,7 @@
const { Strategy: PassportLocalStrategy } = require('passport-local');
const User = require('../models/User');
const { loginSchema, errorsToString } = require('./validators');
const DebugControl = require('../utils/debug.js');
const logger = require('../utils/logger');
async function validateLoginRequest(req) {
const { error } = loginSchema.safeParse(req.body);
@ -28,21 +28,25 @@ async function passportLogin(req, email, password, done) {
const validationError = await validateLoginRequest(req);
if (validationError) {
logError('Passport Local Strategy - Validation Error', { reqBody: req.body });
logger.error(`[Login] [Login failed] [Username: ${email}] [Request-IP: ${req.ip}]`);
return done(null, false, { message: validationError });
}
const user = await findUserByEmail(email);
if (!user) {
logError('Passport Local Strategy - User Not Found', { email });
logger.error(`[Login] [Login failed] [Username: ${email}] [Request-IP: ${req.ip}]`);
return done(null, false, { message: 'Email does not exist.' });
}
const isMatch = await comparePassword(user, password);
if (!isMatch) {
logError('Passport Local Strategy - Password does not match', { isMatch });
logger.error(`[Login] [Login failed] [Username: ${email}] [Request-IP: ${req.ip}]`);
return done(null, false, { message: 'Incorrect password.' });
}
logger.info(`[Login] [Login successful] [Username: ${email}] [Request-IP: ${req.ip}]`);
return done(null, user);
} catch (err) {
return done(err);
@ -51,10 +55,7 @@ async function passportLogin(req, email, password, done) {
function logError(title, parameters) {
const entries = Object.entries(parameters).map(([name, value]) => ({ name, value }));
DebugControl.log.functionName(title);
if (entries) {
DebugControl.log.parameters(entries);
}
logger.error(title, { parameters: entries });
}
module.exports = () =>

View file

@ -1,23 +1,4 @@
const pino = require('pino');
const logger = pino({
level: 'info',
redact: {
paths: [
// List of Paths to redact from the logs (https://getpino.io/#/docs/redaction)
'env.OPENAI_API_KEY',
'env.BINGAI_TOKEN',
'env.CHATGPT_TOKEN',
'env.MEILI_MASTER_KEY',
'env.GOOGLE_CLIENT_SECRET',
'env.JWT_SECRET',
'env.JWT_SECRET_DEV',
'env.JWT_SECRET_PROD',
'newUser.password',
], // See example to filter object class instances
censor: '***', // Redaction character
},
});
const logger = require('./logger');
// Sanitize outside the logger paths. This is useful for sanitizing variables directly with Regex and patterns.
const redactPatterns = [

12
api/utils/logger.js Normal file
View file

@ -0,0 +1,12 @@
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'login-logs.log' }),
],
});
module.exports = logger;