import { ConflictException, Injectable, NestMiddleware } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { UserDocument as User } from '../modules/user/schema/user.schema'; import { NextFunction, Request, Response } from 'express'; import admin from '../main'; import { Model } from 'mongoose'; import { Role } from '../roles/role.enum'; @Injectable() export class PreauthMiddleware implements NestMiddleware { constructor(@InjectModel('User') private readonly userModel: Model<User>) {} use(req: Request, res: Response, next: NextFunction) { const token = req.headers.authorization; if (token && token != null && token != '' && token.length > 0) { admin .auth() .verifyIdToken(token.replace('Bearer ', '')) .then(async (decodedToken) => { const { email, uid, picture } = decodedToken; const userExists = await this.userModel .findOne({ email: email }) .lean(); let role; if (userExists) { role = userExists.role || Role.STUDENT; await this.userModel.updateOne( { email: userExists.email }, { log_in_time: new Date().toString(), }, ); } else { const newUser = new this.userModel({ email, fid: uid, role: Role.STUDENT, photoUrl: picture, log_in_time: ' ', }); await newUser.save(); role = Role.STUDENT; console.log(role); } const user = { email: email, fId: uid, role: role, }; req['user'] = user; next(); }) .catch((error) => { if (error.errorInfo.code == 'auth/id-token-expired') { this.accessDenied(req.url, res, undefined, error.errorInfo); } else { this.accessDenied( req.url, res, error.errorInfo.message, error.errorInfo, ); } }); } else { throw new ConflictException('Access Denied as Token does not exist'); } } private accessDenied( url: string, res: Response, message: string, others?: any, ) { res.status(403).json({ statusCode: 403, timestamp: new Date().toISOString(), path: url, message: message ? message : 'Access Denied', ...others, }); } }