@lvce-editor/main-process 6.19.1 → 6.19.3

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