From 2b809e2fb014f74c78ce69178b6d48b4618eed17 Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 19 Nov 2024 17:26:02 +0100 Subject: [PATCH 1/4] feat(VIL-621): adding new archive mode --- next.config.js | 3 +++ src/components/accueil/Accueil.tsx | 13 +++++++++++-- src/components/activities/List.tsx | 10 +++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/next.config.js b/next.config.js index d1907f919..4245ef732 100644 --- a/next.config.js +++ b/next.config.js @@ -6,6 +6,9 @@ const BUILD_VERSION = process.env.BUILD_VERSION; // eslint-disable-next-line no-undef module.exports = withTM({ + env: { + ARCHIVE_MODE: process.env.ARCHIVE_MODE || 'false', + }, distDir: './dist/next', poweredByHeader: false, webpack: (config) => { diff --git a/src/components/accueil/Accueil.tsx b/src/components/accueil/Accueil.tsx index d5037fb09..437250f52 100644 --- a/src/components/accueil/Accueil.tsx +++ b/src/components/accueil/Accueil.tsx @@ -27,10 +27,19 @@ export const Accueil = () => { const router = useRouter(); const [withPagination, setWithPagination] = React.useState(true); + //Check if the app is in archive mode React.useEffect(() => { + const isArchiveMode = process.env.NEXT_PUBLIC_ARCHIVE_MODE === 'true'; + if (isArchiveMode) { + setWithPagination(false); + return; + } + if (!router.isReady) return; - setWithPagination(!('nopagination' in router.query)); - }, [router.isReady, router.query]); + const urlParams = new URLSearchParams(window.location.search); + const noPagination = urlParams.has('nopagination'); + setWithPagination(!noPagination); + }, [router.isReady]); //TODO: redo conditions and switchs const filterCountries = React.useMemo(() => { diff --git a/src/components/activities/List.tsx b/src/components/activities/List.tsx index 01da6caa5..c81e86130 100644 --- a/src/components/activities/List.tsx +++ b/src/components/activities/List.tsx @@ -76,10 +76,18 @@ export const Activities = ({ activities, noButtons = false, withLinks = false, w const [usePagination, setUsePagination] = React.useState(withPagination); React.useEffect(() => { + const isArchiveMode = process.env.NEXT_PUBLIC_ARCHIVE_MODE === 'true'; + if (isArchiveMode) { + setUsePagination(false); + return; + } + if (!router.isReady) { return; } - setUsePagination(!('nopagination' in router.query)); + const urlParams = new URLSearchParams(window.location.search); + const noPagination = urlParams.has('nopagination'); + setUsePagination(!noPagination); }, [router.isReady, router.query, withPagination]); React.useEffect(() => { From 0bbc3d19fd2ffc43fd28b4628343e6fb4dbebdfd Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 19 Nov 2024 17:30:18 +0100 Subject: [PATCH 2/4] fix lint error --- server/controllers/analytic.ts | 6 +++--- server/h5p/get-h5p-router.ts | 8 ++++---- server/middlewares/authenticate.ts | 2 +- server/middlewares/handleErrors.ts | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server/controllers/analytic.ts b/server/controllers/analytic.ts index d70256379..4bc60e959 100644 --- a/server/controllers/analytic.ts +++ b/server/controllers/analytic.ts @@ -278,8 +278,8 @@ analyticController.router.post( // Retrieve current user session or save the new one. // eslint-disable-next-line prefer-const let [sessionCount, userPhase] = await Promise.all([ - AppDataSource.getRepository(AnalyticSession).count({ where: { id: data.sessionId } }), - AppDataSource.getRepository(User).createQueryBuilder('user').select('user.firstlogin').where({ id: data.userId }).getRawOne(), + AppDataSource.getRepository(AnalyticSession).count({where: {id: data.sessionId}}), + AppDataSource.getRepository(User).createQueryBuilder('user').select('user.firstlogin').where({id: data.userId}).getRawOne(), ]); if (sessionCount === 0 && data.event === 'pageview' && data.params?.isInitial) { @@ -331,7 +331,7 @@ analyticController.router.post( pagePerf.data = data.params.perf as BrowserPerf; AppDataSource.getRepository(AnalyticPerformance).save(pagePerf).catch(); // no need to wait } else if (data.event === 'session' && data.params?.duration) { - AppDataSource.getRepository(AnalyticSession).update({ id: data.sessionId }, { duration: data.params?.duration }).catch(); // no need to wait + AppDataSource.getRepository(AnalyticSession).update({id: data.sessionId}, {duration: data.params?.duration}).catch(); // no need to wait } } catch (e) { logger.error(e); diff --git a/server/h5p/get-h5p-router.ts b/server/h5p/get-h5p-router.ts index bd27ec81f..9b83ca577 100644 --- a/server/h5p/get-h5p-router.ts +++ b/server/h5p/get-h5p-router.ts @@ -220,14 +220,14 @@ export const getH5pRouter = async () => { res.status(400).send('Malformed request'); return; } - const { id: contentId, metadata } = await h5pEditor.saveOrUpdateContentReturnMetaData( + const {id: contentId, metadata} = await h5pEditor.saveOrUpdateContentReturnMetaData( undefined as unknown as string, req.body.params.params, req.body.params.metadata, req.body.library, req.user as unknown as H5pUser, ); - res.status(200).json({ contentId, metadata }); + res.status(200).json({contentId, metadata}); }), ); @@ -238,14 +238,14 @@ export const getH5pRouter = async () => { res.status(400).send('Malformed request'); return; } - const { id: contentId, metadata } = await h5pEditor.saveOrUpdateContentReturnMetaData( + const {id: contentId, metadata} = await h5pEditor.saveOrUpdateContentReturnMetaData( req.params.contentId, req.body.params.params, req.body.params.metadata, req.body.library, req.user as unknown as H5pUser, ); - res.status(200).sendJSON({ contentId, metadata }); + res.status(200).sendJSON({contentId, metadata}); }), ); diff --git a/server/middlewares/authenticate.ts b/server/middlewares/authenticate.ts index 758938c33..9df9634c1 100644 --- a/server/middlewares/authenticate.ts +++ b/server/middlewares/authenticate.ts @@ -9,7 +9,7 @@ import { AppDataSource } from '../utils/data-source'; const secret: string = process.env.APP_SECRET || ''; -export function authenticate(userType: UserType | undefined = undefined): RequestHandler { +export function authenticate(userType?: UserType | UserType[] | undefined) { return async (req: Request, res: Response, next: NextFunction): Promise => { let token: string; if (req.cookies && req.cookies['access-token']) { diff --git a/server/middlewares/handleErrors.ts b/server/middlewares/handleErrors.ts index 37b32cf54..40b6aed12 100644 --- a/server/middlewares/handleErrors.ts +++ b/server/middlewares/handleErrors.ts @@ -31,7 +31,7 @@ interface PromiseRequestHandler extends RequestHandler { (req: Request, res: Response, next: NextFunction): Promise | void; } -export function handleErrors(fn: RequestHandler): RequestHandler { +export function handleErrors(fn) { return (req: Request, res: Response, next: NextFunction): void => { const sendError = (err: Error | AppError): void => { logger.error(err.message); From 5884399f863bd8a8c77b74f663cec1c882ae5d49 Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 19 Nov 2024 17:35:05 +0100 Subject: [PATCH 3/4] fix linter --- next.config.js | 1 + server/controllers/analytic.ts | 6 +++--- server/h5p/get-h5p-router.ts | 8 ++++---- server/middlewares/authenticate.ts | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/next.config.js b/next.config.js index 4245ef732..56d4be959 100644 --- a/next.config.js +++ b/next.config.js @@ -7,6 +7,7 @@ const BUILD_VERSION = process.env.BUILD_VERSION; // eslint-disable-next-line no-undef module.exports = withTM({ env: { + // eslint-disable-next-line no-undef ARCHIVE_MODE: process.env.ARCHIVE_MODE || 'false', }, distDir: './dist/next', diff --git a/server/controllers/analytic.ts b/server/controllers/analytic.ts index 4bc60e959..d70256379 100644 --- a/server/controllers/analytic.ts +++ b/server/controllers/analytic.ts @@ -278,8 +278,8 @@ analyticController.router.post( // Retrieve current user session or save the new one. // eslint-disable-next-line prefer-const let [sessionCount, userPhase] = await Promise.all([ - AppDataSource.getRepository(AnalyticSession).count({where: {id: data.sessionId}}), - AppDataSource.getRepository(User).createQueryBuilder('user').select('user.firstlogin').where({id: data.userId}).getRawOne(), + AppDataSource.getRepository(AnalyticSession).count({ where: { id: data.sessionId } }), + AppDataSource.getRepository(User).createQueryBuilder('user').select('user.firstlogin').where({ id: data.userId }).getRawOne(), ]); if (sessionCount === 0 && data.event === 'pageview' && data.params?.isInitial) { @@ -331,7 +331,7 @@ analyticController.router.post( pagePerf.data = data.params.perf as BrowserPerf; AppDataSource.getRepository(AnalyticPerformance).save(pagePerf).catch(); // no need to wait } else if (data.event === 'session' && data.params?.duration) { - AppDataSource.getRepository(AnalyticSession).update({id: data.sessionId}, {duration: data.params?.duration}).catch(); // no need to wait + AppDataSource.getRepository(AnalyticSession).update({ id: data.sessionId }, { duration: data.params?.duration }).catch(); // no need to wait } } catch (e) { logger.error(e); diff --git a/server/h5p/get-h5p-router.ts b/server/h5p/get-h5p-router.ts index 9b83ca577..bd27ec81f 100644 --- a/server/h5p/get-h5p-router.ts +++ b/server/h5p/get-h5p-router.ts @@ -220,14 +220,14 @@ export const getH5pRouter = async () => { res.status(400).send('Malformed request'); return; } - const {id: contentId, metadata} = await h5pEditor.saveOrUpdateContentReturnMetaData( + const { id: contentId, metadata } = await h5pEditor.saveOrUpdateContentReturnMetaData( undefined as unknown as string, req.body.params.params, req.body.params.metadata, req.body.library, req.user as unknown as H5pUser, ); - res.status(200).json({contentId, metadata}); + res.status(200).json({ contentId, metadata }); }), ); @@ -238,14 +238,14 @@ export const getH5pRouter = async () => { res.status(400).send('Malformed request'); return; } - const {id: contentId, metadata} = await h5pEditor.saveOrUpdateContentReturnMetaData( + const { id: contentId, metadata } = await h5pEditor.saveOrUpdateContentReturnMetaData( req.params.contentId, req.body.params.params, req.body.params.metadata, req.body.library, req.user as unknown as H5pUser, ); - res.status(200).sendJSON({contentId, metadata}); + res.status(200).sendJSON({ contentId, metadata }); }), ); diff --git a/server/middlewares/authenticate.ts b/server/middlewares/authenticate.ts index 9df9634c1..5b9b56721 100644 --- a/server/middlewares/authenticate.ts +++ b/server/middlewares/authenticate.ts @@ -1,4 +1,4 @@ -import type { NextFunction, Request, RequestHandler, Response } from 'express'; +import type { NextFunction, Request, Response } from 'express'; import jwt from 'jsonwebtoken'; import { getNewAccessToken } from '../authentication/lib/tokens'; From ed3600c776c5544d62d41e6f912afc2844ce8e33 Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 21 Nov 2024 10:41:01 +0100 Subject: [PATCH 4/4] fix: ts errors --- server/controllers/archive.ts | 22 ++++++++++------------ server/controllers/controller.ts | 2 +- server/middlewares/authenticate.ts | 6 +++--- server/middlewares/handleErrors.ts | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/server/controllers/archive.ts b/server/controllers/archive.ts index 0d08f3019..57b5770b6 100644 --- a/server/controllers/archive.ts +++ b/server/controllers/archive.ts @@ -6,20 +6,18 @@ import { streamFile } from '../fileUpload/streamFile'; import { Controller } from './controller'; const archiveController = new Controller('/archives'); +const userType = UserType.SUPER_ADMIN || UserType.ADMIN || UserType.MEDIATOR; // get file -archiveController.get( - { path: '/*', userType: [UserType.SUPER_ADMIN, UserType.ADMIN, UserType.MEDIATOR] }, - async (req: Request, res: Response, next: NextFunction) => { - const url = decodeURI(req.url); - const key = `archives${url}${url.split('/').length === 2 ? '/index.html' : url.indexOf('.') === -1 ? '.html' : ''}`; - try { - streamFile(key, req, res, next); - } catch { - next(); - } - }, -); +archiveController.get({ path: '/*', userType: userType }, async (req: Request, res: Response, next: NextFunction) => { + const url = decodeURI(req.url); + const key = `archives${url}${url.split('/').length === 2 ? '/index.html' : url.indexOf('.') === -1 ? '.html' : ''}`; + try { + streamFile(key, req, res, next); + } catch { + next(); + } +}); /** * Liste les dossiers dans un préfixe S3 spécifié. diff --git a/server/controllers/controller.ts b/server/controllers/controller.ts index a76171e27..a86b6a164 100644 --- a/server/controllers/controller.ts +++ b/server/controllers/controller.ts @@ -11,7 +11,7 @@ import { diskStorage } from '../middlewares/multer'; type RouteOptions = { path: string; - userType?: UserType | UserType[]; + userType?: UserType; }; fs.ensureDir(path.join(__dirname, '../fileUpload/videos')).catch(); diff --git a/server/middlewares/authenticate.ts b/server/middlewares/authenticate.ts index 5b9b56721..548a85b1c 100644 --- a/server/middlewares/authenticate.ts +++ b/server/middlewares/authenticate.ts @@ -1,4 +1,4 @@ -import type { NextFunction, Request, Response } from 'express'; +import type { NextFunction, Request, Response, RequestHandler } from 'express'; import jwt from 'jsonwebtoken'; import { getNewAccessToken } from '../authentication/lib/tokens'; @@ -9,8 +9,8 @@ import { AppDataSource } from '../utils/data-source'; const secret: string = process.env.APP_SECRET || ''; -export function authenticate(userType?: UserType | UserType[] | undefined) { - return async (req: Request, res: Response, next: NextFunction): Promise => { +export function authenticate(userType: UserType | undefined = undefined): RequestHandler { + return async (req: Request, res: Response, next: NextFunction) => { let token: string; if (req.cookies && req.cookies['access-token']) { if (!req.isCsrfValid && req.method !== 'GET') { diff --git a/server/middlewares/handleErrors.ts b/server/middlewares/handleErrors.ts index 40b6aed12..37b32cf54 100644 --- a/server/middlewares/handleErrors.ts +++ b/server/middlewares/handleErrors.ts @@ -31,7 +31,7 @@ interface PromiseRequestHandler extends RequestHandler { (req: Request, res: Response, next: NextFunction): Promise | void; } -export function handleErrors(fn) { +export function handleErrors(fn: RequestHandler): RequestHandler { return (req: Request, res: Response, next: NextFunction): void => { const sendError = (err: Error | AppError): void => { logger.error(err.message);