153 lines
4.8 KiB
TypeScript
153 lines
4.8 KiB
TypeScript
import { validationResult } from 'express-validator';
|
|
import { SecurityManager } from '../managers/SecurityManager';
|
|
import { CryptoService } from '../services/CryptoService';
|
|
import { TemporalTokenMongoManager } from '../db/mongo/TemporalTokenMongoManager';
|
|
import { BaseController } from './BaseController';
|
|
import { MailerService } from '../services/mailer/MailerService';
|
|
import { NamespacesService } from '../services/NamespacesService';
|
|
import { UsersService } from '../services/UsersService';
|
|
import { Request, Response } from 'express';
|
|
|
|
export class UserController extends BaseController {
|
|
security = new SecurityManager();
|
|
temporalTokenManager = new TemporalTokenMongoManager();
|
|
usersService = new UsersService();
|
|
mailService = new MailerService();
|
|
cryptoService = new CryptoService();
|
|
namespacesService = new NamespacesService();
|
|
|
|
constructor() {
|
|
super();
|
|
}
|
|
|
|
async getNamespaces(req: Request, res: Response) {
|
|
return await this.namespacesService.getNamespaces();
|
|
}
|
|
|
|
async getUser(req: Request, res: Response) {
|
|
try {
|
|
const { id } = req.params;
|
|
const user = await this.usersService.getById(id);
|
|
res.json(user).status(200).end();
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async createUser(req: Request, res: Response) {
|
|
const user = req.body;
|
|
try {
|
|
const validation = validationResult(req);
|
|
if (!validation.isEmpty()) {
|
|
res.status(400).json({ errors: validation.array() });
|
|
return;
|
|
}
|
|
await this.usersService.createUser(user);
|
|
res.status(201).end();
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async updateUserNamespace(req: Request, res: Response) {
|
|
try {
|
|
const { userId, namespaceId } = req.params;
|
|
return await this.usersService.updateUserNamespace(userId, namespaceId);
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async resetUserNamespace(req: Request, res: Response) {
|
|
try {
|
|
const { userId } = req.params;
|
|
const defaultNS = await this.namespacesService.getDefaultNamespace();
|
|
if (!defaultNS._id) {
|
|
throw new Error('Default namespace not found');
|
|
}
|
|
return await this.usersService.updateUserNamespace(userId, defaultNS._id.toString());
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async updateUser(req: Request, res: Response) {
|
|
const user = req.body;
|
|
try {
|
|
const validation = validationResult(req);
|
|
if (!validation.isEmpty()) {
|
|
res.status(400).json({ errors: validation.array() });
|
|
return;
|
|
}
|
|
|
|
const { id } = req.params;
|
|
await this.usersService.updateUser(user, id);
|
|
res.status(200).end();
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async deleteUser(req: Request, res: Response) {
|
|
try {
|
|
const { id } = req.params;
|
|
await this.usersService.deleteUser(id);
|
|
res.status(200).end();
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async listUsers(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const { available = false } = req.query;
|
|
let users = [];
|
|
if (available) {
|
|
const defaultNamespace = await this.namespacesService.getDefaultNamespace();
|
|
users = await this.usersService.listUsers({ not: defaultNamespace._id });
|
|
} else {
|
|
users = await this.usersService.listUsers();
|
|
}
|
|
res.json(users).status(200).end();
|
|
} catch (error) {
|
|
this.handleError(res, error);
|
|
}
|
|
}
|
|
|
|
async passwordRecovery(req: Request, res: Response) {
|
|
try {
|
|
const { username } = req.body;
|
|
const user = await this.usersService.getByUsername(username);
|
|
if (user === null) {
|
|
res.status(404).json({ message: 'User not found', code: 'user-not-found'}).end();
|
|
return;
|
|
}
|
|
if (!user.email) {
|
|
res.status(404).json({ message: 'Email not found', code: 'email-not-found'}).end();
|
|
return;
|
|
}
|
|
const { email, firstname, lastname, _id: userId } = user;
|
|
const pin = this.cryptoService.generateRandomPin(8);
|
|
const token = this.security.getHashedPassword(pin);
|
|
const temporalToken = {
|
|
userId,
|
|
token,
|
|
createdAt: new Date().getTime(),
|
|
validUntil: new Date().getTime() + 1000 * 60 * 60 * 1,
|
|
type: TemporalTokenMongoManager.Types.PASSWORD_RECOVERY,
|
|
}
|
|
|
|
if (!userId) {
|
|
throw new Error('User not found');
|
|
}
|
|
|
|
this.temporalTokenManager.deleteAllByUserAndType(userId.toString(), TemporalTokenMongoManager.Types.PASSWORD_RECOVERY);
|
|
this.temporalTokenManager.addToken(temporalToken);
|
|
await this.mailService.sendRecoveryPasswordEmail(firstname, lastname, email, pin);
|
|
res.status(200).end();
|
|
} catch (error: any) {
|
|
this.handleError(res, error, { code: 'critical', message: error.message });
|
|
}
|
|
}
|
|
}
|