@evomap/evolver-adapter-public 2.0.0-beta.2 → 2.0.0-beta.22

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.
@@ -99,6 +99,7 @@ export function collectIntegrityHashes(packageRoot = resolveAdapterPackageRoot()
99
99
  export function buildHeartbeatAntiAbuseTelemetry(opts = {}) {
100
100
  const env = opts.env ?? process.env;
101
101
  const fp = opts.envFingerprint ?? bootstrap.captureEnvFingerprint({ env });
102
+ const evolverVersion = bootstrap.normalizeEvolverVersion(Object.hasOwn(opts, 'evolverVersion') ? opts.evolverVersion : fp.evolver_version);
102
103
  const salt = opts.salt ?? env['EVOLVER_ANTI_ABUSE_SALT'];
103
104
  const saltId = opts.saltId ?? env['EVOLVER_ANTI_ABUSE_SALT_ID'] ?? (salt ? 'env' : null);
104
105
  const pseudonymStatus = salt ? 'salt_configured' : 'salt_missing';
@@ -159,7 +160,7 @@ export function buildHeartbeatAntiAbuseTelemetry(opts = {}) {
159
160
  // AUTHORITATIVE per-asset model lives on the capsule (threaded from input.model), so 'unknown' on a heartbeat
160
161
  // is "this node didn't say", never a contradiction of a capsule's real model.
161
162
  model: fp.model,
162
- evolver_version: opts.evolverVersion ?? null,
163
+ evolver_version: evolverVersion ?? null,
163
164
  client: '@evomap/evolver-adapter-public',
164
165
  client_version: null,
165
166
  region: fp.region ?? null,
@@ -1,8 +1,95 @@
1
+ import { linkSync, renameSync } from 'node:fs';
1
2
  import type { hub } from '@evomap/evolver-core';
2
- /** 凭证持久化(~/.evomap, 0600). token/keypair 私钥都经此, 文件权限收紧. */
3
+ export interface CredentialStoreOptions {
4
+ /**
5
+ * Test seam for the Windows policy; defaults to the current platform.
6
+ * Windows enforces entry types, identity checks, exclusive random temporary
7
+ * files and atomic replacement. POSIX additionally enforces owner and mode.
8
+ */
9
+ platform?: NodeJS.Platform;
10
+ /** Injectable so the Windows DACL policy can be verified on any platform. */
11
+ windowsAclOps?: WindowsCredentialAclOps;
12
+ /** Injectable so Darwin ancestor ACL caching can be tested without process mocks. */
13
+ darwinAclReader?: (path: string) => string;
14
+ /** Injectable so Windows parent ACL cache invalidation can be tested deterministically. */
15
+ windowsParentStateReader?: (path: string) => readonly PathSecurityState[];
16
+ /** Injectable filesystem primitive for deterministic no-clobber publication tests. */
17
+ linkFile?: typeof linkSync;
18
+ /** Injectable filesystem primitive for deterministic atomic replacement tests. */
19
+ renameFile?: typeof renameSync;
20
+ }
21
+ export interface WindowsCredentialAclOps {
22
+ assertTrustedParent(path: string, strictCreate: boolean): void;
23
+ /** Fail-closed file DACL check before any Set-Acl and before trusting content. */
24
+ assertTrustedFile(path: string): void;
25
+ secureDirectory(path: string): void;
26
+ secureFile(path: string): void;
27
+ }
28
+ export declare class CredentialStoreError extends Error {
29
+ constructor(message: string, options?: ErrorOptions);
30
+ }
31
+ interface FileIdentity {
32
+ dev: bigint;
33
+ ino: bigint;
34
+ }
35
+ interface FileSecurityState extends FileIdentity {
36
+ ctimeNs: bigint;
37
+ }
38
+ interface PathSecurityState extends FileSecurityState {
39
+ path: string;
40
+ }
41
+ /** Persists OAuth tokens and keypair private keys behind a local secret-file boundary. */
3
42
  export declare class CredentialStore {
4
43
  private readonly path;
5
- constructor(path: string);
44
+ private readonly platform;
45
+ private readonly windowsAclOps;
46
+ private readonly darwinAclReader;
47
+ private readonly windowsParentStateReader;
48
+ private readonly linkFile;
49
+ private readonly renameFile;
50
+ private securedDirectoryState;
51
+ private securedCredentialState;
52
+ private readonly securedAncestorStates;
53
+ private readonly trustedWindowsParentStates;
54
+ constructor(path: string, options?: CredentialStoreOptions);
6
55
  load(): hub.Credential | null;
56
+ /** Validate an existing credential path without changing its mode, DACL, ACL, or contents. */
57
+ inspectTrustedExisting(): {
58
+ dev: bigint;
59
+ ino: bigint;
60
+ birthtimeNs: bigint;
61
+ ctimeNs: bigint;
62
+ mtimeNs: bigint;
63
+ size: bigint;
64
+ mode: bigint;
65
+ uid: bigint;
66
+ } | null;
67
+ /** Validate the existing parent chain for a future create without creating or hardening it. */
68
+ inspectTrustedParentForCreate(): void;
7
69
  save(cred: hub.Credential): void;
8
- }
70
+ /** Persist a credential only when no filesystem entry already occupies its path. */
71
+ saveIfAbsent(cred: hub.Credential): boolean;
72
+ private saveCredential;
73
+ private prepareDirectory;
74
+ private missingDirectoryComponents;
75
+ private createDirectoryComponent;
76
+ private openCredentialFile;
77
+ private secureCredentialFd;
78
+ private assertCredentialFdTrustedReadOnly;
79
+ private assertSafeDestination;
80
+ private verifySavedFile;
81
+ private directoryIdentity;
82
+ private assertDirectoryIdentity;
83
+ private exclusiveWriteFlags;
84
+ private publishIfAbsent;
85
+ private syncDirectory;
86
+ private unlinkIfSameFile;
87
+ private secureWindowsDirectory;
88
+ private secureWindowsFile;
89
+ private clearDarwinAcl;
90
+ private assertSafeDarwinAncestor;
91
+ private assertTrustedDarwinFile;
92
+ private assertTrustedWindowsParent;
93
+ private isPosix;
94
+ }
95
+ export {};