#StackBounty: #node.js #file-system #promise #typescript #generator Generator function to enumerate files

Bounty: 50

I want to implement a function that enumerates all files in directory. I think the function should

  • Return a Promise, because underlying readdir call is prefered over readdirSync.
  • Be a generator function, because checking statSync(...).isFile() might take some time and maybe, I will need only first few files…

So my attempt

import * as fs from 'fs';
import * as path from 'path';

function enumerateFiles(dir: string): Promise<IterableIterator<string>> {
    let result = function* (files: string[]): IterableIterator<string> {
        for (let enty of files) {
            let fullpath = path.join(dir, enty);

            if (fs.statSync(fullpath).isFile())
                yield fullpath;
        }
    };

    return new Promise<IterableIterator<string>>((resolve, reject) => {
        fs.readdir(dir, (err, files) => {
            if (err)
                reject(err);
            else
                resolve(result(files));
        });
    });
}

And usage

for (let file of await enumerateFiles(String.raw`C:WindowsWebScreen`))
    console.log(file);

// C:WindowsWebScreenimg100.jpg
// C:WindowsWebScreenimg101.jpg
// ...

What do you think? I’m really not sure about combining Promises with generator functions. Especially in this order…


Get this bounty!!!

#StackBounty: #node.js #bash #heroku #imagemagick #tmp FFMPEG cannot read files in /tmp/ on Heroku

Bounty: 50

I created a nodejs application hosted on heroku which uses imagemagick. I am doing this operation:

require('child_process').exec(`convert -quiet -delay 1 output.avi ${gif}`);

This should convert output.avi (which is present) to a gif file. In this case, gif is "/app/temp/gifs/xstrycatdq.gif". This command works perfectly on my local windows machine. As I use the path module to get a variable with path.joinand __dirname.

I have installed heroku buildpack:

The error I am receiving is:

