my-provider-dash-manager 0.13.0 → 0.13.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/main.js +15 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-provider-dash-manager",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "CLI to install and update My Provider Dash Manager: a free Windows desktop app that keeps many accounts per service (Vercel, Netlify, Supabase, Cloudflare, AWS, Google, Microsoft, GitHub, Gmail) signed in at once, each in a fully isolated session. Also available as mpdm.",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
package/src/main.js CHANGED
@@ -1637,7 +1637,8 @@ async function runSmokeCreds() {
1637
1637
  // (4) an UNREADABLE v1 store: the broken case the owner hit. Simulated with a wrong-key v1 blob
1638
1638
  // (a real safeStorage ciphertext from another key cannot be produced honestly here). The file must
1639
1639
  // be left byte-identical, the app must show ONE honest notice, and an import must still work and
1640
- // switch the store to v2 (with the old bytes preserved under their own name).
1640
+ // switch the store to v2 (0.13.1: no copy of the old bytes is made anywhere — a second
1641
+ // secret-bearing file next to the key would only hand backup/support tools another grab).
1641
1642
  {
1642
1643
  const wrongKeyBlob = crypto.randomBytes(96).toString('base64'); // not a DPAPI blob at all
1643
1644
  const v1Unreadable = JSON.stringify({ ct: wrongKeyBlob, count: 7, savedAt: '2026-01-04T00:00:00.000Z' }, null, 2);
@@ -1656,11 +1657,21 @@ async function runSmokeCreds() {
1656
1657
  fs.writeFileSync(csvRe, 'url,username,password\nhttps://vercel.com/login,reimport@example.com,reimport-pw\n');
1657
1658
  try { creds.importFromCsv(csvRe); } finally { try { fs.rmSync(csvRe, { force: true }); } catch {} }
1658
1659
  const afterReimport = creds.storeState();
1660
+ const backupAbsent = !fs.existsSync(path.join(app.getPath('userData'), 'credentials.v1-unreadable.json'));
1659
1661
  check('store-v1-unreadable-clears-after-a-reimport',
1660
1662
  afterReimport.legacyUnreadable === false && afterReimport.notice === null
1661
- && creds.stats().total === 1 && readStore().v === 2
1662
- && fs.existsSync(path.join(app.getPath('userData'), 'credentials.v1-unreadable.json')),
1663
- `notice=${afterReimport.notice} rows=${creds.stats().total} format=v${readStore().v} backup=${fs.existsSync(path.join(app.getPath('userData'), 'credentials.v1-unreadable.json'))}`);
1663
+ && creds.stats().total === 1 && readStore().v === 2 && backupAbsent,
1664
+ `notice=${afterReimport.notice} rows=${creds.stats().total} format=v${readStore().v} no-backup-file=${backupAbsent}`);
1665
+ // 0.13.1: a file that EXISTS but does not parse is damage, not "no store yet" — it is
1666
+ // reported (MALFORMED), never silently treated as an empty list.
1667
+ {
1668
+ fs.writeFileSync(storeFile, '{ truncated');
1669
+ const malformed = creds.storeState();
1670
+ check('store-v2-malformed-file-reported',
1671
+ malformed.error && malformed.error.code === 'MALFORMED' && creds.stats().total === 0,
1672
+ `error=${malformed.error && malformed.error.code} rows=${creds.stats().total}`);
1673
+ fs.rmSync(storeFile, { force: true });
1674
+ }
1664
1675
  }
1665
1676
 
1666
1677
  // (5) THE regression proof: two REAL launches on ONE scratch profile. Launch A seeds a login and
@@ -1669,7 +1680,6 @@ async function runSmokeCreds() {
1669
1680
  {
1670
1681
  fs.rmSync(keyFile, { force: true });
1671
1682
  fs.rmSync(storeFile, { force: true });
1672
- fs.rmSync(path.join(app.getPath('userData'), 'credentials.v1-unreadable.json'), { force: true });
1673
1683
  fs.rmSync(path.join(app.getPath('userData'), 'cross-process-seed.json'), { force: true });
1674
1684
  fs.rmSync(path.join(app.getPath('userData'), 'cross-process-read.json'), { force: true });
1675
1685
  const run = args => new Promise(resolve => {