Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/plugins/default-browser-emulator/injected-scripts/navigator.plugins.ts
1029 views
1
function installNamedNodeItems(
2
nativeObj: PluginArray | MimeTypeArray,
3
list: (Plugin | MimeType)[],
4
prop: 'type' | 'name',
5
) {
6
const props = [];
7
for (let i = 0; i < list.length; i += 1) {
8
const item = list[i];
9
props.push(String(i));
10
Object.defineProperty(nativeObj, i, {
11
value: item,
12
enumerable: true,
13
writable: false,
14
configurable: true,
15
});
16
}
17
for (const item of list) {
18
props.push(item[prop]);
19
Object.defineProperty(nativeObj, item[prop], {
20
value: item,
21
enumerable: false,
22
writable: false,
23
configurable: true,
24
});
25
}
26
return props;
27
}
28
29
function createNamedNodeMap(
30
protoClass: PluginArray | MimeTypeArray,
31
list: (Plugin | MimeType)[],
32
prop: 'type' | 'name',
33
) {
34
const nativeObj = Object.create(protoClass) as PluginArray | MimeTypeArray;
35
36
installNamedNodeItems(nativeObj, list, prop);
37
38
proxyFunction(
39
nativeObj,
40
'item',
41
(target, thisArg, argArray) => {
42
if (!argArray || !argArray.length) return ProxyOverride.callOriginal;
43
return thisArg[argArray[0]];
44
},
45
true,
46
);
47
proxyFunction(
48
nativeObj,
49
'namedItem',
50
(target, thisArg, argArray) => {
51
if (!argArray || !argArray.length) return ProxyOverride.callOriginal;
52
return thisArg[argArray[0]];
53
},
54
true,
55
);
56
if (nativeObj instanceof PluginArray) {
57
proxyFunction(nativeObj, 'refresh', () => undefined, true);
58
}
59
// @ts-ignore - seems to be missing from ts def
60
// proxyFunction(nativeObj, Symbol.iterator, () => [...list], true);
61
proxyGetter(nativeObj, 'length', () => list.length, true);
62
return nativeObj;
63
}
64
65
function createMime(fakeMime) {
66
const mime: MimeType = Object.create(MimeType.prototype);
67
proxyGetter(mime, 'type', () => fakeMime.type, true);
68
proxyGetter(mime, 'suffixes', () => fakeMime.suffixes, true);
69
proxyGetter(mime, 'description', () => fakeMime.description, true);
70
proxyGetter(mime, 'enabledPlugin', () => navigator.plugins[fakeMime.__pluginName], true);
71
return mime;
72
}
73
74
const mimeList: MimeType[] = args.mimeTypes.map(createMime);
75
const mimes = createNamedNodeMap(MimeTypeArray.prototype, mimeList, 'type') as MimeTypeArray;
76
77
const pluginList: Plugin[] = args.plugins.map(fakeP => {
78
let plugin: Plugin = Object.create(Plugin.prototype);
79
80
const pluginMimes = args.mimeTypes.filter(m => m.__pluginName === fakeP.name);
81
const mimeProps = installNamedNodeItems(plugin, pluginMimes.map(createMime), 'type');
82
83
proxyGetter(plugin, 'name', () => fakeP.name, true);
84
proxyGetter(plugin, 'description', () => fakeP.description, true);
85
proxyGetter(plugin, 'filename', () => fakeP.filename, true);
86
proxyGetter(plugin, 'length', () => pluginMimes.length, true);
87
proxyFunction(
88
plugin,
89
'item',
90
(target, thisArg, argArray) => {
91
if (!argArray || !argArray.length) return ProxyOverride.callOriginal;
92
const entry = pluginMimes[argArray[0]];
93
if (entry) return createMime(entry);
94
},
95
true,
96
);
97
proxyFunction(
98
plugin,
99
'namedItem',
100
(_, __, argArray) => {
101
if (!argArray || !argArray.length) return ProxyOverride.callOriginal;
102
const match = pluginMimes.find(x => x.type === argArray[0]);
103
if (match) return createMime(match);
104
},
105
true,
106
);
107
108
plugin = new Proxy(plugin, {
109
get(target, p) {
110
if (mimeProps.includes(p)) {
111
let fakeMime = pluginMimes.find(x => x.type === p);
112
if (new RegExp(/^\d+$/).test(String(p))) {
113
fakeMime = pluginMimes[p];
114
}
115
return createMime(fakeMime);
116
}
117
118
return target[p];
119
},
120
});
121
122
return plugin;
123
});
124
125
const navigatorPlugins = createNamedNodeMap(
126
PluginArray.prototype,
127
pluginList,
128
'name',
129
) as PluginArray;
130
131
proxyGetter(navigator, 'mimeTypes', () => mimes, true);
132
proxyGetter(navigator, 'plugins', () => navigatorPlugins, true);
133
134