jwt prevents me from seeing other users' profiles nodejs, angular - node.js

I followed a tutorial on how to create an authentication system. I tried to understand as much as possible while following the tutorial, but there are things that I still don't get, and now I've come to a problem that I've tried many things to fix but the answer is still negative. The problem is that the jwt middleware only allows me to see the profile of the user that I am logged in as, but I don't want that, I want a user to be able to see every other users' profiles, how can I do that? Thanks in advance!!
For the backend, here is my "user.route.js"
router.get("/profile/:id",auth, async (req, res) => {
try {
// request.user is getting fetched from Middleware after token authentication
const user = await User.findById(req.user.id);
res.json(user);
} catch (e) {
res.send({ message: "Error in Fetching user" });
}
});
for front end, here is my "authentication.service.ts"
export interface UserDetails{
username: string
email: string
password: string
firstName: string
lastName: string
exp: number
iat: number
}
interface TokenResponse{
token: string
}
export interface TokenPayload{
username: string
email: string
password: string
firstName: string
lastName: string
}
#Injectable({
providedIn: 'root'
})
export class AuthenticationService {
private token: string
constructor(private http: HttpClient, private router: Router) {}
private saveToken(token: string): void{
localStorage.setItem('usertoken', token)
this.token = token
}
private getToken(): string{
if(!this.token){
this.token = localStorage.getItem('usertoken')
}
return this.token
}
public getUserDetails(): UserDetails{
const token = this.getToken()
let payload
if(token){
payload = token.split('.')[1]
payload = window.atob(payload)
return JSON.parse(payload)
}else{
return null
}
}
public isLoggedIn(): boolean{
const user = this.getUserDetails()
if(user){
return user.exp > Date.now()/ 1000
}
else{
return false
}
}
public login(user: TokenPayload): Observable<any>{
const base = this.http.post('/user/login', user)
const request = base.pipe(
map((data: TokenResponse) => {
if(data.token){
this.saveToken(data.token)
}return data
})
)
return request
}
public register(user: TokenPayload) : Observable<any>{
const base = this.http.post('/user/register', user)
const request = base.pipe(
map((data: TokenResponse) => {
if(data.token){
this.saveToken(data.token)
}
return data
})
)
return request
}
public profile(id): Observable<any>{
const username = this.getUserDetails().username
return this.http.get(`/user/profile/${id}`,
{
headers: {Authorization: `${this.getToken()}`}
})
}
public logout(): void{
this.token = ''
window.localStorage.removeItem('usertoken')
this.router.navigateByUrl('/')
}
}
and this is the "profile.component.ts" code
ngOnInit() {
this.route.params.subscribe(params => {
const id = params.id;
this.auth.profile(id).subscribe(
user => {
this.details = user
},
err => {
console.error(err)
}
)
})
}

req.user up there is filled in by the authorization middleware, it does not use the id from url path like you want. For that you should use req.params.id

Related

I can't update information from inside the entity with typeorm

I'm building a "forgot password" controller, so my goal in "forgotPasswordController" is to generate a token and send it to my user entity, but the problem is that even following the typeorm documentation, I can't.but it still doesn't work, even though I use the const user instead of the User directly from the entity
error : (property) tokenResetPass: string Expected 3 arguments, but got 2.ts(2554) EntityManager.d.ts(208, 145): An argument for 'partialEntity' was not provided.
the problem is in
const sendToken = await AppDataSource.manager.update(User, {
tokenResetPass: token
});
forgotPassController
import { Request, Response } from "express";
import { User } from "../entities/User";
import { AppDataSource } from "../database/Config";
import jwt from 'jsonwebtoken';
import sendEmail from "../utils/mailer";
class forgotPasswordController {
async authenticate(req: Request, res: Response) {
const { email } = req.body;
const secret = process.env.JWT_SEC as string;
try {
const user = await AppDataSource.manager.findOneBy(User, {
email: email
});
if (!user) {
return res.status(401).json('Email not registered!');
};
if (user.isResetPass === true) {
return res.status(401).json('You have already made a request, check your email inbox.');
}
const token = jwt.sign({ id: user.id }, secret, {
expiresIn: process.env.EXPIRES_LOGIN,
});
if (!token) {
return res.status(401).json('Expired token, please try again.')
}
const sendToken = await AppDataSource.manager.update(User, {
tokenResetPass: token
});
sendEmail({
from: 'noreply#email.com',
to: user.email,
subject: 'Reset Password E-mail',
text: 'Token sending email to reset password',
html: `<h2>Copy the generated token below to reset your password</h2>
<h4>${token}</h4>
`,
});
return res.status(200).json('Email sent! Check your email box. ');
} catch (err) {
return res.status(500).json(err);
}
}
}
export default new forgotPasswordController();
user entity
import { BeforeInsert, BeforeUpdate, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
import bcrypt from 'bcryptjs';
#Entity('users')
export class User {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column()
username: string;
#Column()
email: string;
#Column()
password: string;
#Column({
default: false
})
isResetPass: boolean;
#Column({
default: null
})
tokenResetPass: string;
#BeforeInsert()
#BeforeUpdate()
hashPassword() {
this.password = bcrypt.hashSync(this.password, 8);
}
}

