blob: 6ab9ca86423cbb7ff573bc66dd7e7cd842094dab (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
LoginHelper: "resource://gre/modules/LoginHelper.sys.mjs",
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
});
ChromeUtils.defineLazyGetter(lazy, "log", () => {
let logger = lazy.LoginHelper.createLogger("LoginRelatedRealms");
return logger;
});
export class LoginRelatedRealmsParent extends JSWindowActorParent {
/**
* @type RemoteSettingsClient
*
* @memberof LoginRelatedRealmsParent
*/
_sharedCredentialsClient = null;
/**
* @type string[][]
*
* @memberof LoginRelatedRealmsParent
*/
_relatedDomainsList = [[]];
/**
* Handles the Remote Settings sync event
*
* @param {Object} aEvent
* @param {Array} aEvent.current Records that are currently in the collection after the sync event
* @param {Array} aEvent.created Records that were created
* @param {Array} aEvent.updated Records that were updated
* @param {Array} aEvent.deleted Records that were deleted
* @memberof LoginRelatedRealmsParent
*/
onRemoteSettingsSync(aEvent) {
let {
data: { current },
} = aEvent;
this._relatedDomainsList = current;
}
async getSharedCredentialsCollection() {
if (!this._sharedCredentialsClient) {
this._sharedCredentialsClient = lazy.RemoteSettings(
lazy.LoginHelper.relatedRealmsCollection
);
this._sharedCredentialsClient.on("sync", event =>
this.onRemoteSettingsSync(event)
);
this._relatedDomainsList = await this._sharedCredentialsClient.get();
}
return this._relatedDomainsList;
}
/**
* Determine if there are any related realms of this `formOrigin` using the related realms collection
* @param {string} formOrigin A form origin
* @return {string[]} filteredRealms An array of domains related to the `formOrigin`
* @async
* @memberof LoginRelatedRealmsParent
*/
async findRelatedRealms(formOrigin) {
try {
let formOriginURI = Services.io.newURI(formOrigin);
let originDomain = formOriginURI.host;
let [{ relatedRealms } = {}] =
await this.getSharedCredentialsCollection();
if (!relatedRealms) {
return [];
}
let filterOriginIndex;
let shouldInclude = false;
let filteredRealms = relatedRealms.filter(_realms => {
for (let relatedOrigin of _realms) {
// We can't have an origin that matches multiple entries in our related realms collection
// so we exit the loop early
if (shouldInclude) {
return false;
}
if (Services.eTLD.hasRootDomain(originDomain, relatedOrigin)) {
shouldInclude = true;
break;
}
}
return shouldInclude;
});
// * Filtered realms is a nested array due to its structure in Remote Settings
filteredRealms = filteredRealms.flat();
filterOriginIndex = filteredRealms.indexOf(originDomain);
// Removing the current formOrigin match if it exists in the related realms
// so that we don't return duplicates when we search for logins
if (filterOriginIndex !== -1) {
filteredRealms.splice(filterOriginIndex, 1);
}
return filteredRealms;
} catch (e) {
lazy.log.error(e);
return [];
}
}
}
|