page-api-handler.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { diag } from '@opentelemetry/api';
  2. import type { IncomingMessage } from 'http';
  3. import { ATTR_HTTP_TARGET } from '../../semconv';
  4. import type { AnonymizationModule } from '../interfaces/anonymization-module';
  5. import { anonymizeQueryParams } from '../utils/anonymize-query-params';
  6. const logger = diag.createComponentLogger({
  7. namespace: 'growi:anonymization:page-api-handler',
  8. });
  9. /**
  10. * Page API anonymization module
  11. */
  12. export const pageApiModule: AnonymizationModule = {
  13. /**
  14. * Check if this module can handle page API endpoints
  15. */
  16. canHandle(url: string): boolean {
  17. return (
  18. url.includes('/_api/v3/pages/list') ||
  19. url.includes('/_api/v3/pages/subordinated-list') ||
  20. url.includes('/_api/v3/page/check-page-existence') ||
  21. url.includes('/_api/v3/page/get-page-paths-with-descendant-count')
  22. );
  23. },
  24. /**
  25. * Handle anonymization for page API endpoints
  26. */
  27. handle(request: IncomingMessage, url: string): Record<string, string> | null {
  28. const attributes: Record<string, string> = {};
  29. let hasAnonymization = false;
  30. // Handle endpoints with 'path' parameter
  31. if (
  32. url.includes('path=') &&
  33. (url.includes('/_api/v3/pages/list') ||
  34. url.includes('/_api/v3/pages/subordinated-list') ||
  35. url.includes('/_api/v3/page/check-page-existence'))
  36. ) {
  37. const anonymizedUrl = anonymizeQueryParams(url, ['path']);
  38. attributes[ATTR_HTTP_TARGET] = anonymizedUrl;
  39. hasAnonymization = true;
  40. // Determine endpoint type for logging
  41. let endpointType = 'page API';
  42. if (url.includes('/_api/v3/pages/list')) endpointType = '/pages/list';
  43. else if (url.includes('/_api/v3/pages/subordinated-list'))
  44. endpointType = '/pages/subordinated-list';
  45. else if (url.includes('/_api/v3/page/check-page-existence'))
  46. endpointType = '/page/check-page-existence';
  47. logger.debug(
  48. `Anonymized ${endpointType} URL: ${url} -> ${anonymizedUrl}`,
  49. );
  50. }
  51. // Handle page/get-page-paths-with-descendant-count endpoint with paths parameter
  52. if (
  53. url.includes('/_api/v3/page/get-page-paths-with-descendant-count') &&
  54. url.includes('paths=')
  55. ) {
  56. const anonymizedUrl = anonymizeQueryParams(url, ['paths']);
  57. attributes[ATTR_HTTP_TARGET] = anonymizedUrl;
  58. hasAnonymization = true;
  59. logger.debug(
  60. `Anonymized page/get-page-paths-with-descendant-count URL: ${url} -> ${anonymizedUrl}`,
  61. );
  62. }
  63. return hasAnonymization ? attributes : null;
  64. },
  65. };