@lvce-editor/main-process 6.19.1 → 6.19.2

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.
@@ -11,6 +11,7 @@ import { dirname, join as join$1, isAbsolute } from 'node:path';
11
11
  import { homedir, tmpdir } from 'node:os';
12
12
  import { pbkdf2Sync, createDecipheriv, createHash } from 'node:crypto';
13
13
  import { DatabaseSync } from 'node:sqlite';
14
+ import dbus, { Variant } from 'dbus-native';
14
15
  import { MessageChannel } from 'node:worker_threads';
15
16
 
16
17
  const scheme = 'lvce-oss';
@@ -4613,6 +4614,7 @@ const beep$1 = () => {
4613
4614
  };
4614
4615
 
4615
4616
  const chromeV10Prefix = Buffer.from('v10');
4617
+ const chromeV11Prefix = Buffer.from('v11');
4616
4618
  const chromeV10Key = pbkdf2Sync('peanuts', 'saltysalt', 1, 16, 'sha1');
4617
4619
  const chromeV10Iv = Buffer.alloc(16, 0x20);
4618
4620
  const domainHashLength = 32;
@@ -4622,13 +4624,25 @@ class UnsupportedChromeCookieEncryptionError extends Error {
4622
4624
  this.name = 'UnsupportedChromeCookieEncryptionError';
4623
4625
  }
4624
4626
  }
