import { app, shell } from 'electron';

app.on('web-contents-created', (_, contents) => {
  const isInternalUrl = (url: string) => {
    return (
      (process.env.DEV_SERVER_URL &&
        url.startsWith(process.env.DEV_SERVER_URL)) ||
      url.startsWith('affine://') ||
      url.startsWith('file://.')
    );
  };
  /**
   * Block navigation to origins not on the allowlist.
   *
   * Navigation is a common attack vector. If an attacker can convince the app to navigate away
   * from its current page, they can possibly force the app to open web sites on the Internet.
   *
   * @see https://www.electronjs.org/docs/latest/tutorial/security#13-disable-or-limit-navigation
   */
  contents.on('will-navigate', (event, url) => {
    if (isInternalUrl(url)) {
      return;
    }
    // Prevent navigation
    event.preventDefault();
    shell.openExternal(url).catch(console.error);
  });

  /**
   * Hyperlinks to allowed sites open in the default browser.
   *
   * The creation of new `webContents` is a common attack vector. Attackers attempt to convince the app to create new windows,
   * frames, or other renderer processes with more privileges than they had before; or with pages opened that they couldn't open before.
   * You should deny any unexpected window creation.
   *
   * @see https://www.electronjs.org/docs/latest/tutorial/security#14-disable-or-limit-creation-of-new-windows
   * @see https://www.electronjs.org/docs/latest/tutorial/security#15-do-not-use-openexternal-with-untrusted-content
   */
  contents.setWindowOpenHandler(({ url }) => {
    if (!isInternalUrl(url) || url.includes('/redirect-proxy')) {
      // Open default browser
      shell.openExternal(url).catch(console.error);
    }
    // Prevent creating new window in application
    return { action: 'deny' };
  });
});
