// This is a very simple example of Passport.JS
    // with the express-session library.

// Start with standard Express boilerplate.
const express  = require('express');
const app = express();

// The following two lines enable sessions.
// Every client will be assigned a cookie with
// a unique session id (req.sessionID).
// and data for each client will be stored locally.    

// Do not use the following code in production.
// Visit ExpressJS.com for better documentation.
const session  = require('express-session');
app.use(session({secret:'secret string'}));

// Passport can authenticate users via various methods.
// For this demo, we'll use the local strategy.
// Passport takes a username and password from the client and then
// it's up to you to write the code that determines if they're legit.
    
// Import the Passport modules.
const passport = require('passport');
const LocalStrategy = require('passport-local');

// Enable Passport to use sessions.
app.use(passport.authenticate('session'));

// Define a custom verification function.
// It gets a username, password and a callback function.
// You determine if the username and password are legit
// and return the value from the callback function.

// If there's an error, pass an error message in the first argument.
// E.g. cb('This is an error') .

// If, the credentials are invalid, simply call the callback
// with a false value for the second argument.

// Otherwise, call it with a unique value for the second argument
// which is associated with the verified user. This value will be
// stored in a session. You can access this value via req.user .

// Please don't use this code for production.
const passwords = {
  jon:1234,
  jan:4567
}
  
function verify(username, password, cb) {
  console.log('verifying...');
  if (passwords[username] == password) {
    return cb(null, username); // right password
  } else {
    return cb(null, false); // wrong password
  }
}
  
passport.use(new LocalStrategy(verify));


// serializeUser stores data for this user in a session.
passport.serializeUser(function(user, cb) {
  console.log('serializeUser...');
  console.log('user='+user);
  process.nextTick(function() {
    cb(null, user);
  });
});

// And deserializeUser retrieves session data for this user.
passport.deserializeUser(function(user, cb) {
  console.log('deserializeUser...');
  console.log('user='+user);
  process.nextTick(function() {
    return cb(null, user);
  });
});


// And here are the routes.
app.get('/', (req, res) => {
  
  if (req.user) {
    
    res.send(`<pre>
You are logged in.

req.isAuthenticated() = ${req.isAuthenticated()}

req.user = ${req.user}

req.session = ${JSON.stringify(req.session,null,1)}

<form action="/Logout" method="post">
<button type="submit">Logout</button>
</form>

</pre>`)
    
  } else {

  res.send(`<pre>
This is a simple example of PassportJS.

Your session id is ${req.sessionID}.

You can log in as ${Object.entries(passwords).map(x=>`username ${x[0]} and password ${x[1]}`).join(' or \n')}.

<form action="/Login" method="post">
 <label for="username">Username</label>
 <input id="username" name="username" type="text" required autofocus>

 <label for="current-password">Password</label>
 <input id="current-password" name="password" type="password" required>

 <button type="submit">Login</button>
</form>
</pre>`);
    
  }
});


app.post('/Login', 
  express.urlencoded(),
  passport.authenticate('local', {
    failureRedirect: '/Bad',
    successRedirect: '/'
  }));


app.get('/Bad', (req, res) => res.send(`<pre>
Failed.

<a href="/">Try again.</a>
</pre>`));


app.post('/Logout', (req, res, next) => {
  req.logout(err => {
    if (err) return next(err) ;
    res.redirect('/');
  });
});


app.listen(8000, ()=>console.log('listening on port 8000'));


// https://sean.brunnock.com  12/2022