Command failed: convert -quiet -delay 1 output.avi /app/temp/gifs/xstrycatdq.gif
convert: DelegateFailed `'ffmpeg' -nostdin -v -1 -vframes %S -i '%i' -vcodec pam -an -f rawvideo -y '%u.pam' 2> '%Z'' @ error/delegate.c/InvokeDelegate/1919.
convert: UnableToOpenBlob `magick-93R4VJcemPz0z1.pam': No such file or directory @ error/blob.c/OpenBlob/2705.
convert: NoImagesDefined `/app/temp/gifs/xstrycatdq.gif' @ error/convert.c/ConvertImageCommand/3257.

It seems that the /tmp/ directory can’t be written to or anything. I also tried to mkdir /tmp/ but bash tells me that this dir already exists.

I have also tried changing the imagemagick’s temp directory with the environment variable by doing export MAGICK_TMPDIR="temp".

Any help?

Edit: The variables are now absolute.


Get this bounty!!!

#StackBounty: #node.js #promise #typescript #express.js #oracle Exception handling and releasing of OracleDB connection

Bounty: 50

Before I start implementing several REST API service endpoints, I’d like to make sure that I’m not doing it totally wrong.

/**
 * GET /api/test
 * Test API example.
 */
export let getTest = (req: Request, res: Response, next: NextFunction) => {
    // const token = req.user.tokens.find((token: any) => token.kind === "facebook");
    const db = new Database();

    db.getConnection()
        .then(con => {
            con.execute('SELECT * FROM BTO_MDS.AlARMS', {}, { maxRows: 22000 })
                .then(result => {
                    con.release();
                    res.json({data: result.rows});
                })
                .catch(ex => {
                    con.release();
                    res.status(500).json({message: ex.message});
                });
        })
        .catch(ex => {
            res.status(500).json({message: ex.message});
        });

};
  • Is the connection always released properly, or have I forgotten something?

  • What seems a bit messy is that I need to release the connection two times, and that I have two catch’es, since I cannot release the connection in the second catch.

For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:

import * as oracledb from 'oracledb';
import { IConnectionPool } from 'oracledb';

const config = {
    user: 'user',
    password: 'pw',
    connectString: 'databaseNameFromTNSNames',
    poolMax: 16
};

export default class Database {
    private pool: IConnectionPool;    
    constructor() {  
    }

    public createPool(): void {
        oracledb.createPool(config).then(conpool => {
                this.pool = conpool;
                console.log('Connection Pool created!');
            },
            err => {
                console.log('Error creating pool!');
            });
    }

    public getConnection() {
        return oracledb.getConnection();
    }    
}


Get this bounty!!!

#StackBounty: #asp.net #node.js #docker #docker-compose #dockerfile Docker copy from one container to another

Bounty: 50

I have this docker file:

FROM microsoft/aspnetcore:2.0-nanoserver-1709 AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/aspnetcore-build:2.0-nanoserver-1709 AS build
WORKDIR /src
COPY *.sln ./
COPY MyApp.Api/MyApp.Api.csproj MyApp.Api/
RUN dotnet restore
COPY . .
WORKDIR /src/MyApp.Api
RUN dotnet build -c Release -o /app

FROM build AS publish
RUN dotnet publish -c Release -o /app

FROM base AS final
copy --from=build["C:Program Filesnodejs", "C:nodejs"]
RUN SETX PATH "%PATH%;C:nodejs"
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "MyApp.Api.dll"]

And I want to copy nodejs from c:Program Filesnodejs on build to C:nodejs on final.
But when I build it i get this error:

Step 15/19 : copy –from=publish [“C:Program Filesnodejs”,
“C:nodejs”]

ERROR: Service ‘myapp.api’ failed to build:
failed to process “[“C:Program”: unexpected end of statement while
looking for matching double-quote

How can I copy nodejs from the build image to my final image?
Thanks


Get this bounty!!!

#StackBounty: #node.js #rest #file-upload #sftp NodeJS API sync uploaded files through SFTP

Bounty: 50

I have a NodeJS REST API which has endpoints for users to upload assets (mostly images). I distribute my assets through a CDN. How I do it right now is call my endpoint /assets/upload with a multipart form, the API creates the DB resource for the asset and then use SFTP to transfer the image to the CDN origin’s. Upon success I respond with the url of the uploaded asset.

I noticed that the most expensive operation for relatively small files is the connection to the origin through SFTP.

So my first question is:

1. Is it a bad idea to always keep the connection alive so that I can
always reuse it to sync my files.

My second question is:

2. Is it a bad idea to have my API handle the SFTP transfer to the CDN origin, should I consider having a CDN origin that could handle the HTTP request itself?


Get this bounty!!!

#StackBounty: #javascript #object-oriented #node.js #typescript Poker Holdem Hand Evaluation 7 cards to 5

Bounty: 200

I’m building a poker Hold’em hand evaluator. Ultimately my goal after building the evaluator is to build a client on the browser but that’s far from now.

What I’ve done so far is a hand analyzer that check checks hand strength but I’m unsure of the architecture I’ve chosen. Since this is going to be at the core of what I’ll build after I’d like to make the right decision from the get go.

Here is what is included:

  • Card: A card has a Suit (diamond) and a Rank ( ace).
  • Hand: A hand has cards[]. A hand actually represent the cards the player is holding + the cards on the board (which means that a hand has between 0 and n cards). A hand also has ranks[][] so when a 2 is placed in it it’s placed at ranks[0].push(2). It makes it easy to see if there are four of a kind, pairs, and sets.
  • HandEvaluator: evaluate a hand and return a WinningHand
  • WinningHand: representation of the winning hand with its strength.

So what I’m interested in being reviewed on is:

  • The architecture, class names I’ve chosen. Why something else would make more sense?
  • If you have time I’d like the logic for evaluating a hand to be reviewed as well. I think it’s a bit mind bending with the filterings etc. that happen.

Demo here .. all the files are under ./src/poker/


Card

export class Card {

    private static suits: string[] = [ 'h', 's', 'd', 'c' ];
    private static ranks: string[] = [ '2', '3', '4', '5', '6', '7', '8', '9', 'T',
                                                                        'J', 'Q', 'K', 'A' ];

    constructor(private _rank: Rank, private _suit: Suit) {
        if (this._rank >= Card.ranks.length)
            throw Error('A rank must be 0 and 12. ( Ace to king)');
        if (this._suit >= Card.suits.length)
            throw Error('A suit must be between 0 and 3 (h, s, d, c)')
    }

    toString() {
        return Card.ranks[this._rank] + Card.suits[this._suit];
    }

    static sortFn(a: Card, b: Card) {
        return b.rank - a.rank;
    }

    get suit() {
        return this._suit;
    }

    get rank() {
        return this._rank;
    }

    // transfor 4d, 7s type of strings to a new Card
    static fromString(str: string) {
        if (str.length !== 2)
            throw Error('Card length should be 2');

        const rank = Card.ranks.findIndex(x => x === str[0]);
        const suit = Card.suits.findIndex(x => x === str[1]);

        if (rank === -1 || suit === -1)
            throw Error(`Rank ${str[0]} or suit ${str[1]} was not found`);

        return new Card(rank, suit);
    }
}

Hand:

// the Hand class contains the player cards + board cards.
export class Hand {
    public cards: Card[] = [];
    // those two are used when evaluating a hand
    // take a look at evaluate hand for more details
    public suits: Card[][] = new Array(4).fill(0).map(_ => []);
    public ranks: Card[][] = new Array(13).fill(0).map(_ => []);

    constructor(cards: Card[] = []) {
        cards.forEach(card => this.addCard(card));
    }

    addCard(card: Card): Hand {
        if (this.cards.length > 7)
            throw Error('Hand containing board card must have max 7 cards. This is Hold'em');
        // precautious check to see that we can actually add the card (there shouldn't be two Ad in a deck for example)
        if (this.cards.some(c => c.toString() === card.toString()))
            throw Error('This card has already been added to this hand!');

        this.cards.push(card);
        // we are adding the suit and ranks to their respective array so we can easily
        // evaluate those.
        this.suits[card.suit].push(card);
        this.ranks[card.rank].push(card);
        return this;
    }

    evaluateHand() {
        // in hold'em poker there is 5 cards on board + 2 cards in hand.
        // for convenience, the Hand class contains the board cards as well
        if (this.cards.length < 7)
            throw new Error('When evaluating a hand, the hand must have 7 cards');

    }

    hasRank(rank: Rank) {
        return this.ranks[rank].length > 0;
    }

    // gives back a string representation of the hand of the form: 7d 6h 8s Js 9s Td As
    toString() {
        return this.cards.toString().replace(/,/g, ' ');
    }

    static fromString(str: String): Hand {
        const hand = new Hand();
        const cardsStr = str.split(' ');
        cardsStr.forEach(cardStr => {
            const card = Card.fromString(cardStr);
            hand.addCard(card);
        });
        return hand;
    }
}

Hand Evaluator

export class HandEvaluator {

    evaluateHand(hand: Hand): WinningHand {
        let winningCards: Card[] | undefined;
        if (winningCards = this.evaluateRoyalFlush(hand))
            return new WinningHand(winningCards, HandRank.ROYAL_FLUSH);
        if (winningCards = this.evaluateStraightFlush(hand))
            return new WinningHand(winningCards, HandRank.STRAIGHT_FLUSH);
        else if (winningCards = this.evaluateFourOfAKind(hand))
            return new WinningHand(winningCards, HandRank.FOUR_OF_A_KIND);
        else if (winningCards = this.evaluateFullHouse(hand))
            return new WinningHand(winningCards, HandRank.FULL_HOUSE);
        else if (winningCards = this.evaluateFlush(hand))
            return new WinningHand(winningCards, HandRank.FLUSH);
        else if (winningCards = this.evaluateStraight(hand))
            return new WinningHand(winningCards, HandRank.STRAIGHT);
        else if (winningCards = this.evaluateSet(hand))
            return new WinningHand(winningCards, HandRank.SET);
        else if (winningCards = this.evaluateDoublePair(hand))
            return new WinningHand(winningCards, HandRank.DOUBLE_PAIR);
        else if (winningCards = this.evaluatePair(hand))
            return new WinningHand(winningCards, HandRank.PAIR);
        else
            return new WinningHand(this.findHighests(5, hand.cards), HandRank.HIGH_CARD);
    }

    evaluateRoyalFlush(hand: Hand): Card[] | undefined {
        const straightFlush = this.evaluateStraightFlush(hand);
        if (straightFlush) {
            const sfHand = new Hand(straightFlush);
            if (sfHand.hasRank(Rank.ACE) && sfHand.hasRank(Rank.KING))
                return sfHand.cards;
        }
    }

    evaluateStraightFlush(hand: Hand): Card[] | undefined {
        let flush: any = this.evaluateFlush(hand, 7);
        let straightFlush;
        if (flush) {
            straightFlush = this.evaluateStraight(new Hand(flush));
        }
        return straightFlush;
    }

    // returns the biggest flush in a Hand
    evaluateFlush(hand: Hand, amount: number = 5): Card[] | undefined {
        // we need to remove other cards
        // originally the Suit is an enum but it's converted to a number
        // by typescript under the hood
        const flushCards = hand.suits.find( cardArr => cardArr.length >= 5);
        if (flushCards)
            return this.findHighests(amount, flushCards);
    }


    evaluateStraight(hand: Hand): Card[] | undefined {
        let consecutives: Card[] = [];
        const length = hand.ranks.length;
        // for A2345 we put the A already in the consecutive array
        if (hand.hasRank(Rank.ACE))
            consecutives.push(hand.ranks[Rank.ACE][0])

        // we loop through each rank in hand, if we find a group of card
        // we push the first one of the group into consecutives
        // if there is no card at said rank we reset consecutives.
        for (let i = 0; i < length; i++) {
            // we are only sure there is at least one card at that rank
            if (hand.hasRank(i))
                consecutives.push(hand.ranks[i][0]);
            else
                consecutives = [];
            // if we have 5 consecutives cards we still need to check
            // that there isn't anymore after
            if (consecutives.length >= 5) {
                const nextCards = hand.ranks[i + 1];
                if (nextCards && nextCards.length === 0) {
                    break;
                }
            }
        }
        if (consecutives.length >= 5)
            return consecutives.reverse().slice(0, 5);
    }

    evaluateFullHouse(hand: Hand): Card[] | undefined {
        const set = this.findHighestArr(3, hand);
        if (set){
            const pair = this.findHighestArr(2, hand, set[0]);
            if (pair)
                return [...set, ...pair];
        }
    }

    evaluateFourOfAKind(hand: Hand): Card[] | undefined {
        const four = hand.ranks.find(cardArr => cardArr.length === 4);
        if (four) {
            four.push(...this.findHighests(1, hand.cards, four));
            return four;
        }
    }

    evaluateSet(hand: Hand): Card[] | undefined {
        const set = this.findHighestArr(3, hand);
        if (set) {
            set.push(...this.findHighests(2, hand.cards, set));
            return set;
        }
    }

    evaluateDoublePair(hand: Hand): Card[] | undefined {
        const pair1 = this.findHighestArr(2, hand);
        let pair2;
        if (pair1)
            pair2 = this.findHighestArr(2, hand, pair1[0]);
        if (pair1 && pair2){
            const combination = [ ...pair1, ...pair2 ];
            return [...combination, ...this.findHighests(1, hand.cards, combination)]
        }
    }

    evaluatePair(hand: Hand): Card[] | undefined {
        const pair = this.findHighestArr(2, hand);
        if (pair) {
            pair.push(...this.findHighests(3, hand.cards, pair));
            return pair;
        }
    }

    findHighestArr(length: number, hand: Hand, omitted?: Card): Card[] | undefined {
        let ranksReverse = [...hand.ranks].reverse();
        // omit the ones we don't want by checking omitted rank and rank.firstcard.rank
        if (omitted)
            ranksReverse = ranksReverse.filter(arr => arr[0] && arr[0].rank !== omitted.rank);
        const set = ranksReverse
            .find(arr => arr.length >= length);
        if (set)
            return set.slice(0, length);
    }

    // get x highest number of cards
    findHighests(amount: number, cards: Card[] = [], omitted: Card[] = []): Card[] {
        // !~indexOf = not found
        const relevant =  (cards.filter(c => !~omitted.indexOf(c)) as Card[])
            .sort(Card.sortFn);
        return relevant.slice(0, amount);
    }


}

Winning Hand

// A hand consist of the cards the player is holding + the cards on board
// Which equals to 7 cards.
// A winning hand is the best possible combination of 5 cards from those 7 cards
export class WinningHand extends Hand{

    constructor(cards: Card[], public rank: HandRank) {
        super();
        super.cards = cards;
    }

    // If a hand has a rank of PAIR
    // we need to be able to compare it with another
    // wining hand that is also pair. Thus we need additional information,
    // like the high card, etc.
    // We will total 6 ranks
    calculateRanks(rank: HandRank){
        // TODO
    }
}

Also a few enums

export enum Suit {
    HEARTH,
    SPADE,
    DIAMOND,
    CLUB
}

export enum Rank {
    TWO,
    THREE,
    FOUR,
    FIVE,
    SIX,
    SEVEN,
    EIGHT,
    NINE,
    TEN,
    JACK,
    QUEEN,
    KING,
    ACE
}

export enum HandRank {
    HIGH_CARD,
    PAIR,
    DOUBLE_PAIR,
    SET,
    STRAIGHT,
    FLUSH,
    FULL_HOUSE,
    FOUR_OF_A_KIND,
    STRAIGHT_FLUSH,
    ROYAL_FLUSH,
}


Get this bounty!!!

#StackBounty: #javascript #node.js #api #express.js #proxy Node.js/Express middleware to relay requests to various APIs

Bounty: 100

I am creating a nodejs middleware server that will handle api transactions from a frontend and relay them to various api’s (internal and external). The primary goal is to hide api keys from the frontend. It can also consolidate requests that may require 2 or more endpoints, and modify data structures, thus simplifying our frontend code.

I am hoping for feedback on overall design/structure which will allow us to create a project that will be flexible as we add more apis while keeping it DRY

URLs, keys, etc. are stored in a .env file

index.js

require('dotenv').load();
const express = require('express'),
  app = express(),
  request = require("./request").request,
  bodyParser = require('body-parser');

app.use(bodyParser.json());

//returns all locations
app.get("/locations", (req, res) => {
  let URL = '...';
  request({
    method: 'get',
    url: URL,
    api: 'apiName'
  }).then((resp) => {
    res.json(resp);
  })
});

//send password reset link
app.post("/resetemail", (req, res) => {
  let URL = '...';
  let DATA = req.body;

  request({
    method: 'post',
    url: URL,
    api: 'apiName',
    data: DATA
  }).then((resp) => {
    res.json(resp);
  })
});

app.listen(3000);

request.js

module.exports.request = function (options) {

  const client = require('./' + options.api).instance;
  const handleError = require('./' + options.api).handleError;
  const onSuccess = function (response) {
    console.log('Request Successful!', response);
    return response.data;
  }

  return client(options)
    .then(onSuccess)
    .catch(handleError);
}

apiName.js

const axios = require('axios');
const axiosInstance = axios.create({
  headers: { "token": process.env.API_TOKEN },
  baseURL: process.env.API_BASE_URL,
  timeout: 2000
});

const handleError = function (error) {
  console.error('Request Failed:', error.config);

  if (error.response) {
    console.error('Status:', error.response.status);
    console.error('Data:', error.response.data);
    console.error('Headers:', error.response.headers);

  } else {
    console.error('Error Message:', error.message);
  }

  return Promise.reject(error.response || error.message);
}

module.exports = {
  instance: axiosInstance,
  handleError: handleError
}


Get this bounty!!!

#StackBounty: #node.js #promise #typescript #express.js #oracle Is my exception handling and releasing of oracledb connection done corr…

Bounty: 50

Before I start implementing several REST API service endpoints, I’d like to make sure that I’m not doing it totally wrong.

/**
 * GET /api/test
 * Test API example.
 */
export let getTest = (req: Request, res: Response, next: NextFunction) => {
    // const token = req.user.tokens.find((token: any) => token.kind === "facebook");
    const db = new Database();

    db.getConnection()
        .then(con => {
            con.execute('SELECT * FROM BTO_MDS.AlARMS', {}, { maxRows: 22000 })
                .then(result => {
                    con.release();
                    res.json({data: result.rows});
                })
                .catch(ex => {
                    con.release();
                    res.status(500).json({message: ex.message});
                });
        })
        .catch(ex => {
            res.status(500).json({message: ex.message});
        });

};
  • Is the connection always released properly, or I have forgotten something?

  • What seems a bit messy is that I need to release the connection two times, and that I have two catch’es, since I cannot release the connection in the second catch.

For completeness: Database is simply a wrapper that contains the connection string configuration and returns a reference to a new connection:

import * as oracledb from 'oracledb';
import { IConnectionPool } from 'oracledb';

const config = {
    user: 'user',
    password: 'pw',
    connectString: 'databaseNameFromTNSNames',
    poolMax: 16
};

export default class Database {
    private pool: IConnectionPool;    
    constructor() {  
    }

    public createPool(): void {
        oracledb.createPool(config).then(conpool => {
                this.pool = conpool;
                console.log('Connection Pool created!');
            },
            err => {
                console.log('Error creating pool!');
            });
    }

    public getConnection() {
        return oracledb.getConnection();
    }    
}


Get this bounty!!!

#StackBounty: #javascript #node.js #mongodb #mongoose #mongodb-query Query documents with conditions which are based on subdocuments

Bounty: 50

I have a room schema like this:

let roomSchema = new mongoose.Schema({
  events: [{type: mongoose.Schema.ObjectId, ref: 'Event'}],
  name: { type: String, required: true, index: { unique: true } }
});

It contains an array of event ids. Event schema:

let eventSchema = new mongoose.Schema({
  title: { type: String, required: true },
  room: { type: mongoose.Schema.ObjectId, ref: 'Room', required: true },
  date: { type: Date, required: true },
  slot: { type: Number, required: true }
});

What I am trying to do, is:
“query all rooms, that don’t contain events of a particular date AND slot“.

So if the date from the request matches the date of a room AND the slot, then that room should not be in the response. If only one of the fields match it should be in the response.

I found similar questions here, but none for my scenario:
https://stackoverflow.com/a/36371665/5115768
Mongoose query where value is not null

I tried something like:

this.model.find(req.query).populate({
  path: 'events',
  match: {
    date: { $ne: req.query.date },
    slot: { $ne: req.query.slot }
  }
}).exec((err, rooms) => {

  rooms = rooms.filter((room) => {
    return room.events != null;
  });

  res.status(200).json(rooms);
});

But of course it doesn’t work (rooms is always empty array). I have a really hard time figure this out.

How can I query documents (rooms) with conditions which are based on subdocuments (events)?

UPDATE

I changed my schema and code so that slot is not an array anymore.

If I understood @Veeram’s solution correctly, it can’t be used, because it would return empty events arrays for “reserved rooms”. The problem with this is that I need to filter out these rooms with empty events array, which would include rooms that didn’t have any events associated in the first place (these shouldn’t be filtered out).

Now I managed to get all “reserved rooms” (the ones that contain an event that matches req.query.date AND req.query.slot):

this.model.find(req.query).populate({
  path: 'events',
  match: {
    $and: [
      { date: { $eq: date } },
      { slot: { $eq: slot } }
    ]
  }
}).exec((err, reservedRooms) => {
  reservedRooms = reservedRooms.filter(room => room.events.length > 0);
  res.status(200).json(reservedRooms);
});

This is the exact opposite of what I want but it’s a start, how can I “reverse” that?


Get this bounty!!!

#StackBounty: #node.js #express #session #authentication #passport.js PassportJs isAuthenticated not Authenticating

Bounty: 200

I have PassportJS setup with Google+ Login.

The Google authentication seems to work fine but when I redirect to a page that only an authenticated user should have access to. Passport’s isAuthenticated() function always seems to return false

I’ve seen people mention that you should be able to find the user by console logging: req.session.passport.user but when I console log req.session all I get is:

  sessionID: 'Q5NaeyfnAphOK633tKjiGnbbex0KJj7e',
  session:
   Session {
     cookie:
      { path: '/',
        _expires: null,
        originalMaxAge: null,
        httpOnly: true } },

Google Callback route:

router.get("/google/callback", function(req, res, next) {
    passport.authenticate("google", function(err, user, info) {
        req.session.save(()=>{
            res.redirect("/api/v1/dashboard");
            console.log("after Passport AUTH");
        });
    })(req, res, next);
});

Note: I’ve added a manual req.session.save() to ensure that the session is being saved.

Dashboard route:

router.get("/", middleware.isLoggedIn , function(req, res) {
    console.log("Request: Get All Dashboard Data!");
    models.PortfolioBalance.findAll({ raw: true }).then(function(
        portfolioBalance
    ) {
        res.render("dashboard/index", { portfoliobalances: portfolioBalance });
    });
});

Middleware module:

module.exports = {
    isLoggedIn: function(req, res, next) {
        console.log("===========================================");
        console.log("isAuthenticated: ", req.isAuthenticated);
        console.log("===========================================");
        if (req.isAuthenticated()) {
            return next();
        }
        console.log("not authenticated");
        res.redirect("/login");
    }
};

Serialise and De-Serialise:

//  used to serialize the user for the session
passport.serializeUser(function(user, done) {
    console.log("SerializeUser:", models.User.userId);
    done(null, user.id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    console.log("deserializeUser:", models.User.userId);
    models.User.findOne({ where: { userId: id } }).then(function(
        err,
        user
    ) {
        done(err, user);
    });
});

Potential Issue:

  • Could it be an issue with passportJS not serialising and deserialising properly? Why? because I never see the console.log messages being run at any point during the authentication process.


Get this bounty!!!