8

Well, I have this a similar question to this one (I know that is similar to another one). But req.user was undefined until I installed @types/passport.

Now I get this problem in VS Code despites I have my session instantiation on my server.

The problem

The problem

The instantiation

// Middlewares
app.use(bodyParser.urlencoded({ extended: false }));
app.use(logger(process.env.NODE_ENV === 'development' ? 'dev' : 'combined'));
app.use(express.json());
app.use(session({
    secret: process.env.NODE_ENV === 'development' ? process.env.SESSION_SECRET : 'secret',
    resave: false,
    saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());

No errors above. Therefore... the app in fact works... but I get this "error color" on my VSC file that would be great to avoid. Any suggestions?

Just in case, I will include the whole router file:

// POST - Crear usuario
router.post('/', async (req: Request, res: Response) => {
    const resultado: IResultado = {
        data: null,
        ok: false
    };
    const messages: Array<object> = [];
    const datos: IUsuario = req.body;

    // Validación de campos
    if (!validator.isEmail(datos.email)) {
        messages.push({ email: 'El correo electrónico es inválido'});
    }

    if (validator.isLength(datos.password, { max: 5})) {
        messages.push({ password: 'La contraseña debe tener como mínimo seis caracteres' });
    }

    if (!validator.isMobilePhone(datos.telefono, ['es-UY'])) {
        messages.push({ telefono: 'El número de teléfono es inválido' });
    }

    if (!empty(messages)) {
        resultado.message = 'No se pudo crear el usuario';
        resultado.messages = messages;
        return res.json(resultado);
    }

    datos.password = await bcrypt.hash(datos.password, 10);
    datos.fechaCreacion = Date.now();
    datos.fechaActualizacion = Date.now();

    if (req.user && req.user) {
        datos.propietario = req.user.email;
    }

    const ref: any = db.collection('usuarios').doc(datos.email);

    const doc = await ref.get();

    if (doc.exists) {
        // Usuario ya existe
        resultado.message = 'El correo electrónico ya está en uso';
        return res.json(resultado);
    }
    try {
        await ref.set(datos);
        delete datos.password;
        resultado.message = 'Usuario creado correctamente';
        resultado.data = datos;
        resultado.ok = true;
        return res.json(resultado);
    } catch(error) {
        resultado.message = 'No se pudo crear el usuario';
        resultado.error = error;
        console.log(error);
        return res.status(500).json(resultado);
    }
});

The User interface (@types/passport module)

// tslint:disable-next-line:no-empty-interface
        interface AuthInfo {}
        // tslint:disable-next-line:no-empty-interface
        interface User {}

        interface Request {
            authInfo?: AuthInfo;
            user?: User;
...
Maramal
  • 3,145
  • 9
  • 46
  • 90
  • Are you sure `user` has own property email? It looks like not but probably you can initialize it manualny. By default it contains only `username` and `id` properties – Adrian Solarczyk Apr 01 '20 at 23:25
  • it doesn't. But is defined inside `@types/passport` module. I will extend it as you mentioned. – Maramal Apr 01 '20 at 23:36

2 Answers2

19

You need to extend the Express.User type:

declare global {
  namespace Express {
    interface User {
      email: string;
    }
  }
}
Jerguš Lejko
  • 610
  • 4
  • 25
  • Where should put this code? I have similar problem here: https://stackoverflow.com/questions/72340135/property-admin-does-not-exist-on-type-user-ts2339?noredirect=1#comment127798285_72340135 – Hasani May 22 '22 at 18:17
3

I think all you need to do is extend basic User type interface. That already was asked on GitHub.

interface User extends SomeOtherUserTypeYouHaveDefined {
      email?: string;
      alsoAnyOtherPropertyYourCodeSetsOnUser: number;
    }