Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autoUpdater does not work when have authenticated proxy #5020

Closed
MarshallOfSound opened this issue Apr 4, 2016 · 60 comments
Closed

autoUpdater does not work when have authenticated proxy #5020

MarshallOfSound opened this issue Apr 4, 2016 · 60 comments

Comments

@MarshallOfSound
Copy link
Member

  • Electron version: 0.36.7
  • Operating system: Windows

The autoUpdater module in electron does not appear to be attempting to update all my users on windows from 3.0.1 to 3.1.0. It took a clean reinstall of the application on a few computers that I am aware of before it decided there was an update too download.

Upon sniffing out the traffic I could see that an update check request was being sent to fetch the RELEASES file and then didn't attempt to download the obviously available update.

I don't see how it can work for around 80% of users (that number is a guestimate) and not work for the rest.

The update server is here http://update.googleplaymusicdesktopplayer.com/update/{platform}/{version}
The update code is here https://github.com/MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-/blob/master/src/main/features/core/autoUpdater.js

@kevinsawicki
Copy link
Contributor

What version of squirrel on windows is your installer using?

@MarshallOfSound
Copy link
Member Author

Whichever version is packaged with grunt-electron-installer version 1.2.3

I can see that that repository received a major version bump recently to 2.0.0, is that bump at all related to this issue?

@kevinsawicki
Copy link
Contributor

is that bump at all related to this issue?

No, that major bump was for a new underlying library that was used.

@MarshallOfSound
Copy link
Member Author

No, that major bump was for a new underlying library that was used.

Bit of a long shot hope 😆

I'm trying to find a way to accurately replicate this issue but it appears to be completely random 😢

@kevinsawicki
Copy link
Contributor

Are you able to get the squirrel logs off any of the machines that are experiencing the issue?

@MarshallOfSound
Copy link
Member Author

I'll grab them as soon as I can make it do this again. Completely uninstalling and reinstalling to replicate is time consuming when there is only a small chance it fails 😄

@MarshallOfSound
Copy link
Member Author

@kevinsawicki It appears as though there is some release notes parsing error https://gist.github.com/MarshallOfSound/7c6616b032a2499afd56de71186ef451 but then it still (eventually) starts building the full package and my app receives an update notification.

Still trying to make it not update 😞

I just pinged all the issues related to this asking for them to upload their squirrel log. I'll ping here if / when I get one

@MarshallOfSound
Copy link
Member Author

@kevinsawicki I managed to get a log from someone else's PC experiencing this issue.
https://gist.github.com/rickwastaken/c659c5a9fe75ecb3db274222bf6c288c

