test: session.middleware

This commit is contained in:
Nicolas Meienberger 2023-05-05 21:52:30 +02:00 committed by Nicolas Meienberger
parent 10f3c9efcf
commit b7bb09a770
5 changed files with 154 additions and 9 deletions

View file

@ -101,6 +101,7 @@
"@types/react": "18.0.28",
"@types/react-dom": "18.0.11",
"@types/semver": "^7.3.12",
"@types/supertest": "^2.0.12",
"@types/testing-library__jest-dom": "^5.14.5",
"@types/uuid": "^9.0.1",
"@types/validator": "^13.7.14",
@ -130,6 +131,7 @@
"next-router-mock": "^0.9.2",
"nodemon": "^2.0.21",
"prettier": "^2.8.4",
"supertest": "^6.3.3",
"ts-jest": "^29.0.3",
"ts-node": "^10.9.1",
"typescript": "5.0.2",

View file

@ -219,6 +219,9 @@ devDependencies:
'@types/semver':
specifier: ^7.3.12
version: 7.3.13
'@types/supertest':
specifier: ^2.0.12
version: 2.0.12
'@types/testing-library__jest-dom':
specifier: ^5.14.5
version: 5.14.5
@ -306,6 +309,9 @@ devDependencies:
prettier:
specifier: ^2.8.4
version: 2.8.4
supertest:
specifier: ^6.3.3
version: 6.3.3
ts-jest:
specifier: ^29.0.3
version: 29.0.5(@babel/core@7.21.3)(esbuild@0.16.17)(jest@29.5.0)(typescript@5.0.2)
@ -2384,6 +2390,10 @@ packages:
resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==}
dev: true
/@types/cookiejar@2.1.2:
resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==}
dev: true
/@types/debug@4.1.7:
resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
dependencies:
@ -2579,6 +2589,19 @@ packages:
resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
dev: true
/@types/superagent@4.1.17:
resolution: {integrity: sha512-FFK/rRjNy24U6J1BvQkaNWu2ohOIF/kxRQXRsbT141YQODcOcZjzlcc4DGdI2SkTa0rhmF+X14zu6ICjCGIg+w==}
dependencies:
'@types/cookiejar': 2.1.2
'@types/node': 18.15.3
dev: true
/@types/supertest@2.0.12:
resolution: {integrity: sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==}
dependencies:
'@types/superagent': 4.1.17
dev: true
/@types/testing-library__jest-dom@5.14.5:
resolution: {integrity: sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==}
dependencies:
@ -3082,6 +3105,10 @@ packages:
get-intrinsic: 1.2.0
dev: true
/asap@2.0.6:
resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
dev: true
/asn1.js@5.4.1:
resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==}
dependencies:
@ -3575,6 +3602,10 @@ packages:
engines: {node: '>= 12.0.0'}
dev: true
/component-emitter@1.3.0:
resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==}
dev: true
/concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@ -3627,6 +3658,10 @@ packages:
engines: {node: '>= 0.6'}
dev: false
/cookiejar@2.1.4:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
dev: true
/copy-anything@3.0.3:
resolution: {integrity: sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw==}
engines: {node: '>=12.13'}
@ -3848,6 +3883,13 @@ packages:
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
dev: false
/dezalgo@1.0.4:
resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==}
dependencies:
asap: 2.0.6
wrappy: 1.0.2
dev: true
/diff-sequences@29.4.3:
resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@ -5068,6 +5110,10 @@ packages:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
dev: true
/fast-safe-stringify@2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
dev: true
/fastq@1.15.0:
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
dependencies:
@ -5185,6 +5231,15 @@ packages:
fetch-blob: 3.2.0
dev: false
/formidable@2.1.2:
resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==}
dependencies:
dezalgo: 1.0.4
hexoid: 1.0.0
once: 1.4.0
qs: 6.11.0
dev: true
/forwarded@0.2.0:
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
engines: {node: '>= 0.6'}
@ -5493,6 +5548,11 @@ packages:
resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==}
dev: true
/hexoid@1.0.0:
resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==}
engines: {node: '>=8'}
dev: true
/hoist-non-react-statics@3.3.2:
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
dependencies:
@ -6916,7 +6976,6 @@ packages:
/methods@1.1.2:
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
engines: {node: '>= 0.6'}
dev: false
/micromark-core-commonmark@1.0.6:
resolution: {integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==}
@ -7191,6 +7250,12 @@ packages:
hasBin: true
dev: false
/mime@2.6.0:
resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==}
engines: {node: '>=4.0.0'}
hasBin: true
dev: true
/mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
@ -7965,7 +8030,6 @@ packages:
engines: {node: '>=0.6'}
dependencies:
side-channel: 1.0.4
dev: false
/querystringify@2.2.0:
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
@ -8753,6 +8817,24 @@ packages:
resolution: {integrity: sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==}
dev: false
/superagent@8.0.9:
resolution: {integrity: sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==}
engines: {node: '>=6.4.0 <13 || >=14'}
dependencies:
component-emitter: 1.3.0
cookiejar: 2.1.4
debug: 4.3.4
fast-safe-stringify: 2.1.1
form-data: 4.0.0
formidable: 2.1.2
methods: 1.1.2
mime: 2.6.0
qs: 6.11.0
semver: 7.3.8
transitivePeerDependencies:
- supports-color
dev: true
/superjson@1.12.2:
resolution: {integrity: sha512-ugvUo9/WmvWOjstornQhsN/sR9mnGtWGYeTxFuqLb4AiT4QdUavjGFRALCPKWWnAiUJ4HTpytj5e0t5HoMRkXg==}
engines: {node: '>=10'}
@ -8760,6 +8842,16 @@ packages:
copy-anything: 3.0.3
dev: false
/supertest@6.3.3:
resolution: {integrity: sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==}
engines: {node: '>=6.4.0'}
dependencies:
methods: 1.1.2
superagent: 8.0.9
transitivePeerDependencies:
- supports-color
dev: true
/supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}

