index.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { SCOPE } from '@growi/core/dist/interfaces';
  2. import type { NextFunction, Request, Response } from 'express';
  3. import { query, validationResult } from 'express-validator';
  4. import { FilterXSS } from 'xss';
  5. import type { LsxApiOptions } from '../interfaces/api';
  6. import { listPages } from './routes/list-pages';
  7. const loginRequiredFallback = (req: Request, res: Response) => {
  8. return res.status(403).send('login required');
  9. };
  10. const filterXSS = new FilterXSS();
  11. const lsxValidator = [
  12. query('pagePath').notEmpty().isString(),
  13. query('offset').optional().isInt().toInt(),
  14. query('limit').optional().isInt().toInt(),
  15. query('options')
  16. .optional()
  17. .customSanitizer((options) => {
  18. try {
  19. const jsonData: LsxApiOptions = JSON.parse(options);
  20. for (const key in jsonData) {
  21. jsonData[key] = filterXSS.process(jsonData[key]);
  22. }
  23. return jsonData;
  24. } catch {
  25. throw new Error('Invalid JSON format in options');
  26. }
  27. }),
  28. query('options.*').optional().isString(),
  29. ];
  30. const paramValidator = (req: Request, res: Response, next: NextFunction) => {
  31. const errObjArray = validationResult(req);
  32. if (errObjArray.isEmpty()) {
  33. return next();
  34. }
  35. const errs = errObjArray.array().map((err) => {
  36. return new Error(`Invalid lsx parameter: ${err.param}: ${err.msg}`);
  37. });
  38. res.status(400).json({ errors: errs.map((err) => err.message) });
  39. };
  40. // biome-ignore lint/suspicious/noExplicitAny: ignore
  41. const middleware = (crowi: any, app: any): void => {
  42. const loginRequired = crowi.require('../middlewares/login-required')(
  43. crowi,
  44. true,
  45. loginRequiredFallback,
  46. );
  47. const accessTokenParser = crowi.accessTokenParser;
  48. app.get(
  49. '/_api/lsx',
  50. accessTokenParser([SCOPE.READ.FEATURES.PAGE], { acceptLegacy: true }),
  51. loginRequired,
  52. lsxValidator,
  53. paramValidator,
  54. listPages,
  55. );
  56. };
  57. export default middleware;