Repository: jiahaog/nativefier
File: app/src/helpers/windowHelpers.ts (TypeScript)

Code before:
        injectCSSIntoResponse(details, cssToInject)
          .then((responseHeaders) => {
            callback({
              cancel: false,
              responseHeaders,
            });
          })
          .catch((err) => {
            log.error('injectCSSIntoResponse ERROR', err);
            callback({
              cancel: false,
              responseHeaders: details.responseHeaders,
            });
          });
      },
    );
  });
}

async function injectCSSIntoResponse(
  details: OnHeadersReceivedListenerDetails,
  cssToInject: string,
): Promise<Record<string, string[]>> {
  const nonInjectableMethods = ['DELETE', 'OPTIONS'];
  const nonInjectableResourceTypes = ['image', 'script', 'stylesheet', 'xhr'];

  if (
    nonInjectableMethods.includes(details.method) ||
    nonInjectableResourceTypes.includes(details.resourceType) ||
    !details.webContents
  ) {
    log.debug(
      `Skipping CSS injection for:\n${details.url}\nwith method ${details.method} and resourceType ${details.resourceType} and content-type ${details.responseHeaders['content-type']}`,
    );
    return details.responseHeaders;
  }

  log.debug('browserWindow.webContents.session.webRequest.onHeadersReceived', {
    details,
    contentType: details.responseHeaders['content-type'],
  });
  await details.webContents.insertCSS(cssToInject);

  return details.responseHeaders;
}

export function sendParamsOnDidFinishLoad(
  options,
  window: BrowserWindow,
): void {
  window.webContents.on('did-finish-load', () => {

Review comment (suggestion):
Your PR description rationale would be useful here:

```suggestion
  // We go with a denylist rather than a whitelist (e.g. only GET/html)
  // to avoid "whoops I didn't think this should have been CSS-injected" cases
  const nonInjectableMethods = ['DELETE', 'OPTIONS'];
```

Code after:
        injectCSSIntoResponse(details, cssToInject)
          .then((responseHeaders) => {
            callback({
              cancel: false,
              responseHeaders,
            });
          })
          .catch((err) => {
            log.error('injectCSSIntoResponse ERROR', err);
            callback({
              cancel: false,
              responseHeaders: details.responseHeaders,
            });
          });
      },
    );
  });
}

async function injectCSSIntoResponse(
  details: OnHeadersReceivedListenerDetails,
  cssToInject: string,
): Promise<Record<string, string[]>> {
  // We go with a denylist rather than a whitelist (e.g. only GET/html)
  // to avoid "whoops I didn't think this should have been CSS-injected" cases
  const nonInjectableMethods = ['DELETE', 'OPTIONS'];
  const nonInjectableResourceTypes = ['image', 'script', 'stylesheet', 'xhr'];

  if (
    nonInjectableMethods.includes(details.method) ||
    nonInjectableResourceTypes.includes(details.resourceType) ||
    !details.webContents
  ) {
    log.debug(
      `Skipping CSS injection for:\n${details.url}\nwith method ${details.method} and resourceType ${details.resourceType} and content-type ${details.responseHeaders['content-type']}`,
    );
    return details.responseHeaders;
  }

  log.debug('browserWindow.webContents.session.webRequest.onHeadersReceived', {
    details,
    contentType: details.responseHeaders['content-type'],
  });
  await details.webContents.insertCSS(cssToInject);

  return details.responseHeaders;
}

export function sendParamsOnDidFinishLoad(
  options,
  window: BrowserWindow,