All files / scripts/instrumentor/patcher signalsInjection.ts

92.3% Statements 12/13
83.33% Branches 5/6
100% Functions 2/2
92.3% Lines 12/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72                                                                  42x 11x 11x     29x   29x   28x 2x     28x                                 26x 26x     26x   26x    
import { PatcherRequest } from './types'
import { PatcherContext } from './context'
import { logger } from '../../shared/logger'
import { APP_INCLUDED_CREDENTIALS_FLAG, SIGNALS_KEY } from '../../../shared/const'
 
/**
 * Parameters required for handling signals injection into requests.
 */
type CollectSignalsParams = {
  /** The request object that may receive signals injection */
  request: PatcherRequest
  /** Patcher context providing access to signals and other functionality */
  ctx: PatcherContext
}
 
/**
 * Handles the injection of fingerprinting signals into requests targeting protected APIs.
 * Collects fingerprinting signals if the request targets a protected API.
 *
 * This function checks if a request targets a protected URL and, if so, retrieves signals
 * from the patcher context and returns them. If the URL is not protected or no signals
 * are available, the function logs appropriate debug/warning messages.
 *
 * @param params - Configuration object containing the request and context
 * @param params.request - The request object that may receive signals injection
 * @param params.ctx - Patcher context providing access to signals and other functionality
 *
 * @returns the signals; undefined if no signals were collected.
 */
export async function collectSignalsForProtectedUrl({
  request,
  ctx,
}: CollectSignalsParams): Promise<string | undefined> {
  if (!ctx.isProtectedUrl(request.url, request.method)) {
    logger.debug('Skipping signals injection:', request.url)
    return undefined
  }
 
  logger.debug('Injecting signals:', request.url)
 
  const signals = await ctx.getSignals()
 
  if (!signals) {
    logger.warn('No signals data found.')
  }
 
  return signals
}
 
export type SignalInjectionResult = {
  /** true if the application configured the request to include credentials in a cross-origin request */
  appIncludedCredentials: boolean
}
 
/**
 * Inject the fingerprinting signals into the request
 *
 * @param request the `PatcherRequest` to modify
 * @param signals the signals to inject
 *
 * @returns the results of signal injection as a `SignalInjectionResult`
 */
export function injectSignalsIntoRequest(request: PatcherRequest, signals: string): SignalInjectionResult {
  const appIncludedCredentials = request.setIncludeCredentials()
  Iif (appIncludedCredentials) {
    request.setHeader(SIGNALS_KEY, `${APP_INCLUDED_CREDENTIALS_FLAG}${signals}`)
  } else {
    request.setHeader(SIGNALS_KEY, signals)
  }
  return { appIncludedCredentials }
}