axios get method doesn't send any data in to my node backend using react native

When I console.log the variable refToken before the get request the refToken shows what it contains but after that nothing, and my backend sends me the error 401 which means no token was provided!!
I am really confused here
utility file for expo-secure-store
import * as SecureStore from 'expo-secure-store';
const saveRefreshToken = async (value: string) => {
try {
await SecureStore.setItemAsync("refreshToken", value);
} catch (e) {
console.log("Cannot set refresh token")
}
}
const getRefreshToken = async () => {
try {
return await SecureStore.getItemAsync("refreshToken");
} catch (e) {
console.log("can't get requested refreshToken", e);
}
}
const deleteRefreshToken = async () => {
try {
await SecureStore.deleteItemAsync("refreshToken");
} catch (e) {
console.log("cannot delete refreshToken ", e);
}
}
export default {
saveRefreshToken,
getRefreshToken,
deleteRefreshToken
};
React native code
import axios from "../api/axios";
import useAuth from "./useAuth";
import storage from "../utility/storage";
import jwtDecode from "jwt-decode";
const useRefreshToken = () => {
const {setAuth, auth} = useAuth();
return async () => {
const refToken = await storage.getRefreshToken();
// withCredentials: true,
const response = await axios.get(`/auth/refresh/`, {
params: {refreshToken: refToken},
});
//#ts-ignore
setAuth({user: jwtDecode(response.data.accessToken), accessToken: response.data.accessToken});
return response.data.accessToken;
};
}
export default useRefreshToken;
Node.js backend part that deals with this request
// TODO: Generate new access token from refresh
export const refreshTokenSignIn = (
req: express.Request,
res: express.Response,
next: express.NextFunction
) => {
// const refreshToken = req.cookies.jwt;
const refreshToken = req.body.refreshToken;
try {
// Check if the refresh token is not null
if (!refreshToken)
return res.status(401).json({message: "No token provided!"});
// console.log(refreshToken);
const sql = `select * from token_records where refresh_token = '${refreshToken}'`;
// Check if there is such refresh token for the current user
db.query(
sql,
[refreshToken],
(err: QueryError, result: RowDataPacket[]) => {
if (err) return next(err);
if (result.length === 0)
return res.status(403).json({message: "You don't have access"});
//#ts-ignore
jwt.verify(
refreshToken,
//#ts-ignore
process.env.JWT_REFRESH_SECRET,
(err2: VerifyErrors, user: JwtPayload) => {
if (err2) return res.status(403).json({message: "You don't have access"});
const accessToken = jwt.sign(
{
user_id: user.user_id,
firstname: user.firstname,
lastname: user.lastname,
username: user.username,
email: user.email,
role: user.role,
},
//#ts-ignore
process.env.JWT_SECRET
);
res.status(200).json({accessToken: accessToken});
next();
}
);
}
);
} catch (e) {
console.log(e);
next();
}
};

User verification changing 'registered user hashed password', preventing login

