Thursday 5 August 2021

Express + TSOA + Passport

I am new to Passport and to TSOA. I am trying to migrate an old Express route to TSOA controllers but I have not any idea how to achieve this. I did not find any documentation regarding this, in fact, I found this issue but I think I need a workaround.

router.post(
    '/register',
    (req: Request, res: Response, next) => {
        const user: IUserData = req.body

        if (validator.isEmpty(email)) 
            return res.status(422)
                .json({ error: 'Email is mandatory' })

        if (validator.isEmpty(password.trim()))
            return res.status(422)
                .json({ error: 'Password is mandatory' })

        next()
    },
    passport.authenticate('local'),
    async (req: Request, res: Response) => {
        if (req.user)
            return res.json({ message: 'Already logged in' })

        const existingUser: IUser = await UserModel.findOne({ email: req.body.email })
        if (existingUser)
            return res.status(400)
                .json({ error: 'User exists' })

        const data: IUserData = req.body

        try {
            const hashedPassword = await bcrypt.hashSync(data.password, parseInt(process.env.SALT_ROUNDS) || 10)
            data.password = hashedPassword
        } catch(error) {
            return res.status(500)
                .json({ error: error.message })
        }
        
        try {
            const user: IUser = await new User(data)
            await user.save()
            res.json(user);
        } catch(error) {
            return res.status(500)
                .json({ error: error.message });
        }
        return;
    }
);

I have tried to "replicate" this code into a TSOA controller but I don't know how to apply the middleware stuff:

@Route('/auth')
export class AuthController extends Controller {
    @Post()
    public async register(@BodyProp() user: IUserData) {
        const errors: Array<IAuthError> = []

        if (validator.isEmpty(user.emailAddress)) {
            this.setStatus(422)
            return { error: 'Email is mandatory' }
        }

        if (validator.isEmpty(user.password.trim())) {
            this.setStatus(422)
            return { error: 'Password is mandatory' }
        }
    }
}

// to be continued ...

I could also separate this certain route in a different file (without any controller) but I don't know if that would work at all. I guess not.

How should I manage this?

Edit:

I just have read this article regarding TSOA authentication and it seems to handle authentication by using middlewares.



from Express + TSOA + Passport

No comments:

Post a Comment