How to solve user.get is not a function error?

27 Views Asked by At

I am trying to authenticate user login with the passport authenticate method but it is not authorizing the user to login despite having the correct login credentials. When I submit the form, I get a response from the server stating that user.get is not a function.

Here is index.ts:

router.post("/login", function (req, res, next) {
  passport.authenticate("local", function (err: any, user: any, info: any) {
    // Check for server errors
    if (err) {
      console.error("Server error:", err);
      return next(err); // Forward the error to the error handler
    }

    // Check for authentication errors
    if (!user) {
      req.flash("error", "Authentication Error");
      // return res.redirect("/login");
    }

    // If authentication succeeds, log in the user
    req.logIn(user, function (err) {
      if (err) {
        console.error("Login error:", err);
        return next(err); // Forward the error to the error handler
      }
      // return res.redirect("/about");
    });
  })(req, res, next); // Pass req, res, and next to passport.authenticate
});

Here is a portion of my app.ts:

import createErrorfrom, { HttpError } from "http-errors";
import express, { NextFunction } from "express";
import path from "path";
import cookieParser from "cookie-parser";
import logger from "morgan";

// Module to connect to MongoDB
import mongoose from "mongoose";

// Modules to support authentication
import session from "express-session"; // cookie-based session
import passport from "passport"; // authentication support
import passportLocal from "passport-local"; // authentication strategy (username/password)
import flash from "connect-flash"; // authentication messaging

// Authentication Model and Strategy Alias
let localStrategy = passportLocal.Strategy; // Alias

// User Model
import User from "../Models/user";

// App Configuration
import indexRouter from "../Routes/index";
import usersRouter from "../Routes/users";
import createHttpError from "http-errors";

// Configure session middleware
// Define a custom interface extending express-session's Session interface

const app = express();

// DB Configuration
// Find the DB Config file
import * as DBConfig from "./db";

// Connect to the NoSQL DB by using the connection method and inputting the LocalURI string
mongoose.connect(DBConfig.LocalURI);
//Alias for mongoose connection
const db = mongoose.connection; //
db.on("error", function () {
  console.error(`Connection Error! ${DBConfig.LocalURI}`);
});
db.once("open", function () {
  console.log(`Connection to MongoDB at ${DBConfig.HostName}`);
});

//Use express-session middleware with custom session interface
app.use(
  session({
    secret: DBConfig.SessionSecret,
    resave: false,
    saveUninitialized: false,
  })
);

console.log(`Directory Name --> ${__dirname}`);
console.log(`File Name --> ${__filename}`);

// view engine setup
app.set("views", path.join(__dirname, "../Views"));
app.set("view engine", "ejs");

// Middleware configuration
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "../../Client")));
app.use(express.static(path.join(__dirname, "../../node_modules")));

app.use(flash());

// Initalize Passport
// Configure this before the route configuration so the login/logout can be processed
app.use(passport.initialize());
app.use(passport.session());

// Implement an Autg Strategy
passport.use(User.createStrategy());

// Seralize and Deserialize our data
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

This is my User Model:

import mongoose, { PassportLocalSchema } from "mongoose";
const Schema = mongoose.Schema; // strucuture for a class
import passportLocalMongoose from "passport-local-mongoose";

const UserSchema = new Schema(
  {
    FirstName: String,
    LastName: String,
    username: String,
    SecurityLevel: String,
    EmailAddress: String,
    DateCreated: {
      type: Date,
      default: Date.now(),
    },
    LastUpdate: {
      type: Date,
      default: Date.now(),
    },
  },
  {
    collection: "users",
  }
);

UserSchema.plugin(passportLocalMongoose);

const Model = mongoose.model("User", UserSchema);

declare global {
  export type UserDocument = mongoose.Document & {
    FirstName: String;
    LastName: String;
    username: String;
    SecurityLevel: String;
    EmailAddress: String;
  };
}

export default Model;

The error is being thrown in my node_modules> passport-local-mongoose > index.js @ line 212. When I look into my node_modules> passport-local-mongoose > index.d.ts file there is a pile of errors.

Here are the errors in the node_modules> passport-local-mongoose>index.d.ts file:

Here is the index.d.ts for passport-local-mongoose

declare module 'mongoose' {
  import passportLocal = require('passport-local');

  export interface AuthenticationResult {
      user: any;
      error: any;
  }