User registers with a bcrypt hashed password. After proceding with email verification through mailtrap/nodemailer and successfully verifing user status to true, the login fails, returning 'unmatched password", because it is changing stored user hashed password. If I skip the verification step and proceed with login directly, it will work fine. So how do I do 'user verification' without changing stored hashed password in my code below?
async login(req: Request, res: Response){
// Get user from database
const userRepository = getRepository(User);
const { email, password } = req.body;
if (!(email && password)) {
console.error('Empty name or password!');
return res.status(400).send({
error: 'Empty name or password'
});
}
const user = await userRepository.findOne({ where: { email } });
let storedUserPass = user!.password;
console.log(password) //-> consoles plain typed text
console.log(storedUserPass) //-> consoles encrypted password
const isValidPassword = await bcrypt.compareSync(password, storedUserPass as string);
console.log(isValidPassword) //-> consoles false
if(!user) {
return res.send(`User doesn t exist! `);
}
else if (!user.isVerified) {
return res.send('Your Email has not been verified. Please do so!');
}
else if(!isValidPassword) {
return res.send('Password doesn t match')
}
else {
// Sing JWT, valid for 1 hour
const token = jwt.sign(
{ id: user.id, email: user.email },
process.env.NODE_ENV,
{ expiresIn: "1d" }
);
res.json({
user,
token
});
}
},
async create(req: Request, res: Response) {
const verificationToken = await crypto.randomBytes(8).toString('hex');
const { name, email, password, role, isVerified } = req.body;
const date = new Date();
try {
const userRepository = getRepository(User);
const tokenRepository = getRepository(Token);
//User validation
const data = {
name,
email,
password,
}
const schema = Yup.object().shape({
name: Yup.string().required('Name required.').max(60),
email: Yup.string().email("Invalid Email.").required(),
password: Yup.string().required().min(4).max(10),
})
await schema.validate(data, {
abortEarly: false
});
const userExists = await userRepository.findOne({ where: { email }})
if(userExists) {
return res.send(`Usuário com email cadastrado ${email} já existe!` );
} else {
const token = tokenRepository.create({token: verificationToken, tokenDate: date})
await tokenRepository.save(token);
const user = userRepository.create({ name, email, password, role: role || "basic", isVerified, date, token})
console.log(user.password) // consoles plain text
await userRepository.save(user);
console.log(user.password) //consoles encrypted text
return new Promise((resolve,reject)=>{
const transp = transport;
var mailOptions = {
from: 'Administrador <c3e26a9df0-703049#inbox.mailtrap.io>',
to: email,
subject: 'Account verification link!',
html: `<h2>Olá ${user.name}</h2><br/>
<p>Finalize o seu cadastro clicando neste <a href="http://${req.headers.host}/users/confirmation/${user.email}/${verificationToken}" target="_about" style="color: blue, text-derocation: none"}>Link</a>`
}
transp.sendMail(mailOptions, function(error: Err){
if (error) {
return res.status(500).send({msg:'Technical Issue!,Please click on resend for verify your Email.'});
}
else {
return res.send('A verification email has been sent to ' + user.email + '. It will be expire after one day. If you not get verification Email click on resend token.');
});
})
}
} catch(err) {
return res.status(404).send({ err: "Failed to send email."})
}
},
//TYPEORM USER MODEL:
#Entity('users')
export default class User {
#PrimaryGeneratedColumn('uuid')
id: number;
#Column()
name: string;
#Column({
unique: true
})
email: string;
#Column()
password: string;
#Column()
role: string;
default: 'basic'
enum: ["basic", "supervisor", "admin"];
#Column({
type: "datetime"
})
date!: Date;
#Column({
default: false
})
isVerified: boolean;
#BeforeInsert()
#BeforeUpdate()
hashPassword() {
this.password = bcrypt.hashSync(this.password, 8); // salt de 8
}
checkIfUnencryptedPasswordIsValid(unencryptedPassword: string) {
return bcrypt.compareSync(unencryptedPassword, this.password);
}
#OneToMany(() => Orphanage, orphanage => orphanage.user, {
cascade: ['insert' , 'update']
})
#JoinColumn({ name: 'user_id'})
orphanages: Orphanage[];
#OneToOne(type => Token)
#JoinColumn()
token: Token;
}
async confirmEmail(req: Request, res: Response) {
try {
const userRepository = getRepository(User);
const tokenRepository = getRepository(Token);
const tokenExists = await tokenRepository.findOne({ token: req.params.token });
tokenExists!.tokenDate
if( !tokenExists ) {
return res.status(400).send({msg:'Your verification link may have expired. Please click on resend for verify your Email.'});
} else {
const user = await userRepository.findOne({where: { token: tokenExists, email: req.params.email }})
//user not exist
if(!user) {
return res.status(401).send({msg:'We were unable to find a user for this verification. Please SignUp!'});
} // user is already verified
else if (user.isVerified){
return res.status(200).send('User has been already verified. Please Login');
} else { //verify user
user.isVerified = true;
await userRepository.save(user);
console.log(user) // -> hashed user.password is different from when created user after user is verified.
return res.status(200).send('Your account has been successfully verified')
}
}
} catch(err) {
return res.status(500).send({err: "Sorry, it could not be validated!"});
}
},
Using ? in user?.password is not a valid way. The symbol? is used in the ternary operator. The ternary operator needs three parameters and you are not providing these parameters.
solution: format your code as given below. I used the ! operator in user!.password. This operator in user! ensures your transpiler that the user will not be undefined. So, before using this operator you should check whether a user is defined or not, in this way:
if(!user) {
return res.send(`User doesn t exist! `);
}
If you don't check the user before using ! you may get a run-time error in the case of an undefined user. No need to use as string.
Changed Block in your code:
const user = await userRepository.findOne({ where: { email } });
//check user immediately after getting it to avoid errors
if(!user) {
return res.send(`User doesn t exist! `);
}
let storedUserPass = user!.password;
const isValidPassword = await bcrypt.compareSync(password, storedUserPass);
Now your code will look like:
async login(req: Request, res: Response){
// Get user from database
const userRepository = getRepository(User);
const { email, password } = req.body;
if (!(email && password)) {
console.error('Empty name or password!');
return res.status(400).send({
error: 'Empty name or password'
});
}
const user = await userRepository.findOne({ where: { email } });
if(!user) {
return res.send(`User doesn t exist! `);
}
let storedUserPass = user!.password;
const isValidPassword = await bcrypt.compareSync(password, storedUserPass);
if (!user.isVerified) {
return res.send('Your Email has not been verified. Please do so!');
}
else if(!isValidPassword) {
return res.send('Password doesn t match')
}
else {
// Sing JWT, valid for 1 hour
const token = jwt.sign(
{ id: user.id, email: user.email },
process.env.NODE_ENV,
{ expiresIn: "1d" }
);
res.json({
user,
token
});
}
}
Shakir Aqeel, please do not consider my last answer, I got confused, the prob has nothing to do with token.
But I have always used same library to encrypt the password when creating user, located on User model:
hashPassword() {
this.password = bcrypt.hashSync(this.password, 8);
}
In the User controller:
console.log(user.password) -> plain typed password
await userRepository.save(user);
console.log(user.password) -> encrypted password
If I register a new user with verification status as 'true', it will login with no problem....