From what I can see they are having really strange DNS issues, which used to happen a lot (as an example MarshallOfSound/Google-Play-Music-Desktop-Player-UNOFFICIAL-#301)

However when the user accesses update.googleplaymusicdesktopplayer.com in there browser. It resolves the address fine (as seen here

Any reason why C#'s WebClient wouldn't resolve the name but a browser would?

@kevinsawicki
Copy link
Contributor

Any reason why C#'s WebClient wouldn't resolve the name but a browser would?

No idea, not sure if @paulcbetts might know 🔦

@anaisbetts
Copy link
Contributor

Any reason why C#'s WebClient wouldn't resolve the name but a browser would?

If it's using an authenticated proxy

@MarshallOfSound
Copy link
Member Author

@paulcbetts Is there any way around this? Or any way for me to detect that proxy from within electron and tell the user they won't be able to get updates?

@MarshallOfSound
Copy link
Member Author

@paulcbetts Or maybe implementing this https://msdn.microsoft.com/en-us/library/system.net.webrequest.defaultwebproxy.aspx in Squirrel.Windows

@baconbrad
Copy link
Contributor

Is there any way around this? Or any way for me to detect that proxy from within electron and tell the user they won't be able to get updates?

@MarshallOfSound There are several NPM packages that let you detect a proxy. Or you could write your own solution in Node.js to detect a proxy. Could you do that without needing changes in Squirrel for Windows? Because there would be cases where someone would want to update via a proxy.

Ideally I would skip all the above together and either check to see if the file could be reached and notify the user if not or attempt to download the file and notify the user if the download fails. This is how most updaters handle this.

If none of the above works for you I guess I don't completely understand your case.

@anaisbetts
Copy link
Contributor

So, the problem at the end of the day is, if you have an authenticated proxy on Windows, you need to pop UI to prompt for username/passwords at the time of request (i.e. not just in a system settings dialog). This is deeply stupid, but it is what it is.

To mitigate this, you could download RELEASES and the latest NuPkg file yourself with Chromium (as well as implement the login callback to actually show UI in-app), then point your updater URL to that temp folder. This is deeply obnoxious, but so are proxy servers.

@MarshallOfSound
Copy link
Member Author

@paulcbetts Out of interest do you know how / if atom handles this problem? Downloading the RELEASES and nupkg files through electron seems a bit silly to me but it seems like I need to somehow bypass a network connection all together so I'm not sure.... 😢

@zcbenz zcbenz changed the title autoUpdater does not appear to update on 100% of clients autoUpdater does not work when have authenticated proxy Apr 8, 2016
@anaisbetts
Copy link
Contributor

@MarshallOfSound It almost certainly doesn't solve it at all

@chandrachivukula
Copy link

@MarshallOfSound, have you found a way to get the autoUpdater to work with an authenticated proxy?

(for a separate issue) We've added headers option to setFeedUrl which if you can set the headers, and call checkForUpdates(), it should work. could you try this out and let us know?

@vadim-ch
Copy link

vadim-ch commented Dec 14, 2016

@chandrachivukula

(for a separate issue) We've added headers option to setFeedUrl which if you can set the headers, and call checkForUpdates(), it should work. could you try this out and let us know?

As seen from the code heades are not transferred - https://github.com/electron/electron/blob/master/lib/browser/api/auto-updater/auto-updater-win.js#L21

@MarshallOfSound
Copy link
Member Author

@vadim-ch As in the documentation the headers param is macOS only

@vadim-ch
Copy link

@MarshallOfSound Yes. It's very bad. I am sad. I'm looking for any workaround.

@vadim-ch
Copy link

vadim-ch commented Dec 16, 2016

Hello. For myself I found a solution.

First step:
Request the latest version available. (For example using Electron Release Server you can get a list of versions - http://download.myapp.com/api/version)

Second step:
Compare the current version and available.

Third step:
Download file available version to a temporary folder(temporaryDirPath) - http://download.myapp.com/download/${availableVersion}/windows_64/MyApp-0.1.1-full.nupkg

Fourth step:
UptoUpdater set the path, but not url. And checkForUpdates.

autoUpdater.setFeedURL(temporaryDirPath);
autoUpdater.checkForUpdates();

@stale stale bot added the wontfix label Mar 15, 2017
@zeke zeke removed wontfix labels Mar 15, 2017
@hosnar
Copy link

hosnar commented Jul 1, 2020

@joshuapinter did you have any issues with file protocol when implementing local feed auto update? I can't get this to work, because I keep getting error "Error: Protocol "file:" not supported".

@joshuapinter
Copy link

@hosnar I don't recall seeing that error message but it was over a year ago since I've looked at it.

@fengxiangge
Copy link

I've found an alternative solution that works for basic proxies.

Within my app, I have added a app.on("login", ... handler, which prompts the user for credentials. It works great, except for the autoUpdater.
I was hoping that autoUpdater was using electron.net, so that it would fire the login event, but it does not fire. I get the impression that the updater runs outside of Electron.

This is true however you can listen for the autoUpdater login event instead. See https://www.electron.build/auto-update#updatersignal

autoUpdater.on('login', async (authInfo, callback) => {
  const [username, password] = ...... // prompt on UI, use cache, other solution to acquire credentials
  callback(username, password)
})
autoUpdater.requestHeaders = {'User-Agent': userAgent}
// Will cause a login event
const {info, provider} = await autoUpdater.getUpdateInfoAndProvider()
const updateAvailable = await autoUpdater.isUpdateAvailable(info)

This was really worked. I have been success.

@electron-triage
Copy link

The Electron version reported on this issue is no longer supported. See our supported versions documentation.

If you're still experiencing this issue on a supported version, please open a new issue with an updated repro - a Fiddle is very appreciated.

Electron has a large issues backlog. To help our team prioritize, we're closing older issues and asking for new issues with updated repro steps if it affects a supported version. This helps sort what issues are still relevant and helps us fix them more quickly.

Thanks for your patience and understanding!

@NookieGrey
Copy link

download( mainWindow, urlToNupkg, {
  directory: global.tempPath,
  onProgress: progress => mainWindow.webContents.send( "downloadProgress", progress )
} );

Sorry, where is download function's location?

@sploders101
Copy link

@NookieGrey You'll probably have to write it yourself. Judging by the fact that they're passing a BrowserView to the function, I'd imagine it's an RPC call running through electron's IPC into a preload script in the frontend. You'll probably have to set up a set of events to transfer back and forth between the frontend and backend to make this work, and use something like Axios in the frontend to fetch the file.

@sploders101
Copy link

I just wanted to throw an idea out there that I'm using to satisfy a requirement for an internal tool for work. We don't necessarily need to download the files ourselves. We just need to add things to redirect the request to another location that can resolve them. My problem isn't quite the same, as I just need to have a password on my update server, which of course, squirrel for Windows doesn't support (even with the credentials in the URL as per http scheme spec). I'd be happy to release a POC example once I've finished and tested it, but what if instead of parsing and downloading packages ourselves, effectively eliminating the elegance and speed of delta updates, we just create a proxy on localhost. Then, when squirrel goes looking for an update, we receive all of its requests, and can do with them what we wish. In my case, I can simply inject an authorization header, rewrite the host, and voila! Authentication headers are now added to the request before they reach the update server.

Side note:
According to my research, it looks like squirrel is an external program that runs on-demand when electron asks for it. It does not appear that squirrel makes any requests outside of the app's lifecycle, because it only kills the app when it's already downloaded and ready to start the new version, so there's no reason the app couldn't be its own update server. Only the URL makes it into squirrel, and it doesn't support basic auth, so there's no hope of getting squirrel to make the requests properly (this term is used loosely, since this is kind of an edge case). However, electron has an http server, and squirrel can request via HTTP, which means the application can be squirrel's update server and it doesn't matter if squirrel supports the protocols used on the public-facing server. I'm not sure if this works or not for authenticated proxies, since squirrel would need to bypass them, but maybe there's an exception if it's sending requests to localhost?

@sploders101
Copy link

I have finished and tested my authentication proxy example and am happy to report that it works! Unfortunately, it's not the most secure thing in the world, but I'd say it's about as secure as bundling your update password with the application, which you'd probably have to do anyway unless you were to prompt the user for it on every launch. You could also start the server just long enough to get an update in order to mitigate the risk.

https://gist.github.com/sploders101/23719534c683216baf76b816098e614b

Ultimately, I think the most useful way to go about this would be to implement an RPC-esque proxy on stdin/out on both squirrel and electron, which could be handled on the JS side similarly to HTTP requests, and could be enabled via a command line flag on the squirrel exe, but I'm not sure how likely that is to be implemented.

@FCF-Releases
Copy link

hi all, everything seems to be working fine for me on this except that it never seems to trigger the autoUpdate.on('update-downloaded') event? Anyone experienced this?

@FCF-Releases
Copy link

Fingers crossed someone sees this! I was using this successfully and now it appears to not recognize the feedURL or at least autoUpdater.checkForUpdates() does not trigger anymore. Has anything changed in the AutoUpdater for electron?

@sploders101
Copy link

Fingers crossed someone sees this! I was using this successfully and now it appears to not recognize the feedURL or at least autoUpdater.checkForUpdates() does not trigger anymore. Has anything changed in the AutoUpdater for electron?

Are you using the built-in updater the npm module?

Unfortunately, I don't believe the built-in updater has supported this for quite some time, which is why I posted the in-app HTTP proxy method above. The updater runs outside the JavaScript context, so unless they add support for this, I don't think it's going to work. Someone please correct me if I'm wrong.

@christianblandford
Copy link

christianblandford commented Feb 16, 2022

I created electron-github-autoupdater to solve this problem. It's a custom autoUpdater that works pretty much the same, but accepts a config object including a GH user token. More information in the readme.

I've tested this on the latest versions of electron-forge, but I believe forge is electron 14, so it may not be compatible on v16+. Also, I have only tested on windows, I would very much appreciate a Mac user giving it a go.

@qiqetes
Copy link

qiqetes commented Jun 28, 2022

I'm trying to Manually handle updates.

I download the update from s3 bucket whenever there's an available update. And then I create a feed.json file with the format:

{"url": "file:///var/temp/aofsdjaodsijf/update.zip"}

Then I set the

autoUpdater.setFeedUrl("file:///var/temp/aofsdjaodsijf/feed.json");
autoUpdater.checkUpdates();

But I get this error:
Error: Could not locate update bundle for com.github.Electron within file:///Users/X/Library/Caches/com.github.Electron.ShipIt/update.SrmZwAy/ that looks nothing like the "url" that I passed...

I'm very stuck on this, some help would be very appreciated.

@zschreur
Copy link

@qiqetes Using the url package could help ensure the URL is properly formatted.

const URL = require('url');

...

const createFeedUrlFile = async (updateCache, zipFile) => {
   const json = {
      url: Url.pathToFileURL(zipFile).href
   }

   const feedUrlFile = path.join(updateCache, 'feed.json');

   await fs.promises.writeFile(feedUrlFile, JSON.stringify(json));

   return feedUrlFile;
}

...

autoUpdater.setFeedURL({
   url: Url.pathToFileURL(feedUrlFile).href
});

@qiqetes
Copy link

qiqetes commented Jun 28, 2022

Thanks for the reply. Seems like the urls are fine. (tried with your method, same error is thrown).
image

@emalei
Copy link

emalei commented Oct 17, 2022

Thanks for the reply. Seems like the urls are fine. (tried with your method, same error is thrown). image

Have you solved this problem

@saibhavateja1
Copy link

saibhavateja1 commented Jan 13, 2023

I'm trying to Manually handle updates.

I download the update from s3 bucket whenever there's an available update. And then I create a feed.json file with the format:

{"url": "file:///var/temp/aofsdjaodsijf/update.zip"}

Then I set the

autoUpdater.setFeedUrl("file:///var/temp/aofsdjaodsijf/feed.json");
autoUpdater.checkUpdates();

But I get this error: Error: Could not locate update bundle for com.github.Electron within file:///Users/X/Library/Caches/com.github.Electron.ShipIt/update.SrmZwAy/ that looks nothing like the "url" that I passed...

I'm very stuck on this, some help would be very appreciated.

@qiqetes @emalei Did you figure out a way to solve this? Looks like autoUpdater creates Users/X/Library/Caches/*/update. before downloading. Since we are skipping that part and doing it ourselves, this file/dir seems to be missing.

@joshuapinter How did you get this to work?

@qiqetes
Copy link

qiqetes commented Jan 13, 2023

I'm trying to Manually handle updates.
I download the update from s3 bucket whenever there's an available update. And then I create a feed.json file with the format:

{"url": "file:///var/temp/aofsdjaodsijf/update.zip"}

Then I set the

autoUpdater.setFeedUrl("file:///var/temp/aofsdjaodsijf/feed.json");
autoUpdater.checkUpdates();

But I get this error: Error: Could not locate update bundle for com.github.Electron within file:///Users/X/Library/Caches/com.github.Electron.ShipIt/update.SrmZwAy/ that looks nothing like the "url" that I passed...
I'm very stuck on this, some help would be very appreciated.

@qiqetes @emalei Did you figure out a way to solve this? Looks like autoUpdater creates Users/X/Library/Caches/*/update. before downloading. Since we are skipping that part and doing it ourselves, this file/dir seems to be missing.

@joshuapinter How did you get this to work?

  const tempPath = path.join(app.getPath("temp"), "updateVersion");

  const setAutoUpdaterMac = () => {
    // We need to manually create a feed.json file with a `url` key that points to our local `.zip` update file.
    const json = {
      url: url.pathToFileURL(path.join(tempPath, "update.zip")).href,
    };

    fs.writeFileSync(tempPath + "/feed.json", JSON.stringify(json));
    console.log("file://" + tempPath + "/feed.json");

    autoUpdater.setFeedURL({
      url: url.pathToFileURL(path.join(tempPath, "feed.json")).href,
    });
     autoUpdater.checkForUpdates();
  };

I don't remember it too much, what I have now and it's working is that piece of code.

@saibhavateja1
Copy link

@qiqetes Thank you for the snippet. Do you mind sharing which version of electron you are using today?
Also is the autoUpdater from electron module?

@qiqetes
Copy link

qiqetes commented Jan 13, 2023

@qiqetes Thank you for the snippet. Do you mind sharing which version of electron you are using today? Also is the autoUpdater from electron module?

Latest version, and yes, autoUpdater comes from the electron module;

@saibhavateja1
Copy link

@qiqetes Thank you. The issue's resolved now. The reason is – I am downloading a .dmg and feeding that to the autoUpdater when instead I should be feeding a zip file of .app

One other thing that I would like to bring up is, I am being prompted with a message saying "Application is downloaded from the internet. Are you sure you want to open it?" This is happening every time an update is downloaded and installed. Any idea why this happens?

@0xWormh0le
Copy link

Is nupkg file still required for auto update on Windows?
I found squirrel.windows, which is used for generating nupkg file, is deprecated and can't see the latest update from its repository.
On the other hand, I found squirrel.windows is still a solution to auto update an electron app on Windows.
https://www.electronjs.org/docs/latest/api/auto-updater#windows
What is the best way to implement auto update on windows?
@joshuapinter @scottrippey

@lockiechen
Copy link

how can i add query token when download the windows pkg

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests