Bug 1909986 - For sidebar revamp, only show chatbot entrypoints (context menu, shortc...
[gecko.git] / netwerk / dns / PublicSuffixList.sys.mjs
blob89cec38fea9d869e050496466e9d7e5a21e86662
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import { RemoteSettings } from "resource://services-settings/remote-settings.sys.mjs";
7 const FileUtils = ChromeUtils.importESModule(
8   "resource://gre/modules/FileUtils.sys.mjs"
9 ).FileUtils;
11 const RECORD_ID = "tld-dafsa";
12 const SIGNAL = "public-suffix-list-updated";
14 export const PublicSuffixList = {
15   CLIENT: RemoteSettings("public-suffix-list"),
17   init() {
18     // Only initialize once.
19     if (this._initialized) {
20       return;
21     }
22     this._initialized = true;
24     this.CLIENT.on("sync", this.onUpdate.bind(this));
25     /* We have a single record for this collection. Let's see if we already have it locally.
26      * Note that on startup, we don't need to synchronize immediately on new profiles.
27      */
28     this.CLIENT.get({ syncIfEmpty: false, filters: { id: RECORD_ID } })
29       .then(async records => {
30         if (records.length == 1) {
31           // Get the downloaded file URI (most likely to be a no-op here, since file will exist).
32           const fileURI = await this.CLIENT.attachments.downloadToDisk(
33             records[0]
34           );
35           // Send a signal so that the C++ code loads the updated list on startup.
36           this.notifyUpdate(fileURI);
37         }
38       })
39       .catch(err => console.error(err));
40   },
42   /**
43    * This method returns the path to the file based on the file uri received
44    * Example:
45    * On windows "file://C:/Users/AppData/main/public-suffix-list/dafsa.bin"
46    * will be converted to "C:\\Users\\main\\public-suffix-list\\dafsa.bin
47    *
48    * On macOS/linux "file:///home/main/public-suffix-list/dafsa.bin"
49    * will be converted to "/home/main/public-suffix-list/dafsa.bin"
50    */
51   getFilePath(fileURI) {
52     const uri = Services.io.newURI(fileURI);
53     const file = uri.QueryInterface(Ci.nsIFileURL).file;
54     return file.path;
55   },
57   notifyUpdate(fileURI) {
58     if (!Services.prefs.getBoolPref("network.psl.onUpdate_notify", false)) {
59       // Updating the PSL while Firefox is running could cause principals to
60       // have a different base domain before/after the update.
61       // See bug 1582647 comment 30
62       return;
63     }
65     const filePath = this.getFilePath(fileURI);
66     const nsifile = new FileUtils.File(filePath);
67     /* Send a signal to be read by the C++, the method
68      * ::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
69      * at netwerk/dns/nsEffectiveTLDService.cpp
70      */
71     Services.obs.notifyObservers(
72       nsifile, // aSubject
73       SIGNAL, // aTopic
74       filePath // aData
75     );
76   },
78   async onUpdate({ data: { created, updated, deleted } }) {
79     // In theory, this will never happen, we will never delete the record.
80     if (deleted.length == 1) {
81       await this.CLIENT.attachments.deleteFromDisk(deleted[0]);
82     }
83     // Handle creation and update the same way
84     const changed = created.concat(updated.map(u => u.new));
85     /* In theory, we should never have more than one record. And if we receive
86      * this event, it's because the single record was updated.
87      */
88     if (changed.length != 1) {
89       console.warn("Unsupported sync event for Public Suffix List");
90       return;
91     }
92     // Download the updated file.
93     let fileURI;
94     try {
95       fileURI = await this.CLIENT.attachments.downloadToDisk(changed[0]);
96     } catch (err) {
97       console.error(err);
98       return;
99     }
101     // Notify the C++ part to reload it from disk.
102     this.notifyUpdate(fileURI);
103   },