  // methods
  export interface PassportLocalDocument extends Document {
      setPassword(password: string): Promise<PassportLocalDocument>;
      setPassword(password: string, cb: (err: any, res: any) => void): void;
      changePassword(oldPassword: string, newPassword: string): Promise<PassportLocalDocument>;
      changePassword(oldPassword: string, newPassword: string, cb: (err: any, res: any) => void): void;
      authenticate(password: string): Promise<AuthenticationResult>;
      authenticate(password: string, cb: (err: any, user: any, error: any) => void): void;
      resetAttempts(): Promise<PassportLocalDocument>;
      resetAttempts(cb: (err: any, res: any) => void): void;
  }

  interface AuthenticateMethod<T> {
      (username: string, password: string): Promise<AuthenticationResult>;
      (username: string, password: string, cb: (err: any, user: T | boolean, error: any) => void): void;
  }

  // statics
  interface PassportLocalModel<T> extends Model<T> {
      authenticate(): AuthenticateMethod<T>;
      serializeUser(): (user: T, cb: (err: any, id?: any) => void) => void;
      deserializeUser(): (username: string, cb: (err: any, user?: any) => void) => void;

      register(user: T, password: string): Promise<T>;
      register(user: T, password: string, cb: (err: any, account: any) => void): void;
      findByUsername(username: string, selectHashSaltFields: boolean): Query<T, T>;
      findByUsername(username: string, selectHashSaltFields: boolean, cb: (err: any, account: any) => void): any;
      createStrategy(): passportLocal.Strategy;
  }

  // error messages
  export interface PassportLocalErrorMessages {
      MissingPasswordError?: string | undefined;
      AttemptTooSoonError?: string | undefined;
      TooManyAttemptsError?: string | undefined;
      NoSaltValueStoredError?: string | undefined;
      IncorrectPasswordError?: string | undefined;
      IncorrectUsernameError?: string | undefined;
      MissingUsernameError?: string | undefined;
      UserExistsError?: string | undefined;
  }

  // plugin options
  export interface PassportLocalOptions {
      saltlen?: number | undefined;
      iterations?: number | undefined;
      keylen?: number | undefined;
      encoding?: string | undefined;
      digestAlgorithm?: string | undefined;
      passwordValidator?: ((password: string, cb: (err: any) => void) => void) | undefined;

      usernameField?: string | undefined;
      usernameUnique?: boolean | undefined;

      usernameQueryFields: Array<string>;

      selectFields?: string | undefined;
      populateFields?: string | undefined;

      usernameCaseInsensitive?: boolean | undefined;
      usernameLowerCase?: boolean | undefined;

      hashField?: string | undefined;
      saltField?: string | undefined;

      limitAttempts?: boolean | undefined;
      lastLoginField?: string | undefined;
      attemptsField?: string | undefined;
      interval?: number | undefined;
      maxInterval?: number | undefined;
      maxAttempts?: number | undefined;

      errorMessages?: PassportLocalErrorMessages | undefined;
  }

  export interface PassportLocalSchema<DocType, Model, TInstanceMethods = {}, TQueryHelpers = {}> extends Schema<DocType, Model, TInstanceMethods, TQueryHelpers> {
      plugin(
          plugin: (schema: PassportLocalSchema<DocType, Model, TInstanceMethods, TQueryHelpers>, options?: PassportLocalOptions) => void,
          options?: PassportLocalOptions,
      ): this;

      // overload for the default mongoose plugin function
      plugin(plugin: (schema: Schema, options?: Object) => void, opts?: Object): this;
  }

  export function model<T>(
      name: string,
      schema?: PassportLocalSchema<T, Model<T, any, any, any>>,
      collection?: string,
      skipInit?: boolean,
  ): PassportLocalModel<T>;

  export function model<T extends Document, U extends PassportLocalModel<T>>(
      name: string,
      schema?: PassportLocalSchema<T, Model<T, any, any, any>>,
      collection?: string,
      skipInit?: boolean,
  ): U;
}

declare module 'passport-local-mongoose' {
  import mongoose = require('mongoose');
  var _: (schema: mongoose.Schema<any, any, any, any>, options?: Object) => void;
  export = _;
}

I have no idea as to why I am getting this error. I know it has something to do in regards to the passport.serializeUser(User.serializeUser()) but beyond that I really don't understand why it is not working. I have looked through other questions on stack overflow, I have ran through the VS Code debugger multiple times but I don't know how or why my Schema is not working in conjuction with passport.

Does anyone know why this is an issue?

0

There are 0 best solutions below