signalapp / Signal-Desktop

A private messenger for Windows, macOS, and Linux.
https://signal.org/download
GNU Affero General Public License v3.0
14.52k stars 2.63k forks source link

interceptFileProtocol is deprecated in electron 25 #6550

Open kyle-go opened 1 year ago

kyle-go commented 1 year ago

Bug Description

Steps to Reproduce

  1. step one
  2. step two
  3. step three

Actual Result:

Expected Result:

Screenshots

Platform Info

Signal Version:

Operating System:

Linked Device Version:

Link to Debug Log

jamiebuilds-signal commented 1 year ago

Cool, it looks fairly straightforward to update:

Blog post: https://www.electronjs.org/blog/electron-25-0#deprecated-protocolregisterinterceptbufferstringstreamfilehttpprotocol Electron PR: https://github.com/electron/electron/pull/36674 RFC: https://github.com/electron/governance/pull/368

Luca-Hackl commented 1 year ago

Hello,

I'm currently working on my first pull request and I apologize if I make any mistakes. I have a question concerning the modification regarding protocol.handle.

function _disabledHandler(
  _request: Request,
): Promise<Response> {
  return Promise.resolve(new Response(null, { status: -10 }));
}

export function installWebHandler({
  session,
  enableHttp,
}: {
  session: Session;
  enableHttp: boolean;
}): void {
  const { protocol } = session;
  protocol.handle('about', _disabledHandler);
  protocol.handle('content', _disabledHandler);
  protocol.handle('chrome', _disabledHandler);
  protocol.handle('cid', _disabledHandler);
  protocol.handle('data', _disabledHandler);
  protocol.handle('filesystem', _disabledHandler);
  protocol.handle('ftp', _disabledHandler);
  protocol.handle('gopher', _disabledHandler);
  protocol.handle('javascript', _disabledHandler);
  protocol.handle('mailto', _disabledHandler);

  if (!enableHttp) {
    protocol.handle('http', _disabledHandler);
    protocol.handle('https', _disabledHandler);
    protocol.handle('ws', _disabledHandler);
    protocol.handle('wss', _disabledHandler);
  }
}

What did the error: -10 do in the original code? I replaced it with

callback({ error: -10 }); //Old
return Promise.resolve(new Response(null, { status: -10 })); //new

but I'm not sure if that is correct

scottnonnenberg-signal commented 1 year ago

There's a link in the original code:

Screenshot 2023-08-03 at 3 14 59 PM

Luca-Hackl commented 1 year ago

Thanks! It seems like the installFileHandler doesn't work with protocol.handle. I changed the response like in my question above, but it keeps giving me Unhandled Promise Rejection: Error: Failed to register protocol: file. I tried debugging it but I can't come to a conclusion on how to fix it.

I also can't find any good resources on changing the file handler especially with the new method. Can someone point me in the right direction or help me with the implementation?

function _createFileHandler({
                              userDataPath,
                              installPath,
                              isWindows,
                            }: {
  userDataPath: string;
  installPath: string;
  isWindows: boolean;
}) {
  const allowedRoots = [
    userDataPath,
    installPath,
    getAvatarsPath(userDataPath),
    getBadgesPath(userDataPath),
    getDraftPath(userDataPath),
    getPath(userDataPath),
    getStickersPath(userDataPath),
    getTempPath(userDataPath),
    getUpdateCachePath(userDataPath),
  ];
  return (request: Request): Response => {
    let targetPath;

    if (!request.url) {
      // This is an "invalid URL" error. See [Chromium's net error list][0].
      //
      // [0]: https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h;l=563;drc=a836ee9868cf1b9673fce362a82c98aba3e195de
      return new Response(null,{status : -300})
    }

    try {
      targetPath = _urlToPath(request.url, { isWindows });

      // normalize() is primarily useful here for switching / to \ on windows
      const target = normalize(targetPath);
      // here we attempt to follow symlinks to the ultimate final path, reflective of what
      //   we do in main.js on userDataPath and installPath
      const realPath = existsSync(target) ? realpathSync(target) : target;
      // finally we do case-insensitive checks on windows
      const properCasing = isWindows ? realPath.toLowerCase() : realPath;

      if (!isAbsolute(realPath)) {
        console.log(
            `Warning: denying request to non-absolute path '${realPath}'`
        );
        // This is an "Access Denied" error. See [Chromium's net error list][0].
        //
        // [0]: https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h;l=57;drc=a836ee9868cf1b9673fce362a82c98aba3e195de
        return new Response(null,{status : -10})
      }

      for (const root of allowedRoots) {
        if (properCasing.startsWith(isWindows ? root.toLowerCase() : root)) {
          return new Response(JSON.stringify({ path: realPath }));
        }
      }

      console.log(
          `Warning: denying request to path '${realPath}' (allowedRoots: '${allowedRoots}')`
      );
      return new Response(null,{status : -10})
    } catch (err) {
      const errorMessage =
          err && typeof err.message === 'string'
              ? err.message
              : 'no error message';
      console.log(
          `Warning: denying request because of an error: ${errorMessage}`
      );

      return new Response(null,{status : -10})
    }
  };
}

export function installFileHandler({
                                     session,
                                     userDataPath,
                                     installPath,
                                     isWindows,
                                   }: {
  session: Session;
  userDataPath: string;
  installPath: string;
  isWindows: boolean;
}): void {
  session.protocol.handle('file', _createFileHandler({ userDataPath, installPath, isWindows }));
}

This is my changed code along with this error message:

Unhandled Promise Rejection: Error: Failed to register protocol: file
    at c.handle (node:electron/js2c/browser_init:2:58169)
    at installFileHandler (C:\Programming\Signal-Desktop\app\protocol_filter.js:103:20)
    at App.<anonymous> (C:\Programming\Signal-Desktop\app\main.js:1337:51)
error Command failed with exit code 1.
ENate commented 10 months ago

Hi there. I am looking at ways to offer my service in the form of contribution. A good first issue may be the way but I am open to looking at this or similar issue, if available. Thanks