@lvce-editor/main-process 6.27.2 → 6.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mainProcessMain.js +159 -507
- package/package.json +2 -3
package/dist/mainProcessMain.js
CHANGED
|
@@ -10,9 +10,8 @@ import * as NodePath from 'node:path';
|
|
|
10
10
|
import { dirname as dirname$1, join as join$1, isAbsolute } from 'node:path';
|
|
11
11
|
import { homedir, tmpdir } from 'node:os';
|
|
12
12
|
import { readFile } from 'node:fs/promises';
|
|
13
|
-
import { pbkdf2Sync, createDecipheriv, createHash } from 'node:crypto';
|
|
14
|
-
import { DatabaseSync } from 'node:sqlite';
|
|
15
13
|
import { MessageChannel } from 'node:worker_threads';
|
|
14
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
16
15
|
|
|
17
16
|
const scheme = 'lvce-oss';
|
|
18
17
|
const applicationName = 'lvce-oss';
|
|
@@ -4667,6 +4666,33 @@ const load = async (path, env = process.env) => {
|
|
|
4667
4666
|
}
|
|
4668
4667
|
};
|
|
4669
4668
|
|
|
4669
|
+
const createWindowCloseHandler = (window, rpc, onError, dispose = () => {}) => {
|
|
4670
|
+
let closePending = false;
|
|
4671
|
+
const handleWindowClose = event => {
|
|
4672
|
+
event.preventDefault();
|
|
4673
|
+
if (closePending) {
|
|
4674
|
+
return;
|
|
4675
|
+
}
|
|
4676
|
+
closePending = true;
|
|
4677
|
+
void (async () => {
|
|
4678
|
+
try {
|
|
4679
|
+
await rpc.invoke('Window.prepareClose');
|
|
4680
|
+
} catch (error) {
|
|
4681
|
+
onError(error);
|
|
4682
|
+
} finally {
|
|
4683
|
+
try {
|
|
4684
|
+
dispose();
|
|
4685
|
+
} catch (error) {
|
|
4686
|
+
onError(error);
|
|
4687
|
+
}
|
|
4688
|
+
window.off('close', handleWindowClose);
|
|
4689
|
+
window.close();
|
|
4690
|
+
}
|
|
4691
|
+
})();
|
|
4692
|
+
};
|
|
4693
|
+
return handleWindowClose;
|
|
4694
|
+
};
|
|
4695
|
+
|
|
4670
4696
|
const accessControlAllowOrigin = 'access-control-allow-origin';
|
|
4671
4697
|
const getCorsResponseHeaders = (responseHeaders = {}) => {
|
|
4672
4698
|
const hasAccessControlAllowOrigin = Object.keys(responseHeaders).some(key => key.toLowerCase() === accessControlAllowOrigin);
|
|
@@ -5002,14 +5028,7 @@ const createAppWindow = async (windowOptions, parsedArgs, workingDirectory, titl
|
|
|
5002
5028
|
webContents: window.webContents
|
|
5003
5029
|
});
|
|
5004
5030
|
const disposeFullScreenListener = listen$1(window, rpc);
|
|
5005
|
-
const handleWindowClose = (
|
|
5006
|
-
try {
|
|
5007
|
-
disposeFullScreenListener();
|
|
5008
|
-
window.off('close', handleWindowClose);
|
|
5009
|
-
} catch (error) {
|
|
5010
|
-
handleError(new VError(error, `Failed to run window close listener`));
|
|
5011
|
-
}
|
|
5012
|
-
};
|
|
5031
|
+
const handleWindowClose = createWindowCloseHandler(window, rpc, error => handleError(new VError(error, `Failed to prepare window close`)), disposeFullScreenListener);
|
|
5013
5032
|
window.on('close', handleWindowClose);
|
|
5014
5033
|
await loadUrl(window, url);
|
|
5015
5034
|
};
|
|
@@ -5018,501 +5037,6 @@ const beep$1 = () => {
|
|
|
5018
5037
|
shell.beep();
|
|
5019
5038
|
};
|
|
5020
5039
|
|
|
5021
|
-
const chromeV10Prefix = Buffer.from('v10');
|
|
5022
|
-
const chromeV11Prefix = Buffer.from('v11');
|
|
5023
|
-
const chromeV10Key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1');
|
|
5024
|
-
const chromeV10Iv = Buffer.alloc(16, 0x20);
|
|
5025
|
-
const domainHashLength = 32;
|
|
5026
|
-
class UnsupportedChromeCookieEncryptionError extends Error {
|
|
5027
|
-
constructor() {
|
|
5028
|
-
super('Unsupported Chrome cookie encryption format');
|
|
5029
|
-
this.name = 'UnsupportedChromeCookieEncryptionError';
|
|
5030
|
-
}
|
|
5031
|
-
}
|
|
5032
|
-
const isV11 = encryptedValue => {
|
|
5033
|
-
return Buffer.from(encryptedValue).subarray(0, chromeV11Prefix.length).equals(chromeV11Prefix);
|
|
5034
|
-
};
|
|
5035
|
-
const decrypt$1 = (hostKey, encryptedValue, databaseVersion, chromeSafeStoragePassword) => {
|
|
5036
|
-
const buffer = Buffer.from(encryptedValue);
|
|
5037
|
-
if (buffer.length <= chromeV10Prefix.length) {
|
|
5038
|
-
throw new UnsupportedChromeCookieEncryptionError();
|
|
5039
|
-
}
|
|
5040
|
-
const prefix = buffer.subarray(0, chromeV10Prefix.length);
|
|
5041
|
-
let key;
|
|
5042
|
-
if (prefix.equals(chromeV10Prefix)) {
|
|
5043
|
-
key = chromeV10Key;
|
|
5044
|
-
} else if (prefix.equals(chromeV11Prefix) && chromeSafeStoragePassword !== undefined) {
|
|
5045
|
-
key = pbkdf2Sync(chromeSafeStoragePassword, 'saltysalt', 1, 16, 'sha1');
|
|
5046
|
-
} else {
|
|
5047
|
-
throw new UnsupportedChromeCookieEncryptionError();
|
|
5048
|
-
}
|
|
5049
|
-
const decipher = createDecipheriv('aes-128-cbc', key, chromeV10Iv);
|
|
5050
|
-
const plaintext = Buffer.concat([decipher.update(buffer.subarray(prefix.length)), decipher.final()]);
|
|
5051
|
-
if (databaseVersion < 24) {
|
|
5052
|
-
return plaintext.toString('utf8');
|
|
5053
|
-
}
|
|
5054
|
-
if (plaintext.length < domainHashLength) {
|
|
5055
|
-
throw new Error('Chrome cookie domain integrity check failed');
|
|
5056
|
-
}
|
|
5057
|
-
const expectedDomainHash = createHash('sha256').update(hostKey).digest();
|
|
5058
|
-
const actualDomainHash = plaintext.subarray(0, domainHashLength);
|
|
5059
|
-
if (!actualDomainHash.equals(expectedDomainHash)) {
|
|
5060
|
-
throw new Error('Chrome cookie domain integrity check failed');
|
|
5061
|
-
}
|
|
5062
|
-
return plaintext.subarray(domainHashLength).toString('utf8');
|
|
5063
|
-
};
|
|
5064
|
-
|
|
5065
|
-
const chromeEpochOffsetMicroseconds = 11_644_473_600_000_000n;
|
|
5066
|
-
const microsecondsPerSecond = 1_000_000n;
|
|
5067
|
-
const getSameSite$1 = sameSite => {
|
|
5068
|
-
switch (sameSite) {
|
|
5069
|
-
case 0:
|
|
5070
|
-
return 'no_restriction';
|
|
5071
|
-
case 1:
|
|
5072
|
-
return 'lax';
|
|
5073
|
-
case 2:
|
|
5074
|
-
return 'strict';
|
|
5075
|
-
default:
|
|
5076
|
-
return 'unspecified';
|
|
5077
|
-
}
|
|
5078
|
-
};
|
|
5079
|
-
const getExpirationDate = expiresUtc => {
|
|
5080
|
-
const chromeMicroseconds = BigInt(expiresUtc);
|
|
5081
|
-
return Number(chromeMicroseconds - chromeEpochOffsetMicroseconds) / Number(microsecondsPerSecond);
|
|
5082
|
-
};
|
|
5083
|
-
const getValue = (row, databaseVersion, chromeSafeStoragePassword) => {
|
|
5084
|
-
if (row.value) {
|
|
5085
|
-
return row.value;
|
|
5086
|
-
}
|
|
5087
|
-
return decrypt$1(row.hostKey, row.encryptedValue, databaseVersion, chromeSafeStoragePassword);
|
|
5088
|
-
};
|
|
5089
|
-
const convert$1 = (row, databaseVersion, chromeSafeStoragePassword, now = Date.now() / 1000) => {
|
|
5090
|
-
if (!row.hostKey || row.topFrameSiteKey) {
|
|
5091
|
-
return undefined;
|
|
5092
|
-
}
|
|
5093
|
-
const host = row.hostKey.startsWith('.') ? row.hostKey.slice(1) : row.hostKey;
|
|
5094
|
-
if (!host) {
|
|
5095
|
-
return undefined;
|
|
5096
|
-
}
|
|
5097
|
-
const secure = Boolean(row.isSecure);
|
|
5098
|
-
const details = {
|
|
5099
|
-
httpOnly: Boolean(row.isHttpOnly),
|
|
5100
|
-
name: row.name,
|
|
5101
|
-
path: row.path || '/',
|
|
5102
|
-
sameSite: getSameSite$1(row.sameSite),
|
|
5103
|
-
secure,
|
|
5104
|
-
url: `${secure ? 'https' : 'http'}://${host}/`,
|
|
5105
|
-
value: getValue(row, databaseVersion, chromeSafeStoragePassword)
|
|
5106
|
-
};
|
|
5107
|
-
if (row.hostKey.startsWith('.')) {
|
|
5108
|
-
details.domain = row.hostKey;
|
|
5109
|
-
}
|
|
5110
|
-
if (row.hasExpires) {
|
|
5111
|
-
const expirationDate = getExpirationDate(row.expiresUtc);
|
|
5112
|
-
if (!Number.isFinite(expirationDate) || expirationDate <= now) {
|
|
5113
|
-
return undefined;
|
|
5114
|
-
}
|
|
5115
|
-
details.expirationDate = expirationDate;
|
|
5116
|
-
}
|
|
5117
|
-
return details;
|
|
5118
|
-
};
|
|
5119
|
-
|
|
5120
|
-
/* eslint-disable n/no-unsupported-features/node-builtins -- Electron 43 provides the node:sqlite API used by the main process */
|
|
5121
|
-
const getDatabaseError$1 = error => {
|
|
5122
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
5123
|
-
if (message.toLowerCase().includes('locked') || message.toLowerCase().includes('busy')) {
|
|
5124
|
-
return new Error('Chrome cookie database is busy. Close Chrome and try again.');
|
|
5125
|
-
}
|
|
5126
|
-
return new Error('Failed to read the Chrome cookie database');
|
|
5127
|
-
};
|
|
5128
|
-
const withDatabase$1 = (path, fn) => {
|
|
5129
|
-
let database;
|
|
5130
|
-
try {
|
|
5131
|
-
database = new DatabaseSync(path, {
|
|
5132
|
-
readOnly: true
|
|
5133
|
-
});
|
|
5134
|
-
database.exec('PRAGMA busy_timeout = 1000');
|
|
5135
|
-
return fn(database);
|
|
5136
|
-
} catch (error) {
|
|
5137
|
-
if (error instanceof Error && error.message.startsWith('Unsupported Chrome cookie database version')) {
|
|
5138
|
-
throw error;
|
|
5139
|
-
}
|
|
5140
|
-
throw getDatabaseError$1(error);
|
|
5141
|
-
} finally {
|
|
5142
|
-
database?.close();
|
|
5143
|
-
}
|
|
5144
|
-
};
|
|
5145
|
-
const getVersion$1 = database => {
|
|
5146
|
-
const row = database.prepare(`SELECT value FROM meta WHERE key = 'version'`).get();
|
|
5147
|
-
const version = Number(row?.value);
|
|
5148
|
-
if (version !== 24) {
|
|
5149
|
-
throw new Error(`Unsupported Chrome cookie database version ${Number.isFinite(version) ? version : 'unknown'}`);
|
|
5150
|
-
}
|
|
5151
|
-
return version;
|
|
5152
|
-
};
|
|
5153
|
-
const getCookieCount$1 = path => {
|
|
5154
|
-
return withDatabase$1(path, database => {
|
|
5155
|
-
getVersion$1(database);
|
|
5156
|
-
const row = database.prepare('SELECT COUNT(*) AS count FROM cookies').get();
|
|
5157
|
-
return row.count;
|
|
5158
|
-
});
|
|
5159
|
-
};
|
|
5160
|
-
const readCookies$1 = path => {
|
|
5161
|
-
return withDatabase$1(path, database => {
|
|
5162
|
-
const version = getVersion$1(database);
|
|
5163
|
-
const rows = database.prepare(`
|
|
5164
|
-
SELECT
|
|
5165
|
-
encrypted_value AS encryptedValue,
|
|
5166
|
-
CAST(expires_utc AS TEXT) AS expiresUtc,
|
|
5167
|
-
has_expires AS hasExpires,
|
|
5168
|
-
host_key AS hostKey,
|
|
5169
|
-
is_httponly AS isHttpOnly,
|
|
5170
|
-
is_secure AS isSecure,
|
|
5171
|
-
name,
|
|
5172
|
-
path,
|
|
5173
|
-
samesite AS sameSite,
|
|
5174
|
-
top_frame_site_key AS topFrameSiteKey,
|
|
5175
|
-
value
|
|
5176
|
-
FROM cookies
|
|
5177
|
-
`).all();
|
|
5178
|
-
return {
|
|
5179
|
-
rows,
|
|
5180
|
-
version
|
|
5181
|
-
};
|
|
5182
|
-
});
|
|
5183
|
-
};
|
|
5184
|
-
|
|
5185
|
-
const secretServiceName = 'org.freedesktop.secrets';
|
|
5186
|
-
const secretServicePath = '/org/freedesktop/secrets';
|
|
5187
|
-
const secretServiceInterface = 'org.freedesktop.Secret.Service';
|
|
5188
|
-
const secretCollectionInterface = 'org.freedesktop.Secret.Collection';
|
|
5189
|
-
const secretItemInterface = 'org.freedesktop.Secret.Item';
|
|
5190
|
-
const propertiesInterface = 'org.freedesktop.DBus.Properties';
|
|
5191
|
-
const defaultCollectionPath = '/org/freedesktop/secrets/aliases/default';
|
|
5192
|
-
const chromeSafeStorageLabel = 'Chrome Safe Storage';
|
|
5193
|
-
const getProperties = async (bus, path) => {
|
|
5194
|
-
return bus.getService(secretServiceName).getInterface(path, propertiesInterface);
|
|
5195
|
-
};
|
|
5196
|
-
const findChromeSafeStorageItem = async (bus, service) => {
|
|
5197
|
-
const [unlocked, locked] = await service.SearchItems({
|
|
5198
|
-
application: 'chrome'
|
|
5199
|
-
});
|
|
5200
|
-
const matchingItems = [...unlocked, ...locked];
|
|
5201
|
-
if (matchingItems.length > 0) {
|
|
5202
|
-
return matchingItems[0];
|
|
5203
|
-
}
|
|
5204
|
-
const collectionProperties = await getProperties(bus, defaultCollectionPath);
|
|
5205
|
-
const items = await collectionProperties.Get(secretCollectionInterface, 'Items');
|
|
5206
|
-
for (const item of items) {
|
|
5207
|
-
const itemProperties = await getProperties(bus, item);
|
|
5208
|
-
const label = await itemProperties.Get(secretItemInterface, 'Label');
|
|
5209
|
-
if (label === chromeSafeStorageLabel) {
|
|
5210
|
-
return item;
|
|
5211
|
-
}
|
|
5212
|
-
}
|
|
5213
|
-
throw new Error('Chrome Safe Storage password was not found in the Linux keyring');
|
|
5214
|
-
};
|
|
5215
|
-
const unlockItem = async (service, item) => {
|
|
5216
|
-
const [unlocked, prompt] = await service.Unlock([item]);
|
|
5217
|
-
if (unlocked.includes(item)) {
|
|
5218
|
-
return;
|
|
5219
|
-
}
|
|
5220
|
-
if (prompt !== '/') {
|
|
5221
|
-
throw new Error('Chrome Safe Storage is locked; unlock the desktop keyring and try again');
|
|
5222
|
-
}
|
|
5223
|
-
throw new Error('Chrome Safe Storage could not be unlocked');
|
|
5224
|
-
};
|
|
5225
|
-
const readPassword = async (bus, sessionInput) => {
|
|
5226
|
-
const service = await bus.getService(secretServiceName).getInterface(secretServicePath, secretServiceInterface);
|
|
5227
|
-
const [, sessionPath] = await service.OpenSession('plain', sessionInput);
|
|
5228
|
-
const item = await findChromeSafeStorageItem(bus, service);
|
|
5229
|
-
let secrets;
|
|
5230
|
-
try {
|
|
5231
|
-
secrets = await service.GetSecrets([item], sessionPath);
|
|
5232
|
-
} catch {
|
|
5233
|
-
await unlockItem(service, item);
|
|
5234
|
-
secrets = await service.GetSecrets([item], sessionPath);
|
|
5235
|
-
}
|
|
5236
|
-
const secret = secrets[item];
|
|
5237
|
-
if (!secret) {
|
|
5238
|
-
throw new Error('Chrome Safe Storage password was not returned by the Linux keyring');
|
|
5239
|
-
}
|
|
5240
|
-
return Buffer.from(secret[2]).toString('utf8');
|
|
5241
|
-
};
|
|
5242
|
-
const getErrorMessage = error => {
|
|
5243
|
-
return error instanceof Error ? error.message : String(error);
|
|
5244
|
-
};
|
|
5245
|
-
const getChromeSafeStoragePassword = async () => {
|
|
5246
|
-
const {
|
|
5247
|
-
default: dbus,
|
|
5248
|
-
Variant
|
|
5249
|
-
} = await import('dbus-native');
|
|
5250
|
-
const bus = dbus.sessionBus({
|
|
5251
|
-
timeout: 5000
|
|
5252
|
-
});
|
|
5253
|
-
try {
|
|
5254
|
-
return await readPassword(bus, new Variant('s', ''));
|
|
5255
|
-
} catch (error) {
|
|
5256
|
-
throw new Error(`Failed to read Chrome Safe Storage password: ${getErrorMessage(error)}`);
|
|
5257
|
-
} finally {
|
|
5258
|
-
await bus.close();
|
|
5259
|
-
}
|
|
5260
|
-
};
|
|
5261
|
-
|
|
5262
|
-
const isValidProfileDirectory = value => {
|
|
5263
|
-
return value !== '' && value !== '.' && value !== '..' && !value.includes('/') && !value.includes('\\');
|
|
5264
|
-
};
|
|
5265
|
-
const getCookieDatabasePath = (chromeDataDirectory, profileDirectory) => {
|
|
5266
|
-
const profilePath = join$1(chromeDataDirectory, profileDirectory);
|
|
5267
|
-
const candidates = [join$1(profilePath, 'Cookies'), join$1(profilePath, 'Network', 'Cookies')];
|
|
5268
|
-
for (const candidate of candidates) {
|
|
5269
|
-
if (existsSync(candidate)) {
|
|
5270
|
-
return candidate;
|
|
5271
|
-
}
|
|
5272
|
-
}
|
|
5273
|
-
throw new Error(`Chrome cookie database was not found for profile ${profileDirectory}`);
|
|
5274
|
-
};
|
|
5275
|
-
const getMostRecentlyActiveProfile = infoCache => {
|
|
5276
|
-
let selected;
|
|
5277
|
-
let selectedActiveTime = -Infinity;
|
|
5278
|
-
for (const [directory, info] of Object.entries(infoCache)) {
|
|
5279
|
-
if (!isValidProfileDirectory(directory)) {
|
|
5280
|
-
continue;
|
|
5281
|
-
}
|
|
5282
|
-
const activeTime = typeof info.active_time === 'number' && Number.isFinite(info.active_time) ? info.active_time : -Infinity;
|
|
5283
|
-
if (selected === undefined || activeTime > selectedActiveTime) {
|
|
5284
|
-
selected = directory;
|
|
5285
|
-
selectedActiveTime = activeTime;
|
|
5286
|
-
}
|
|
5287
|
-
}
|
|
5288
|
-
return selected;
|
|
5289
|
-
};
|
|
5290
|
-
const getChromeDataDirectory = () => {
|
|
5291
|
-
const configDirectory = process.env.XDG_CONFIG_HOME || join$1(homedir(), '.config');
|
|
5292
|
-
return join$1(configDirectory, 'google-chrome');
|
|
5293
|
-
};
|
|
5294
|
-
const getActiveProfile$1 = chromeDataDirectory => {
|
|
5295
|
-
const localStatePath = join$1(chromeDataDirectory, 'Local State');
|
|
5296
|
-
if (!existsSync(localStatePath)) {
|
|
5297
|
-
throw new Error(`Google Chrome profile data was not found at ${chromeDataDirectory}`);
|
|
5298
|
-
}
|
|
5299
|
-
let localState;
|
|
5300
|
-
try {
|
|
5301
|
-
localState = JSON.parse(readFileSync(localStatePath, 'utf8'));
|
|
5302
|
-
} catch {
|
|
5303
|
-
throw new Error('Google Chrome profile metadata is invalid');
|
|
5304
|
-
}
|
|
5305
|
-
const infoCache = localState.profile?.info_cache || {};
|
|
5306
|
-
const orderedProfile = localState.profile?.profiles_order?.find(isValidProfileDirectory);
|
|
5307
|
-
const directory = getMostRecentlyActiveProfile(infoCache) || orderedProfile || 'Default';
|
|
5308
|
-
const name = infoCache[directory]?.name || directory;
|
|
5309
|
-
const cookieDatabasePath = getCookieDatabasePath(chromeDataDirectory, directory);
|
|
5310
|
-
return {
|
|
5311
|
-
cookieDatabasePath,
|
|
5312
|
-
directory,
|
|
5313
|
-
name
|
|
5314
|
-
};
|
|
5315
|
-
};
|
|
5316
|
-
|
|
5317
|
-
const MainFrame = 'mainFrame';
|
|
5318
|
-
const Script = 'script';
|
|
5319
|
-
const Xhr = 'xhr';
|
|
5320
|
-
|
|
5321
|
-
const Get = 'GET';
|
|
5322
|
-
const Head = 'HEAD';
|
|
5323
|
-
const Options = 'OPTIONS';
|
|
5324
|
-
const Post = 'POST';
|
|
5325
|
-
|
|
5326
|
-
// @ts-ignore
|
|
5327
|
-
|
|
5328
|
-
const getBeforeRequestResponseMainFrame = (method, url) => {
|
|
5329
|
-
return {};
|
|
5330
|
-
};
|
|
5331
|
-
const cancelIfStartsWith = (url, canceledUrls) => {
|
|
5332
|
-
for (const canceledUrl of canceledUrls) {
|
|
5333
|
-
if (url.startsWith(canceledUrl)) {
|
|
5334
|
-
return {
|
|
5335
|
-
cancel: true
|
|
5336
|
-
};
|
|
5337
|
-
}
|
|
5338
|
-
}
|
|
5339
|
-
return {};
|
|
5340
|
-
};
|
|
5341
|
-
const getBeforeRequestResponseXhrPost = url => {
|
|
5342
|
-
const canceledUrls = ['https://www.youtube.com/api/stats/qoe', 'https://www.youtube.com/youtubei/v1/log_event', 'https://play.google.com/log'];
|
|
5343
|
-
return cancelIfStartsWith(url, canceledUrls);
|
|
5344
|
-
};
|
|
5345
|
-
const getBeforeRequestResponseXhrGet = url => {
|
|
5346
|
-
const canceledUrls = ['https://www.youtube.com/pagead/', 'https://www.youtube.com/api/stats/qoe', 'https://www.youtube.com/api/stats/ads', 'https://www.youtube.com/api/stats/delayplay', 'https://www.youtube.com/ptracking', 'https://www.youtube.com/api/timedtext', 'https://www.youtube.com/pcs/activeview', 'https://googleads.g.doubleclick.net/pagead/id'];
|
|
5347
|
-
return cancelIfStartsWith(url, canceledUrls);
|
|
5348
|
-
};
|
|
5349
|
-
const getBeforeRequestResponseXhrOptions = url => {
|
|
5350
|
-
const canceledUrls = ['https://play.google.com/log'];
|
|
5351
|
-
return cancelIfStartsWith(url, canceledUrls);
|
|
5352
|
-
};
|
|
5353
|
-
const getBeforeRequestResponseXhrHead = url => {
|
|
5354
|
-
const canceledUrls = ['https://www.youtube.com/generate_204'];
|
|
5355
|
-
return cancelIfStartsWith(url, canceledUrls);
|
|
5356
|
-
};
|
|
5357
|
-
const getBeforeRequestResponseXhr = (method, url) => {
|
|
5358
|
-
switch (method) {
|
|
5359
|
-
case Get:
|
|
5360
|
-
return getBeforeRequestResponseXhrGet(url);
|
|
5361
|
-
case Head:
|
|
5362
|
-
return getBeforeRequestResponseXhrHead(url);
|
|
5363
|
-
case Options:
|
|
5364
|
-
return getBeforeRequestResponseXhrOptions(url);
|
|
5365
|
-
case Post:
|
|
5366
|
-
return getBeforeRequestResponseXhrPost(url);
|
|
5367
|
-
default:
|
|
5368
|
-
return {};
|
|
5369
|
-
}
|
|
5370
|
-
};
|
|
5371
|
-
const getBeforeRequestResponseDefault = (method, url) => {
|
|
5372
|
-
return {};
|
|
5373
|
-
};
|
|
5374
|
-
const getBeforeRequestResponseScript = (method, url) => {
|
|
5375
|
-
const canceledUrls = ['https://static.doubleclick.net'];
|
|
5376
|
-
return cancelIfStartsWith(url, canceledUrls);
|
|
5377
|
-
};
|
|
5378
|
-
const getBeforeRequestResponse = details => {
|
|
5379
|
-
const {
|
|
5380
|
-
method,
|
|
5381
|
-
resourceType,
|
|
5382
|
-
url
|
|
5383
|
-
} = details;
|
|
5384
|
-
switch (resourceType) {
|
|
5385
|
-
case MainFrame:
|
|
5386
|
-
return getBeforeRequestResponseMainFrame();
|
|
5387
|
-
case Script:
|
|
5388
|
-
return getBeforeRequestResponseScript(method, url);
|
|
5389
|
-
case Xhr:
|
|
5390
|
-
return getBeforeRequestResponseXhr(method, url);
|
|
5391
|
-
default:
|
|
5392
|
-
return getBeforeRequestResponseDefault();
|
|
5393
|
-
}
|
|
5394
|
-
};
|
|
5395
|
-
|
|
5396
|
-
/**
|
|
5397
|
-
*
|
|
5398
|
-
* @param {Electron.OnBeforeRequestListenerDetails } details
|
|
5399
|
-
* @param {(response: globalThis.Electron.CallbackResponse) => void} callback
|
|
5400
|
-
*/
|
|
5401
|
-
const handleBeforeRequest = (details, callback) => {
|
|
5402
|
-
const response = getBeforeRequestResponse(details);
|
|
5403
|
-
callback(response);
|
|
5404
|
-
};
|
|
5405
|
-
const filter = {
|
|
5406
|
-
// urls: ['https://*.youtube.com/*'],
|
|
5407
|
-
urls: ['<all_urls>']
|
|
5408
|
-
};
|
|
5409
|
-
|
|
5410
|
-
const state = {
|
|
5411
|
-
session: undefined
|
|
5412
|
-
};
|
|
5413
|
-
const isAllowedPermission = permission => {
|
|
5414
|
-
switch (permission) {
|
|
5415
|
-
case ClipBoardRead:
|
|
5416
|
-
case ClipBoardSanitizedWrite:
|
|
5417
|
-
case FullScreen:
|
|
5418
|
-
case GeoLocation:
|
|
5419
|
-
case WindowPlacement:
|
|
5420
|
-
return true;
|
|
5421
|
-
default:
|
|
5422
|
-
return false;
|
|
5423
|
-
}
|
|
5424
|
-
};
|
|
5425
|
-
const handlePermissionRequest = (webContents, permission, callback, details) => {
|
|
5426
|
-
callback(isAllowedPermission(permission));
|
|
5427
|
-
};
|
|
5428
|
-
const handlePermissionCheck = (webContents, permission, origin, details) => {
|
|
5429
|
-
return isAllowedPermission(permission);
|
|
5430
|
-
};
|
|
5431
|
-
const createSession = () => {
|
|
5432
|
-
const sessionId = `persist:browserView`;
|
|
5433
|
-
const session = Electron.session.fromPartition(sessionId, {
|
|
5434
|
-
cache: true
|
|
5435
|
-
});
|
|
5436
|
-
session.setPermissionRequestHandler(handlePermissionRequest);
|
|
5437
|
-
session.setPermissionCheckHandler(handlePermissionCheck);
|
|
5438
|
-
session.webRequest.onBeforeRequest(filter, handleBeforeRequest);
|
|
5439
|
-
// session.webRequest.addSessionChromeExtensions(session)
|
|
5440
|
-
return session;
|
|
5441
|
-
};
|
|
5442
|
-
const getSession = () => {
|
|
5443
|
-
state.session ||= createSession();
|
|
5444
|
-
return state.session;
|
|
5445
|
-
};
|
|
5446
|
-
|
|
5447
|
-
const assertLinux = () => {
|
|
5448
|
-
if (process.platform !== 'linux') {
|
|
5449
|
-
throw new Error('Importing Chrome cookies is only supported on Linux');
|
|
5450
|
-
}
|
|
5451
|
-
};
|
|
5452
|
-
const getInfoFromDirectory$1 = chromeDataDirectory => {
|
|
5453
|
-
const profile = getActiveProfile$1(chromeDataDirectory);
|
|
5454
|
-
const cookieCount = getCookieCount$1(profile.cookieDatabasePath);
|
|
5455
|
-
return {
|
|
5456
|
-
cookieCount,
|
|
5457
|
-
profileDirectory: profile.directory,
|
|
5458
|
-
profileName: profile.name
|
|
5459
|
-
};
|
|
5460
|
-
};
|
|
5461
|
-
const getInfo$1 = () => {
|
|
5462
|
-
assertLinux();
|
|
5463
|
-
return getInfoFromDirectory$1(getChromeDataDirectory());
|
|
5464
|
-
};
|
|
5465
|
-
const importFromDirectory$1 = async (chromeDataDirectory, session) => {
|
|
5466
|
-
const profile = getActiveProfile$1(chromeDataDirectory);
|
|
5467
|
-
const {
|
|
5468
|
-
rows,
|
|
5469
|
-
version
|
|
5470
|
-
} = readCookies$1(profile.cookieDatabasePath);
|
|
5471
|
-
const requiresChromeSafeStoragePassword = rows.some(row => !row.value && isV11(row.encryptedValue));
|
|
5472
|
-
const chromeSafeStoragePassword = requiresChromeSafeStoragePassword ? await getChromeSafeStoragePassword() : undefined;
|
|
5473
|
-
const cookies = [];
|
|
5474
|
-
let skipped = 0;
|
|
5475
|
-
let unsupportedEncryption = 0;
|
|
5476
|
-
for (const row of rows) {
|
|
5477
|
-
try {
|
|
5478
|
-
const cookie = convert$1(row, version, chromeSafeStoragePassword);
|
|
5479
|
-
if (cookie) {
|
|
5480
|
-
cookies.push(cookie);
|
|
5481
|
-
} else {
|
|
5482
|
-
skipped++;
|
|
5483
|
-
}
|
|
5484
|
-
} catch (error) {
|
|
5485
|
-
skipped++;
|
|
5486
|
-
if (error instanceof UnsupportedChromeCookieEncryptionError) {
|
|
5487
|
-
unsupportedEncryption++;
|
|
5488
|
-
}
|
|
5489
|
-
}
|
|
5490
|
-
}
|
|
5491
|
-
if (cookies.length === 0 && unsupportedEncryption > 0) {
|
|
5492
|
-
throw new Error('Unsupported Chrome cookie encryption format');
|
|
5493
|
-
}
|
|
5494
|
-
let imported = 0;
|
|
5495
|
-
let failed = 0;
|
|
5496
|
-
for (const cookie of cookies) {
|
|
5497
|
-
try {
|
|
5498
|
-
await session.cookies.set(cookie);
|
|
5499
|
-
imported++;
|
|
5500
|
-
} catch {
|
|
5501
|
-
failed++;
|
|
5502
|
-
}
|
|
5503
|
-
}
|
|
5504
|
-
await session.cookies.flushStore();
|
|
5505
|
-
return {
|
|
5506
|
-
failed,
|
|
5507
|
-
imported,
|
|
5508
|
-
skipped
|
|
5509
|
-
};
|
|
5510
|
-
};
|
|
5511
|
-
const importCookies$1 = async () => {
|
|
5512
|
-
assertLinux();
|
|
5513
|
-
return importFromDirectory$1(getChromeDataDirectory(), getSession());
|
|
5514
|
-
};
|
|
5515
|
-
|
|
5516
5040
|
const handleTimeout = () => {
|
|
5517
5041
|
throw new Error('oops');
|
|
5518
5042
|
};
|
|
@@ -6956,6 +6480,136 @@ const ElectronBrowserViewEventListeners = {
|
|
|
6956
6480
|
windowOpen: ElectronBrowserViewEventListenerWindowOpen
|
|
6957
6481
|
};
|
|
6958
6482
|
|
|
6483
|
+
const MainFrame = 'mainFrame';
|
|
6484
|
+
const Script = 'script';
|
|
6485
|
+
const Xhr = 'xhr';
|
|
6486
|
+
|
|
6487
|
+
const Get = 'GET';
|
|
6488
|
+
const Head = 'HEAD';
|
|
6489
|
+
const Options = 'OPTIONS';
|
|
6490
|
+
const Post = 'POST';
|
|
6491
|
+
|
|
6492
|
+
// @ts-ignore
|
|
6493
|
+
|
|
6494
|
+
const getBeforeRequestResponseMainFrame = (method, url) => {
|
|
6495
|
+
return {};
|
|
6496
|
+
};
|
|
6497
|
+
const cancelIfStartsWith = (url, canceledUrls) => {
|
|
6498
|
+
for (const canceledUrl of canceledUrls) {
|
|
6499
|
+
if (url.startsWith(canceledUrl)) {
|
|
6500
|
+
return {
|
|
6501
|
+
cancel: true
|
|
6502
|
+
};
|
|
6503
|
+
}
|
|
6504
|
+
}
|
|
6505
|
+
return {};
|
|
6506
|
+
};
|
|
6507
|
+
const getBeforeRequestResponseXhrPost = url => {
|
|
6508
|
+
const canceledUrls = ['https://www.youtube.com/api/stats/qoe', 'https://www.youtube.com/youtubei/v1/log_event', 'https://play.google.com/log'];
|
|
6509
|
+
return cancelIfStartsWith(url, canceledUrls);
|
|
6510
|
+
};
|
|
6511
|
+
const getBeforeRequestResponseXhrGet = url => {
|
|
6512
|
+
const canceledUrls = ['https://www.youtube.com/pagead/', 'https://www.youtube.com/api/stats/qoe', 'https://www.youtube.com/api/stats/ads', 'https://www.youtube.com/api/stats/delayplay', 'https://www.youtube.com/ptracking', 'https://www.youtube.com/api/timedtext', 'https://www.youtube.com/pcs/activeview', 'https://googleads.g.doubleclick.net/pagead/id'];
|
|
6513
|
+
return cancelIfStartsWith(url, canceledUrls);
|
|
6514
|
+
};
|
|
6515
|
+
const getBeforeRequestResponseXhrOptions = url => {
|
|
6516
|
+
const canceledUrls = ['https://play.google.com/log'];
|
|
6517
|
+
return cancelIfStartsWith(url, canceledUrls);
|
|
6518
|
+
};
|
|
6519
|
+
const getBeforeRequestResponseXhrHead = url => {
|
|
6520
|
+
const canceledUrls = ['https://www.youtube.com/generate_204'];
|
|
6521
|
+
return cancelIfStartsWith(url, canceledUrls);
|
|
6522
|
+
};
|
|
6523
|
+
const getBeforeRequestResponseXhr = (method, url) => {
|
|
6524
|
+
switch (method) {
|
|
6525
|
+
case Get:
|
|
6526
|
+
return getBeforeRequestResponseXhrGet(url);
|
|
6527
|
+
case Head:
|
|
6528
|
+
return getBeforeRequestResponseXhrHead(url);
|
|
6529
|
+
case Options:
|
|
6530
|
+
return getBeforeRequestResponseXhrOptions(url);
|
|
6531
|
+
case Post:
|
|
6532
|
+
return getBeforeRequestResponseXhrPost(url);
|
|
6533
|
+
default:
|
|
6534
|
+
return {};
|
|
6535
|
+
}
|
|
6536
|
+
};
|
|
6537
|
+
const getBeforeRequestResponseDefault = (method, url) => {
|
|
6538
|
+
return {};
|
|
6539
|
+
};
|
|
6540
|
+
const getBeforeRequestResponseScript = (method, url) => {
|
|
6541
|
+
const canceledUrls = ['https://static.doubleclick.net'];
|
|
6542
|
+
return cancelIfStartsWith(url, canceledUrls);
|
|
6543
|
+
};
|
|
6544
|
+
const getBeforeRequestResponse = details => {
|
|
6545
|
+
const {
|
|
6546
|
+
method,
|
|
6547
|
+
resourceType,
|
|
6548
|
+
url
|
|
6549
|
+
} = details;
|
|
6550
|
+
switch (resourceType) {
|
|
6551
|
+
case MainFrame:
|
|
6552
|
+
return getBeforeRequestResponseMainFrame();
|
|
6553
|
+
case Script:
|
|
6554
|
+
return getBeforeRequestResponseScript(method, url);
|
|
6555
|
+
case Xhr:
|
|
6556
|
+
return getBeforeRequestResponseXhr(method, url);
|
|
6557
|
+
default:
|
|
6558
|
+
return getBeforeRequestResponseDefault();
|
|
6559
|
+
}
|
|
6560
|
+
};
|
|
6561
|
+
|
|
6562
|
+
/**
|
|
6563
|
+
*
|
|
6564
|
+
* @param {Electron.OnBeforeRequestListenerDetails } details
|
|
6565
|
+
* @param {(response: globalThis.Electron.CallbackResponse) => void} callback
|
|
6566
|
+
*/
|
|
6567
|
+
const handleBeforeRequest = (details, callback) => {
|
|
6568
|
+
const response = getBeforeRequestResponse(details);
|
|
6569
|
+
callback(response);
|
|
6570
|
+
};
|
|
6571
|
+
const filter = {
|
|
6572
|
+
// urls: ['https://*.youtube.com/*'],
|
|
6573
|
+
urls: ['<all_urls>']
|
|
6574
|
+
};
|
|
6575
|
+
|
|
6576
|
+
const state = {
|
|
6577
|
+
session: undefined
|
|
6578
|
+
};
|
|
6579
|
+
const isAllowedPermission = permission => {
|
|
6580
|
+
switch (permission) {
|
|
6581
|
+
case ClipBoardRead:
|
|
6582
|
+
case ClipBoardSanitizedWrite:
|
|
6583
|
+
case FullScreen:
|
|
6584
|
+
case GeoLocation:
|
|
6585
|
+
case WindowPlacement:
|
|
6586
|
+
return true;
|
|
6587
|
+
default:
|
|
6588
|
+
return false;
|
|
6589
|
+
}
|
|
6590
|
+
};
|
|
6591
|
+
const handlePermissionRequest = (webContents, permission, callback, details) => {
|
|
6592
|
+
callback(isAllowedPermission(permission));
|
|
6593
|
+
};
|
|
6594
|
+
const handlePermissionCheck = (webContents, permission, origin, details) => {
|
|
6595
|
+
return isAllowedPermission(permission);
|
|
6596
|
+
};
|
|
6597
|
+
const createSession = () => {
|
|
6598
|
+
const sessionId = `persist:browserView`;
|
|
6599
|
+
const session = Electron.session.fromPartition(sessionId, {
|
|
6600
|
+
cache: true
|
|
6601
|
+
});
|
|
6602
|
+
session.setPermissionRequestHandler(handlePermissionRequest);
|
|
6603
|
+
session.setPermissionCheckHandler(handlePermissionCheck);
|
|
6604
|
+
session.webRequest.onBeforeRequest(filter, handleBeforeRequest);
|
|
6605
|
+
// session.webRequest.addSessionChromeExtensions(session)
|
|
6606
|
+
return session;
|
|
6607
|
+
};
|
|
6608
|
+
const getSession = () => {
|
|
6609
|
+
state.session ||= createSession();
|
|
6610
|
+
return state.session;
|
|
6611
|
+
};
|
|
6612
|
+
|
|
6959
6613
|
const attach = (webContents, parentWebContents) => {
|
|
6960
6614
|
let shouldRestoreParentFocus = false;
|
|
6961
6615
|
webContents.on(DidStartNavigation, (_event, _url, _isInPlace, isMainFrame) => {
|
|
@@ -7823,8 +7477,6 @@ const trash = async path => {
|
|
|
7823
7477
|
const commandMap = {
|
|
7824
7478
|
'AppWindow.createAppWindow': createAppWindow,
|
|
7825
7479
|
'Beep.beep': beep$1,
|
|
7826
|
-
'ChromeCookieImport.getInfo': getInfo$1,
|
|
7827
|
-
'ChromeCookieImport.importCookies': importCookies$1,
|
|
7828
7480
|
'Crash.crashMainProcess': crashMainProcess$1,
|
|
7829
7481
|
'CreateMessagePort.createMessagePort': createMessagePort,
|
|
7830
7482
|
'CreatePidMap.createPidMap': createPidMap,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/main-process",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.29.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"lvce-editor",
|
|
6
6
|
"electron"
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
"type": "module",
|
|
15
15
|
"main": "dist/mainProcessMain.js",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
-
"electron": "43.4.0"
|
|
17
|
+
"electron": "43.4.1"
|
|
19
18
|
},
|
|
20
19
|
"engines": {
|
|
21
20
|
"node": ">=22"
|