@indigoai-us/hq-cloud 6.14.45 → 6.14.47

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.
@@ -5785,6 +5785,71 @@ describe("scope-invalid key hardening on push (doubled companies/ tree — incid
5785
5785
  ]);
5786
5786
  expect(events.some((e) => e.type === "error")).toBe(false);
5787
5787
  });
5788
+ it("never plans an upload for macOS Finder Icon\\r files — silent skip, valid files still ship", async () => {
5789
+ // The incident: Finder writes an `Icon\r` file into every directory it
5790
+ // renders a custom icon for, and a folder-level cloud-sync agent spreads
5791
+ // them tree-wide. A CR is a control character, so validateVaultUploadKey
5792
+ // throws INVALID_KEY_CONTROL_CHARS inside executeUploads; that throw lands
5793
+ // in the generic catch and emits type:"error". errors[] non-empty makes
5794
+ // the runner return PARTIAL_SYNC_EXIT, so ONE such file marks EVERY sync
5795
+ // pass failed forever. On the reporting machine there were 100+ per run.
5796
+ //
5797
+ // They are excluded during the walk, like .DS_Store, so they never reach
5798
+ // the planner at all — and, being expected noise, without a per-file
5799
+ // "EXCLUDED from sync" warning.
5800
+ const companyRoot = path.join(tmpDir, "companies", "acme");
5801
+ fs.mkdirSync(path.join(companyRoot, "docs"), { recursive: true });
5802
+ fs.writeFileSync(path.join(companyRoot, "docs", "good.md"), "good");
5803
+ fs.writeFileSync(path.join(companyRoot, "Icon\r"), "finder cruft");
5804
+ fs.writeFileSync(path.join(companyRoot, "docs", "Icon\r"), "finder cruft");
5805
+ const events = [];
5806
+ const result = await share({
5807
+ paths: [companyRoot],
5808
+ company: "acme",
5809
+ vaultConfig: mockConfig,
5810
+ hqRoot: tmpDir,
5811
+ onEvent: (e) => events.push(e),
5812
+ });
5813
+ expect(result.aborted).toBe(false);
5814
+ const uploadedKeys = vi.mocked(uploadFile).mock.calls.map((c) => c[2]);
5815
+ expect(uploadedKeys).toEqual(["docs/good.md"]);
5816
+ expect(result.filesUploaded).toBe(1);
5817
+ // The failure class this guards: an error event is what flips the runner
5818
+ // pass to exit 2.
5819
+ expect(events.some((e) => e.type === "error")).toBe(false);
5820
+ // Expected OS noise — excluded without the "review in case this is
5821
+ // unintended" warning that real content would earn.
5822
+ expect(events.some((e) => e.type === "ignore-excluded")).toBe(false);
5823
+ });
5824
+ it("refuses any other control-character key up front — skip event, never an error", async () => {
5825
+ // Belt-and-suspenders for control-char paths that are not the Finder icon
5826
+ // spelling, and for callers that bypass the walker. Symmetric with the
5827
+ // pull leg, which has classified such keys since the same incident.
5828
+ const companyRoot = path.join(tmpDir, "companies", "acme");
5829
+ fs.mkdirSync(path.join(companyRoot, "docs"), { recursive: true });
5830
+ fs.writeFileSync(path.join(companyRoot, "docs", "good.md"), "good");
5831
+ fs.writeFileSync(path.join(companyRoot, "docs", "bad\u0001name.md"), "bad");
5832
+ const events = [];
5833
+ const result = await share({
5834
+ paths: [companyRoot],
5835
+ company: "acme",
5836
+ vaultConfig: mockConfig,
5837
+ hqRoot: tmpDir,
5838
+ onEvent: (e) => events.push(e),
5839
+ });
5840
+ expect(result.aborted).toBe(false);
5841
+ const uploadedKeys = vi.mocked(uploadFile).mock.calls.map((c) => c[2]);
5842
+ expect(uploadedKeys).toEqual(["docs/good.md"]);
5843
+ const skipEvents = events.filter((e) => e.type === "skip-invalid-scoped-key");
5844
+ expect(skipEvents).toEqual([
5845
+ {
5846
+ type: "skip-invalid-scoped-key",
5847
+ path: "docs/bad\u0001name.md",
5848
+ errorCode: "INVALID_KEY_CONTROL_CHARS",
5849
+ },
5850
+ ]);
5851
+ expect(events.some((e) => e.type === "error")).toBe(false);
5852
+ });
5788
5853
  it("tombstones (journal drop, no remote HEAD/DELETE) a companies/ journal key in company mode instead of re-uploading", async () => {
5789
5854
  // Delete-propagation on a poisoned journal entry: HEAD/DeleteObject on a
5790
5855
  // companies/-prefixed key would be rejected by the presign transport's