4625
- const decrypt$1 = (hostKey, encryptedValue, databaseVersion) => {
4627
+ const isV11 = encryptedValue => {
4628
+ return Buffer.from(encryptedValue).subarray(0, chromeV11Prefix.length).equals(chromeV11Prefix);
4629
+ };
4630
+ const decrypt$1 = (hostKey, encryptedValue, databaseVersion, chromeSafeStoragePassword) => {
4626
4631
  const buffer = Buffer.from(encryptedValue);
4627
- if (buffer.length <= chromeV10Prefix.length || !buffer.subarray(0, chromeV10Prefix.length).equals(chromeV10Prefix)) {
4632
+ if (buffer.length <= chromeV10Prefix.length) {
4633
+ throw new UnsupportedChromeCookieEncryptionError();
4634
+ }
4635
+ const prefix = buffer.subarray(0, chromeV10Prefix.length);
4636
+ let key;
4637
+ if (prefix.equals(chromeV10Prefix)) {
4638
+ key = chromeV10Key;
4639
+ } else if (prefix.equals(chromeV11Prefix) && chromeSafeStoragePassword !== undefined) {
4640
+ key = pbkdf2Sync(chromeSafeStoragePassword, 'saltysalt', 1, 16, 'sha1');
4641
+ } else {
4628
4642
  throw new UnsupportedChromeCookieEncryptionError();
4629
4643
  }
4630
- const decipher = createDecipheriv('aes-128-cbc', chromeV10Key, chromeV10Iv);
4631
- const plaintext = Buffer.concat([decipher.update(buffer.subarray(chromeV10Prefix.length)), decipher.final()]);
4644
+ const decipher = createDecipheriv('aes-128-cbc', key, chromeV10Iv);
4645
+ const plaintext = Buffer.concat([decipher.update(buffer.subarray(prefix.length)), decipher.final()]);
4632
4646
  if (databaseVersion < 24) {
4633
4647
  return plaintext.toString('utf8');
4634
4648
  }
@@ -4661,13 +4675,13 @@ const getExpirationDate = expiresUtc => {
4661
4675
  const chromeMicroseconds = BigInt(expiresUtc);
4662
4676
  return Number(chromeMicroseconds - chromeEpochOffsetMicroseconds) / Number(microsecondsPerSecond);
4663
4677
  };
4664
- const getValue = (row, databaseVersion) => {
4678
+ const getValue = (row, databaseVersion, chromeSafeStoragePassword) => {
4665
4679
  if (row.value) {
4666
4680
  return row.value;
4667
4681
  }
4668
- return decrypt$1(row.hostKey, row.encryptedValue, databaseVersion);
4682
+ return decrypt$1(row.hostKey, row.encryptedValue, databaseVersion, chromeSafeStoragePassword);
4669
4683
  };
4670
- const convert$1 = (row, databaseVersion, now = Date.now() / 1000) => {
4684
+ const convert$1 = (row, databaseVersion, chromeSafeStoragePassword, now = Date.now() / 1000) => {
4671
4685
  if (!row.hostKey || row.topFrameSiteKey) {
4672
4686
  return undefined;
4673
4687
  }
@@ -4683,7 +4697,7 @@ const convert$1 = (row, databaseVersion, now = Date.now() / 1000) => {
4683
4697
  sameSite: getSameSite$1(row.sameSite),
4684
4698
  secure,
4685
4699
  url: `${secure ? 'https' : 'http'}://${host}/`,
4686
- value: getValue(row, databaseVersion)
4700
+ value: getValue(row, databaseVersion, chromeSafeStoragePassword)
4687
4701
  };
4688
4702
  if (row.hostKey.startsWith('.')) {
4689
4703
  details.domain = row.hostKey;
@@ -4763,6 +4777,79 @@ const readCookies$1 = path => {
4763
4777
  });
4764
4778
  };
4765
4779
 
4780
+ const secretServiceName = 'org.freedesktop.secrets';
4781
+ const secretServicePath = '/org/freedesktop/secrets';
4782
+ const secretServiceInterface = 'org.freedesktop.Secret.Service';
4783
+ const secretCollectionInterface = 'org.freedesktop.Secret.Collection';
4784
+ const secretItemInterface = 'org.freedesktop.Secret.Item';
4785
+ const propertiesInterface = 'org.freedesktop.DBus.Properties';
4786
+ const defaultCollectionPath = '/org/freedesktop/secrets/aliases/default';
4787
+ const chromeSafeStorageLabel = 'Chrome Safe Storage';
4788
+ const getProperties = async (bus, path) => {
4789
+ return bus.getService(secretServiceName).getInterface(path, propertiesInterface);
4790
+ };
4791
+ const findChromeSafeStorageItem = async (bus, service) => {
4792
+ const [unlocked, locked] = await service.SearchItems({
4793
+ application: 'chrome'
4794
+ });
4795
+ const matchingItems = [...unlocked, ...locked];
4796
+ if (matchingItems.length > 0) {
4797
+ return matchingItems[0];
4798
+ }
4799
+ const collectionProperties = await getProperties(bus, defaultCollectionPath);
4800
+ const items = await collectionProperties.Get(secretCollectionInterface, 'Items');
4801
+ for (const item of items) {
4802
+ const itemProperties = await getProperties(bus, item);
4803
+ const label = await itemProperties.Get(secretItemInterface, 'Label');
4804
+ if (label === chromeSafeStorageLabel) {
4805
+ return item;
4806
+ }
4807
+ }
4808
+ throw new Error('Chrome Safe Storage password was not found in the Linux keyring');
4809
+ };
4810
+ const unlockItem = async (service, item) => {
4811
+ const [unlocked, prompt] = await service.Unlock([item]);
4812
+ if (unlocked.includes(item)) {
4813
+ return;
4814
+ }
4815
+ if (prompt !== '/') {
4816
+ throw new Error('Chrome Safe Storage is locked; unlock the desktop keyring and try again');
4817
+ }
4818
+ throw new Error('Chrome Safe Storage could not be unlocked');
4819
+ };
4820
+ const readPassword = async bus => {
4821
+ const service = await bus.getService(secretServiceName).getInterface(secretServicePath, secretServiceInterface);
4822
+ const [, sessionPath] = await service.OpenSession('plain', new Variant('s', ''));
4823
+ const item = await findChromeSafeStorageItem(bus, service);
4824
+ let secrets;
4825
+ try {
4826
+ secrets = await service.GetSecrets([item], sessionPath);
4827
+ } catch {
4828
+ await unlockItem(service, item);
4829
+ secrets = await service.GetSecrets([item], sessionPath);
4830
+ }
4831
+ const secret = secrets[item];
4832
+ if (!secret) {
4833
+ throw new Error('Chrome Safe Storage password was not returned by the Linux keyring');
4834
+ }
4835
+ return Buffer.from(secret[2]).toString('utf8');
4836
+ };
4837
+ const getErrorMessage = error => {
4838
+ return error instanceof Error ? error.message : String(error);
4839
+ };
4840
+ const getChromeSafeStoragePassword = async () => {
4841
+ const bus = dbus.sessionBus({
4842
+ timeout: 5000
4843
+ });
4844
+ try {
4845
+ return await readPassword(bus);
4846
+ } catch (error) {
4847
+ throw new Error(`Failed to read Chrome Safe Storage password: ${getErrorMessage(error)}`);
4848
+ } finally {
4849
+ await bus.close();
4850
+ }
4851
+ };
4852
+
4766
4853
  const isValidProfileDirectory = value => {
4767
4854
  return value !== '' && value !== '.' && value !== '..' && !value.includes('/') && !value.includes('\\');
4768
4855
  };
@@ -4972,12 +5059,14 @@ const importFromDirectory$1 = async (chromeDataDirectory, session) => {
4972
5059
  rows,
4973
5060
  version
4974
5061
  } = readCookies$1(profile.cookieDatabasePath);
5062
+ const requiresChromeSafeStoragePassword = rows.some(row => !row.value && isV11(row.encryptedValue));
5063
+ const chromeSafeStoragePassword = requiresChromeSafeStoragePassword ? await getChromeSafeStoragePassword() : undefined;
4975
5064
  const cookies = [];
4976
5065
  let skipped = 0;
4977
5066
  let unsupportedEncryption = 0;
4978
5067
  for (const row of rows) {
4979
5068
  try {
4980
- const cookie = convert$1(row, version);
5069
+ const cookie = convert$1(row, version, chromeSafeStoragePassword);
4981
5070
  if (cookie) {
4982
5071
  cookies.push(cookie);
4983
5072
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-process",
3
- "version": "6.19.1",
3
+ "version": "6.19.2",
4
4
  "keywords": [
5
5
  "lvce-editor",
6
6
  "electron"
@@ -14,6 +14,7 @@
14
14
  "type": "module",
15
15
  "main": "dist/mainProcessMain.js",
16
16
  "dependencies": {
17
+ "dbus-native": "^0.15.1",
17
18
  "electron": "43.2.0"
18
19
  },
19
20
  "engines": {