Fetch favicons locally instead of using DuckDuckGo
👋 This PR adds support for resolving favicons locally instead of relying on the DuckDuckGo third party service for this. I think it improves the privacy of Umami since we don't have to send along data to DDG. As far as I can tell the DuckDuckGo API is unofficial, at least I can't find any mentions of it on their site. So this change would also improve the resiliency in case the DDG API disappears at some point.
How it works
When adding a site or saving its settings, we will attempt to fetch the site HTML and parse out <link rel="icon" ...> tags which is the recommended way of adding a favicon. The favicon url is saved to the website table. A migration is provided to add the column.
Changes
- Currently this approach only parses the HTML. We could also add a fallback by trying to fetch
/favicon.icoin the domain root and use that if it returns a 2XX status code. - The favicon will not be automatically updated (this is possible I'm not sure the cost/benefit of adding so much code for this small feature), however it's enough to edit the website and save the changes to refetch the favicon.
- Existing favicons would disappear when updating Umami. I'm open to writing some sort of script to auto-fetch them on upgrade but not sure where would be a good place to add this.
Other
The favicon code is an adaptation of the https://github.com/sudoaugustin/favecon package (using modern async/await and supporting aborting the function if it takes too long). I picked this package because it was based on node-fetch which Umami already uses.
@khromov is attempting to deploy a commit to the umami-software Team on Vercel.
A member of the Team first needs to authorize it.
@mikecao Is there any interest in this?
Yeah i'd like this. seems more robust then the current implementation.
I could rebase it if there is interest in merging it.
Won't be implementing this for now.
@mikecao If you don't want to implement this, can we at least have a toggle to disable automatically sending all the sites in our installation to third party services?
@khromov If we set the referrerpolicy to no-referrer on the favicon link, wouldn't that be enough?
That would hide the location of the Umami server from DDG but it would still be easy to determine which sites are connected to the same page load because multiple favicon requests (one for each Umami domain) would be sent in short succession. It's not that I don't trust DDG but I felt this was unexpected and privacy-problematic behavior that should have an opt out of some sort.
Ok, then we can probably add an environment variable to disable any third party requests.