angular + nodejs console shows "GET http://localhost:4200/user/profile 401 (Unauthorized) "

I'm trying to store data into /profile after logging in. However, I keep getting these 2 errors in the console after logging in.
"VM276:1 GET http://localhost:4200/user/profile 401 (Unauthorized)"
and "HttpErrorResponse {headers: HttpHeaders, status: 401, statusText: "Unauthorized"".
Since i'm following different tutorials to work this out so I know that I've made some mistake with the token code, I just don't know how to fix it. And I would like to thank anyone who's spending time to help! This is my authentication.service.ts
import { Injectable } from '#angular/core';
import {HttpClient} from "#angular/common/http";
import {Observable, of} from 'rxjs';
import { map } from 'rxjs/operators';
import {Router} from '#angular/router';
export interface UserDetails{
username: string
email: string
password: string
exp: number
iat: number
}
interface TokenResponse{
token: string
}
export interface TokenPayload{
username: string
email: string
password: string
}
#Injectable({
providedIn: 'root'
})
export class AuthenticationService {
private token: string
constructor(private http: HttpClient, private router: Router) {}
private saveToken(token: string): void{
localStorage.setItem('usertoken', token)
this.token = token
}
private getToken(): string{
if(!this.token){
this.token = localStorage.getItem('usertoken')
}
return this.token
}
public getUserDetails(): UserDetails{
const token = this.getToken()
let payload
if(token){
payload = token.split('.')[1]
payload = window.atob(payload)
return JSON.parse(payload)
}else{
return null
}
}
public isLoggedIn(): boolean{
const user = this.getUserDetails()
if(user){
return user.exp > Date.now()/ 1000
}
else{
return false
}
}
public login(user: TokenPayload): Observable<any>{
const base = this.http.post('/user/login', user)
const request = base.pipe(
map((data: TokenResponse) => {
if(data.token){
this.saveToken(data.token)
}return data
})
)
return request
}
public register(user: TokenPayload) : Observable<any>{
const base = this.http.post('/user/register', user)
const request = base.pipe(
map((data: TokenResponse) => {
if(data.token){
this.saveToken(data.token)
}
return data
})
)
return request
}
public profile(): Observable<any>{
return this.http.get('/user/profile',{
headers: {Authorization: `${this.getToken()}`}
})
}
public logout(): void{
this.token = ''
window.localStorage.removeItem('usertoken')
this.router.navigateByUrl('/')
}
}
This is my profile.component.ts
export class ProfileComponent implements OnInit {
details: UserDetails
constructor(private auth: AuthenticationService) {}
ngOnInit() {
this.auth.profile().subscribe(
user => {
this.details = user
},
err => {
console.error(err)
}
)
}
}
this is my auth.js
const jwt = require("jsonwebtoken");
module.exports = function(req, res, next) {
const token = req.header("token");
if (!token) return res.status(401).json({ message: "Auth Error" });
try {
const decoded = jwt.verify(token, "randomString");
req.user = decoded.user;
next();
} catch (e) {
console.error(e);
res.status(500).send({ message: "Invalid Token" });
}
};
and this is my /routes/user.js
// Filename : user.js
const express = require("express");
const {check, validationResult} = require("express-validator");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const router = express.Router();
const auth = require("../middleware/auth");
const User = require("../model/User");
/**
* #method - POST
* #param - /signup
* #description - User SignUp
*/
router.post(
"/register",
[
check("username", "Please Enter a Valid Username")
.not()
.isEmpty(),
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength({
min: 6
})
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
errors: errors.array()
});
}
const {
username,
email,
password
} = req.body;
try {
let user = await User.findOne({
email
});
if (user) {
return res.status(400).json({
msg: "User Already Exists"
});
}
user = new User({
username,
email,
password
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
"randomString", {
expiresIn: 10000
},
(err, token) => {
if (err) throw err;
res.status(200).json({
token
});
}
);
} catch (err) {
console.log(err.message);
res.status(500).send("Error in Saving");
}
}
);
router.post(
"/login",
[
check("email", "Please enter a valid email").isEmail(),
check("password", "Please enter a valid password").isLength({
min: 6
})
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
errors: errors.array()
});
}
const { email, password } = req.body;
try {
let user = await User.findOne({
email
});
if (!user)
return res.status(400).json({
message: "User Does Not Exist"
});
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch)
return res.status(400).json({
message: "Incorrect Password!"
});
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
"randomString",
{
expiresIn: 3600
},
(err, token) => {
if (err) throw err;
res.status(200).json({
token
});
}
);
} catch (e) {
console.error(e);
res.status(500).json({
message: "Server Error"
});
}
}
);
/**
* #method - POST
* #description - Get LoggedIn User
* #param - /user/me
*/
router.get("/profile", auth, async (req, res) => {
try {
// request.user is getting fetched from Middleware after token authentication
const user = await User.findById(req.user.id);
res.json(user);
} catch (e) {
res.send({ message: "Error in Fetching user" });
}
});
module.exports = router;
In your angular app you are sending the token with the authorization header
Authorization: token
But in your API (auth.js), you are trying to access the token header
req.header("token")
Replace you api code with
req.header("authorization")

How do I get expected types on express request argument

I'm working on some authentication in an express app, using passport, and typescript. I have defined a user model using typegoose. After passing the login request through the passport strategy, I'm calling a login method that returns the token. I'm getting a typescript error on req.user._id Property '_id' does not exist on type 'User'.
I don't have _id explicitly defined on my user model, but from what I understand with typegoose that is not necessary, and there are other places in the code that I do not have this issue. Also, trying things that are explicitly defined on the model (email, zip, etc) still produces the same error.
import { Request, Response, Router } from 'express';
import jwt from 'jwt-simple';
import passport from 'passport';
import 'dotenv/config';
import ControllerInterface from './controller.interface';
class LoginController implements ControllerInterface {
public path = '/api/login';
public router = Router();
constructor() {
this.initRoutes();
}
public initRoutes(): any {
this.router.post(this.path, [this.requireLogin, this.login]);
}
tokenForUser = (id: string) => {
const timestamp = new Date().getTime();
return jwt.encode({ sub: id, iat: timestamp }, process.env.JWT_ENCRYPTION);
};
requireLogin = passport.authenticate('local', { session: false });
login = (req: Request, res: Response) => {
// eslint-disable-next-line #typescript-eslint/ban-ts-ignore
// #ts-ignore
res.send({ token: this.tokenForUser(req.user._id) });
};
}
export default LoginController;
The passport strategy is using the user model I created with typegoose
const local = new LocalStrategy(localOptions, (email, password, done) => {
UserModel.findOne({ email }, async (err: NodeJS.ErrnoException, user) => {
if (err) return done(err);
if (!user) return done(null, false);
const isMatch = await user.comparePassword(password);
if (!isMatch) return done(null, false);
return done(null, user);
});
});
I've searched around quite a bit with no luck on this yet, thanks!
Edit: adding user model code
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
import 'dotenv/config';
import { arrayProp, getModelForClass, pre, prop } from '#typegoose/typegoose';
const setUserId = () => {
return Math.random()
.toString(36)
.substr(2, 9);
};
const getUserId = (id: string) => {
return id;
};
#pre<UserClass>('save', async function(next) {
if (this.isModified('password') || this.isNew) {
const hashedPass = await bcrypt.hash(this.password, 10);
this.password = hashedPass;
this.updated = new Date();
next();
}
})
class UserClass {
#prop()
public firstName?: string;
#prop()
public lastName?: string;
public get fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
public set fullName(full) {
const [firstName, lastName] = full.split(' ');
this.firstName = firstName;
this.lastName = lastName;
}
#prop({
required: true,
unique: true,
lowercase: true,
trim: true,
validate: {
validator: (email) => {
const emailRegExp = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return emailRegExp.test(email);
},
message: 'Email is invalid.',
},
})
public email!: string;
#prop({
required: true,
validate: {
validator: (password) => {
// at least 8 char
// at least 1 number
// at least 1 special character
const passwordRegExp = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[#$!%*#?&])[A-Za-z\d#$!%*#?&]{8,}$/;
return passwordRegExp.test(password);
},
message: 'Password is not in the proper format.',
},
})
public password!: string;
#prop({ default: Date.now })
public created?: Date;
#prop()
public updated?: Date;
#prop({ unique: true, set: setUserId, get: getUserId, default: setUserId() })
public userId?: string;
async comparePassword(candidatePassword: string): Promise<boolean> {
const isMatch = await bcrypt.compare(candidatePassword, this.password);
return isMatch;
}
getJWT(): string {
const expirationTime = parseInt(process.env.JWT_EXPIRATION, 10);
const bearer = jwt.sign({ userId: this.userId }, process.env.JWT_ENCRYPTION, {
expiresIn: expirationTime,
});
return `Bearer ${bearer}`;
}
toWeb(): object {
return this;
}
}
const UserModel = getModelForClass(UserClass);
export { UserClass };
export default UserModel;
You'd have to add line const { _id: id } = await UserModel.create({ .... } as User) while creating your usermodel

Resources