View file

@ -0,0 +1,28 @@
import { getAuthedPageProps } from '../page-helpers';
describe('getAuthedPageProps', () => {
it('should redirect to /login if there is no user id in session', async () => {
// arrange
const ctx = { req: { session: {} } };
// act
// @ts-expect-error - we're passing in a partial context
const { redirect } = await getAuthedPageProps(ctx);
// assert
expect(redirect.destination).toBe('/login');
expect(redirect.permanent).toBe(false);
});
it('should return props if there is a user id in session', async () => {
// arrange
const ctx = { req: { session: { userId: '123' } } };
// act
// @ts-expect-error - we're passing in a partial context
const { props } = await getAuthedPageProps(ctx);
// assert
expect(props).toEqual({});
});
});

View file

@ -0,0 +1,22 @@
import request from 'supertest';
import express from 'express';
import { sessionMiddleware } from './session.middleware';
describe('Session Middleware', () => {
it('should redirect to /login if there is no user id in session', async () => {
// arrange
let session;
const app = express();
app.use(sessionMiddleware);
app.use('/test', (req, res) => {
session = req.session;
res.send('ok');
});
// act
await request(app).get('/test');
// assert
expect(session).toHaveProperty('cookie');
});
});

View file

@ -7,7 +7,6 @@ import { AuthQueries } from '@/server/queries/auth/auth.queries';
import { Context } from '@/server/context';
import { getConfig } from '../../core/TipiConfig';
import TipiCache from '../../core/TipiCache';
import { Logger } from '../../core/Logger';
import { fileExists, unlinkFile } from '../../common/fs.helpers';
import { decrypt, encrypt } from '../../utils/encryption';
@ -346,12 +345,14 @@ export class AuthServiceClass {
* @param {number} userId - The user ID
*/
private destroyAllSessionsByUserId = async (userId: number) => {
await TipiCache.getByPrefix(`session:${userId}:`).then((sessions) => {
sessions.forEach((session) => {
TipiCache.del(session.key).then(() => Logger.info('Session deleted'));
TipiCache.del(`tipi:${session.val}`).then(() => Logger.info('Session key deleted'));
});
});
const sessions = await TipiCache.getByPrefix(`session:${userId}:`);
await Promise.all(
sessions.map(async (session) => {
await TipiCache.del(session.key);
await TipiCache.del(`tipi:${session.val}`);
}),
);
};
public changePassword = async (params: { currentPassword: string; newPassword: string; userId: number }) => {