feat: Refresh Token for improved Session Security (#927)

* feat(api): refresh token logic

* feat(client): refresh token logic

* feat(data-provider): refresh token logic

* fix: SSE uses esm

* chore: add default refresh token expiry to AuthService, add message about env var not set when generating a token

* chore: update scripts to more compatible bun methods, ran bun install again

* chore: update env.example and playwright workflow with JWT_REFRESH_SECRET

* chore: update breaking changes docs

* chore: add timeout to url visit

* chore: add default SESSION_EXPIRY in generateToken logic, add act script for testing github actions

* fix(e2e): refresh automatically in development environment to pass e2e tests
This commit is contained in:
Danny Avila 2023-09-11 13:10:46 -04:00 committed by GitHub
parent 75be9a3279
commit 33f087d38f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 420 additions and 232 deletions

View file

@ -1,17 +1,15 @@
const passport = require('passport');
const express = require('express');
const router = express.Router();
const { loginLimiter } = require('../middleware');
const config = require('../../../config/loader');
const { setAuthTokens } = require('../services/AuthService');
const domains = config.domains;
const isProduction = config.isProduction;
/**
* Google Routes
*/
router.get(
'/google',
loginLimiter,
passport.authenticate('google', {
scope: ['openid', 'profile', 'email'],
session: false,
@ -26,20 +24,18 @@ router.get(
session: false,
scope: ['openid', 'profile', 'email'],
}),
(req, res) => {
const token = req.user.generateToken();
res.cookie('token', token, {
expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)),
httpOnly: false,
secure: isProduction,
});
res.redirect(domains.client);
async (req, res) => {
try {
await setAuthTokens(req.user._id, res);
res.redirect(domains.client);
} catch (err) {
console.error('Error in setting authentication tokens:', err);
}
},
);
router.get(
'/facebook',
loginLimiter,
passport.authenticate('facebook', {
scope: ['public_profile'],
profileFields: ['id', 'email', 'name'],
@ -56,20 +52,18 @@ router.get(
scope: ['public_profile'],
profileFields: ['id', 'email', 'name'],
}),
(req, res) => {
const token = req.user.generateToken();
res.cookie('token', token, {
expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)),
httpOnly: false,
secure: isProduction,
});
res.redirect(domains.client);
async (req, res) => {
try {
await setAuthTokens(req.user._id, res);
res.redirect(domains.client);
} catch (err) {
console.error('Error in setting authentication tokens:', err);
}
},
);
router.get(
'/openid',
loginLimiter,
passport.authenticate('openid', {
session: false,
}),
@ -82,20 +76,18 @@ router.get(
failureMessage: true,
session: false,
}),
(req, res) => {
const token = req.user.generateToken();
res.cookie('token', token, {
expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)),
httpOnly: false,
secure: isProduction,
});
res.redirect(domains.client);
async (req, res) => {
try {
await setAuthTokens(req.user._id, res);
res.redirect(domains.client);
} catch (err) {
console.error('Error in setting authentication tokens:', err);
}
},
);
router.get(
'/github',
loginLimiter,
passport.authenticate('github', {
scope: ['user:email', 'read:user'],
session: false,
@ -110,20 +102,17 @@ router.get(
session: false,
scope: ['user:email', 'read:user'],
}),
(req, res) => {
const token = req.user.generateToken();
res.cookie('token', token, {
expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)),
httpOnly: false,
secure: isProduction,
});
res.redirect(domains.client);
async (req, res) => {
try {
await setAuthTokens(req.user._id, res);
res.redirect(domains.client);
} catch (err) {
console.error('Error in setting authentication tokens:', err);
}
},
);
router.get(
'/discord',
loginLimiter,
passport.authenticate('discord', {
scope: ['identify', 'email'],
session: false,
@ -138,14 +127,13 @@ router.get(
session: false,
scope: ['identify', 'email'],
}),
(req, res) => {
const token = req.user.generateToken();
res.cookie('token', token, {
expires: new Date(Date.now() + eval(process.env.SESSION_EXPIRY)),
httpOnly: false,
secure: isProduction,
});
res.redirect(domains.client);
async (req, res) => {
try {
await setAuthTokens(req.user._id, res);
res.redirect(domains.client);
} catch (err) {
console.error('Error in setting authentication tokens:', err);
}
},
);