anonymize-query-params.ts 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { diag } from '@opentelemetry/api';
  2. const logger = diag.createComponentLogger({ namespace: 'growi:anonymization:anonymize-query-params' });
  3. /**
  4. * Try to parse JSON array, return null if invalid
  5. */
  6. function tryParseJsonArray(value: string): unknown[] | null {
  7. try {
  8. const parsed = JSON.parse(value);
  9. return Array.isArray(parsed) ? parsed : null;
  10. }
  11. catch {
  12. return null;
  13. }
  14. }
  15. /**
  16. * Anonymize specific query parameters in HTTP target URL
  17. * @param target - The HTTP target URL with query parameters
  18. * @param paramNames - Array of parameter names to anonymize
  19. * @returns Anonymized HTTP target URL
  20. */
  21. export function anonymizeQueryParams(target: string, paramNames: string[]): string {
  22. try {
  23. const url = new URL(target, 'http://localhost');
  24. const searchParams = new URLSearchParams(url.search);
  25. let hasChange = false;
  26. for (const paramName of paramNames) {
  27. // Handle regular parameter (including JSON arrays)
  28. if (searchParams.has(paramName)) {
  29. const value = searchParams.get(paramName);
  30. // Anonymize parameter even if it's empty (null check only)
  31. if (value !== null) {
  32. let replacement = '[ANONYMIZED]';
  33. if (value.startsWith('[') && value.endsWith(']')) {
  34. const jsonArray = tryParseJsonArray(value);
  35. if (jsonArray && jsonArray.length > 0) {
  36. replacement = '["[ANONYMIZED]"]';
  37. }
  38. }
  39. searchParams.set(paramName, replacement);
  40. hasChange = true;
  41. }
  42. }
  43. // Handle array-style parameters (paramName[])
  44. const arrayParam = `${paramName}[]`;
  45. if (searchParams.has(arrayParam)) {
  46. searchParams.delete(arrayParam);
  47. searchParams.set(arrayParam, '[ANONYMIZED]');
  48. hasChange = true;
  49. }
  50. }
  51. return hasChange ? `${url.pathname}?${searchParams.toString()}${url.hash}` : target;
  52. }
  53. catch (error) {
  54. logger.warn(`Failed to anonymize query parameters [${paramNames.join(', ')}]: ${error}`);
  55. return target;
  56. }
  57. }