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?