Add feature to generate refresh token
This commit is contained in:
21
package-lock.json
generated
21
package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"better-sqlite3": "^8.1.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"check-password-strength": "^2.0.7",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"express": "^4.18.2",
|
||||
@@ -2583,6 +2584,26 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz",
|
||||
"integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==",
|
||||
"dependencies": {
|
||||
"cookie": "0.4.1",
|
||||
"cookie-signature": "1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser/node_modules/cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"better-sqlite3": "^8.1.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"check-password-strength": "^2.0.7",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.0.3",
|
||||
"express": "^4.18.2",
|
||||
|
||||
@@ -7,6 +7,7 @@ const {
|
||||
checkPasswordStrength,
|
||||
comparePasswords,
|
||||
generateToken,
|
||||
decodeToken,
|
||||
} = require('../utils');
|
||||
|
||||
const createDefaultTables = async () => {
|
||||
@@ -227,7 +228,7 @@ const obtainAccessToken = async (req, res) => {
|
||||
const payload = {
|
||||
username: user.username,
|
||||
userId: user.id,
|
||||
roleId: usersRole.role_id,
|
||||
roleId: usersRole[0].role_id,
|
||||
};
|
||||
|
||||
// generate an access token
|
||||
@@ -259,9 +260,61 @@ const obtainAccessToken = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
const refreshAccessToken = async (req, res) => {
|
||||
try {
|
||||
// extract the payload from the token and verify it
|
||||
const payload = await decodeToken(
|
||||
req.cookies.refreshToken,
|
||||
config.jwtSecret,
|
||||
);
|
||||
|
||||
// find the user
|
||||
const users = rowService.get({
|
||||
tableName: '_users',
|
||||
whereString: 'WHERE id=?',
|
||||
whereStringValues: [payload.userId],
|
||||
});
|
||||
|
||||
if (users.length <= 0) {
|
||||
return res.status(401).send({ message: 'User not found' });
|
||||
}
|
||||
|
||||
const user = users[0];
|
||||
|
||||
const newPaylod = {
|
||||
username: payload.username,
|
||||
userId: payload.userId,
|
||||
roleId: payload.roleId,
|
||||
};
|
||||
// generate an access token
|
||||
const accessToken = await generateToken(
|
||||
{ subject: 'accessToken', ...newPaylod },
|
||||
config.jwtSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
// generate a refresh token
|
||||
const refreshToken = await generateToken(
|
||||
{ subject: 'refreshToken', ...newPaylod },
|
||||
config.jwtSecret,
|
||||
config.jwtExpirationTime,
|
||||
);
|
||||
|
||||
// set the token in the cookie
|
||||
let cookieOptions = { httpOnly: true, secure: false, Path: '/' };
|
||||
res.cookie('accessToken', accessToken, cookieOptions);
|
||||
res.cookie('refreshToken', refreshToken, cookieOptions);
|
||||
|
||||
res.status(201).send({ message: 'Success', data: { userId: user.id } });
|
||||
} catch (error) {
|
||||
res.status(401).send({ message: 'Invalid refresh token' });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
createDefaultTables,
|
||||
updateUser,
|
||||
registerUser,
|
||||
obtainAccessToken,
|
||||
refreshAccessToken,
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ const expressWinston = require('express-winston');
|
||||
const cors = require('cors');
|
||||
const rateLimit = require('express-rate-limit');
|
||||
const swaggerUi = require('swagger-ui-express');
|
||||
const cookieParser = require('cookie-parser');
|
||||
|
||||
const config = require('./config/index');
|
||||
const db = require('./db/index');
|
||||
@@ -29,6 +30,7 @@ app.get('/health', (req, res) => {
|
||||
});
|
||||
|
||||
app.use(bodyParser.json());
|
||||
app.use(cookieParser());
|
||||
|
||||
// Activate wal mode
|
||||
db.exec('PRAGMA journal_mode = WAL');
|
||||
|
||||
@@ -11,4 +11,10 @@ router.post(
|
||||
controllers.obtainAccessToken,
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/token/refresh',
|
||||
validator(schema.refreshAccessToken),
|
||||
controllers.refreshAccessToken,
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@@ -12,6 +12,13 @@ const obtainAccessToken = Joi.object({
|
||||
}).required(),
|
||||
});
|
||||
|
||||
const refreshAccessToken = Joi.object({
|
||||
query: Joi.object().required(),
|
||||
params: Joi.object({}).required(),
|
||||
body: Joi.object({}).required(),
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
obtainAccessToken,
|
||||
refreshAccessToken,
|
||||
};
|
||||
|
||||
@@ -468,6 +468,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/auth/token/refresh": {
|
||||
"get": {
|
||||
"description": "",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"400": {
|
||||
"description": "Bad Request"
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
||||
Reference in New Issue
Block a user