instar 1.3.1597 → 1.3.1599

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 (96) hide show
  1. package/dashboard/desktop.css +8 -0
  2. package/dashboard/desktop.html +10 -0
  3. package/dashboard/desktop.js +98 -1
  4. package/dist/core/DesktopAccessAudit.d.ts +3 -1
  5. package/dist/core/DesktopAccessAudit.d.ts.map +1 -1
  6. package/dist/core/DesktopAccessAudit.js +1 -0
  7. package/dist/core/DesktopAccessAudit.js.map +1 -1
  8. package/dist/core/DesktopAead.d.ts +8 -1
  9. package/dist/core/DesktopAead.d.ts.map +1 -1
  10. package/dist/core/DesktopAead.js +18 -1
  11. package/dist/core/DesktopAead.js.map +1 -1
  12. package/dist/core/DesktopHelperRetention.d.ts +5 -1
  13. package/dist/core/DesktopHelperRetention.d.ts.map +1 -1
  14. package/dist/core/DesktopHelperRetention.js.map +1 -1
  15. package/dist/core/DesktopHost.d.ts +26 -1
  16. package/dist/core/DesktopHost.d.ts.map +1 -1
  17. package/dist/core/DesktopHost.js.map +1 -1
  18. package/dist/core/DesktopLockState.d.ts +38 -0
  19. package/dist/core/DesktopLockState.d.ts.map +1 -0
  20. package/dist/core/DesktopLockState.js +43 -0
  21. package/dist/core/DesktopLockState.js.map +1 -0
  22. package/dist/core/DesktopLockedController.d.ts +138 -0
  23. package/dist/core/DesktopLockedController.d.ts.map +1 -0
  24. package/dist/core/DesktopLockedController.js +442 -0
  25. package/dist/core/DesktopLockedController.js.map +1 -0
  26. package/dist/core/DesktopOperatorAssertion.d.ts +39 -0
  27. package/dist/core/DesktopOperatorAssertion.d.ts.map +1 -1
  28. package/dist/core/DesktopOperatorAssertion.js +49 -0
  29. package/dist/core/DesktopOperatorAssertion.js.map +1 -1
  30. package/dist/core/DesktopProbeReadiness.d.ts.map +1 -1
  31. package/dist/core/DesktopProbeReadiness.js +4 -1
  32. package/dist/core/DesktopProbeReadiness.js.map +1 -1
  33. package/dist/core/DesktopProvenVersions.d.ts +19 -0
  34. package/dist/core/DesktopProvenVersions.d.ts.map +1 -0
  35. package/dist/core/DesktopProvenVersions.js +8 -0
  36. package/dist/core/DesktopProvenVersions.js.map +1 -0
  37. package/dist/core/DirectDesktopAccess.d.ts +20 -1
  38. package/dist/core/DirectDesktopAccess.d.ts.map +1 -1
  39. package/dist/core/DirectDesktopAccess.js +263 -10
  40. package/dist/core/DirectDesktopAccess.js.map +1 -1
  41. package/dist/core/MacDesktopHost.d.ts +36 -1
  42. package/dist/core/MacDesktopHost.d.ts.map +1 -1
  43. package/dist/core/MacDesktopHost.js +132 -38
  44. package/dist/core/MacDesktopHost.js.map +1 -1
  45. package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
  46. package/dist/core/WriteDomainRegistry.js +8 -0
  47. package/dist/core/WriteDomainRegistry.js.map +1 -1
  48. package/dist/core/types.d.ts +6 -0
  49. package/dist/core/types.d.ts.map +1 -1
  50. package/dist/core/types.js.map +1 -1
  51. package/dist/data/standards-guard-index.json +1 -1
  52. package/dist/data/standards-guard-index.meta.json +2 -2
  53. package/dist/data/standards-registry.meta.json +1 -1
  54. package/dist/native/instar-desktop-host +0 -0
  55. package/dist/native/instar-desktop-host.json +1 -1
  56. package/dist/scaffold/templates.d.ts.map +1 -1
  57. package/dist/scaffold/templates.js +1 -1
  58. package/dist/scaffold/templates.js.map +1 -1
  59. package/dist/server/AgentServer.d.ts +4 -0
  60. package/dist/server/AgentServer.d.ts.map +1 -1
  61. package/dist/server/AgentServer.js +117 -4
  62. package/dist/server/AgentServer.js.map +1 -1
  63. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  64. package/dist/server/CapabilityIndex.js +2 -1
  65. package/dist/server/CapabilityIndex.js.map +1 -1
  66. package/dist/server/DesktopMeshBroker.d.ts +6 -0
  67. package/dist/server/DesktopMeshBroker.d.ts.map +1 -1
  68. package/dist/server/DesktopMeshBroker.js +17 -1
  69. package/dist/server/DesktopMeshBroker.js.map +1 -1
  70. package/dist/server/DesktopStreamManager.d.ts +11 -3
  71. package/dist/server/DesktopStreamManager.d.ts.map +1 -1
  72. package/dist/server/DesktopStreamManager.js +24 -1
  73. package/dist/server/DesktopStreamManager.js.map +1 -1
  74. package/dist/server/machineRoutes.d.ts +1 -0
  75. package/dist/server/machineRoutes.d.ts.map +1 -1
  76. package/dist/server/machineRoutes.js +14 -0
  77. package/dist/server/machineRoutes.js.map +1 -1
  78. package/dist/server/routes.d.ts +9 -0
  79. package/dist/server/routes.d.ts.map +1 -1
  80. package/dist/server/routes.js +99 -0
  81. package/dist/server/routes.js.map +1 -1
  82. package/dist/testing/selfActionRegistry.d.ts.map +1 -1
  83. package/dist/testing/selfActionRegistry.js +58 -0
  84. package/dist/testing/selfActionRegistry.js.map +1 -1
  85. package/package.json +1 -1
  86. package/scripts/build-native-desktop-host.mjs +4 -2
  87. package/src/data/builtin-manifest.json +48 -48
  88. package/src/data/standards-guard-index.json +1 -1
  89. package/src/data/standards-guard-index.meta.json +2 -2
  90. package/src/data/standards-registry.meta.json +1 -1
  91. package/src/scaffold/templates.ts +1 -1
  92. package/upgrades/1.3.1598.md +24 -0
  93. package/upgrades/1.3.1599.md +20 -0
  94. package/upgrades/eli16/kept-helper-both-permissions.md +25 -0
  95. package/upgrades/side-effects/desktop-locked-screen.md +129 -0
  96. package/upgrades/side-effects/kept-helper-both-permissions.md +38 -0
@@ -0,0 +1,138 @@
1
+ import { isLockedClass, type DesktopLockPolicy, type DesktopLockSample, type DesktopLockState } from './DesktopLockState.js';
2
+ import { type DesktopProvenVersion } from './DesktopProvenVersions.js';
3
+ export declare const RELOCK_WATCH_MS = 120000;
4
+ export declare const MAX_GUARD_REPLACEMENTS = 3;
5
+ export declare const DISABLE_MARKER_TIMEOUT_MS = 5000;
6
+ export declare const RESPAWNS_PER_CHANGE = 3;
7
+ export declare const RESPAWNS_PER_REQUEST = 8;
8
+ export interface DesktopLockedSettings {
9
+ enabled: boolean;
10
+ browserBox: boolean;
11
+ chime: boolean;
12
+ }
13
+ export interface DesktopRelockMarker {
14
+ state: string;
15
+ agentId?: string;
16
+ requestId?: string;
17
+ deadlineMs?: number;
18
+ resumeWindowMs?: number;
19
+ relockNow?: boolean;
20
+ typistPid?: number;
21
+ typistStart?: string;
22
+ guardPid?: number;
23
+ guardStart?: string;
24
+ guardReplacements?: number;
25
+ enterPendingAt?: number;
26
+ watchStart?: number;
27
+ bootSession?: string;
28
+ loginSession?: string;
29
+ producerGone?: boolean;
30
+ reported?: boolean;
31
+ }
32
+ /** The helper's state-op verb, in one call. */
33
+ export interface DesktopLockedHostPort {
34
+ lockedOp(op: Record<string, unknown>): Promise<Record<string, unknown>>;
35
+ startRelockGuard(key: string): Promise<void>;
36
+ setLockedMode(mode: {
37
+ root: string;
38
+ refuse: string[];
39
+ chime?: boolean;
40
+ } | null): void;
41
+ }
42
+ export interface DesktopLockedDeps {
43
+ host: DesktopLockedHostPort;
44
+ agentId: string;
45
+ settings: () => DesktopLockedSettings;
46
+ saveSettings: (next: DesktopLockedSettings) => void;
47
+ readPolicy: () => Promise<DesktopLockPolicy>;
48
+ tunnelFirstTierActive: () => boolean;
49
+ /** True only once the item is durably with the owner's attention surface. */
50
+ raiseSecurity: (item: {
51
+ key: string;
52
+ title: string;
53
+ body: string;
54
+ }) => boolean | Promise<boolean>;
55
+ audit?: (event: Record<string, unknown>) => void;
56
+ now?: () => number;
57
+ root?: string;
58
+ /** Only tests pass this. Production always uses the shipped table. */
59
+ provenVersions?: readonly DesktopProvenVersion[];
60
+ }
61
+ /** A dead guard is replaced at most this often for one duty, then the duty fails loudly. */
62
+ export declare function decideGuardReplacement(replacements: number): 'replace' | 'give-up';
63
+ /** 3 per state change and 8 per request; spends one or refuses. */
64
+ export declare function decideLockedRespawn(thisChange: number, total: number): boolean;
65
+ export declare class DesktopLockedController {
66
+ private readonly deps;
67
+ readonly root: string;
68
+ private readonly now;
69
+ private readonly proven;
70
+ private policy;
71
+ private lastRawFlag;
72
+ private lastOsMajor;
73
+ private lastState;
74
+ private readonly live;
75
+ private sweepTimer;
76
+ private sweeping;
77
+ private lastAdmissionRefusal;
78
+ constructor(deps: DesktopLockedDeps);
79
+ private storeExists;
80
+ /** The feature needs the owner's setting AND a proven macOS. */
81
+ active(osMajor?: number | undefined): boolean;
82
+ /** Why the enable route refuses. No route can reach past this. */
83
+ enableRefusal(osMajor: number | undefined): string | null;
84
+ /** Tells the host whether to spawn helpers with the feature on. */
85
+ applyMode(osMajor: number | undefined): void;
86
+ private policyFor;
87
+ readState(sample: DesktopLockSample): Promise<DesktopLockState>;
88
+ wanted(): boolean;
89
+ private read;
90
+ private heartbeatAgeMs;
91
+ private renewLease;
92
+ /** The unlock happened, so nothing is left in a password field. */
93
+ noteUnlocked(): Promise<void>;
94
+ private stale;
95
+ /** Both must be confirmed gone before anything reopens. */
96
+ private stopRecorded;
97
+ /** Null admits. Runs even with the feature off, but only if a marker exists,
98
+ * so a clean Mac stays byte for byte today's path. */
99
+ admissionRefusal(sameRequestId?: string): Promise<string | null>;
100
+ noteGrant(requestId: string): void;
101
+ /** Marker first, then guard, then its acknowledgement. Nothing is typed
102
+ * before all three. */
103
+ prepareSecret(requestId: string, deadlineMs: number): Promise<{
104
+ key: string;
105
+ } | {
106
+ refused: string;
107
+ }>;
108
+ /** Stop or the ceiling: relock now. Transport loss renews until the window. */
109
+ endRequest(requestId: string, reason: 'stop' | 'transport-lost'): Promise<void>;
110
+ /** Acknowledged only if this tap beat the guard. */
111
+ leaveUnlocked(requestId: string): Promise<boolean>;
112
+ refundAttempt(requestId: string): Promise<void>;
113
+ enterPostedAt(requestId: string): Promise<number | null>;
114
+ /** The setting and the live grants go off first, so a helper that throws or
115
+ * hangs cannot leave a session running; the Mac-wide marker is attempted last. */
116
+ disable(endGrants?: () => void): Promise<void>;
117
+ isDisabled(): Promise<boolean>;
118
+ applySettings(patch: Partial<DesktopLockedSettings>): Promise<DesktopLockedSettings>;
119
+ /** A hint for honest pages. The target still refuses, and a hostile front
120
+ * can draw a box anyway; that limit is stated in the spec. */
121
+ browserBoxShown(): boolean;
122
+ /** Null when the password path is ready, else a named reason. */
123
+ passwordRefusal(probe: DesktopLockSample & {
124
+ inputGrant?: string;
125
+ helperSource?: string;
126
+ }, client: 'app' | 'browser', state: DesktopLockState): string | null;
127
+ private startSweep;
128
+ stop(): void;
129
+ /** Covers a watch whose request has already ended, so "tells you" holds. */
130
+ sweep(boot?: boolean): Promise<void>;
131
+ /** A guard that lost its store leaves a file, and has already tried to lock. */
132
+ private reportGuardFailures;
133
+ private retryFailed;
134
+ private replaceGuard;
135
+ status(osMajor: number | undefined): Promise<Record<string, unknown>>;
136
+ }
137
+ export { isLockedClass };
138
+ //# sourceMappingURL=DesktopLockedController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DesktopLockedController.d.ts","sourceRoot":"","sources":["../../src/core/DesktopLockedController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,442 @@
1
+ /**
2
+ * Target-side authority for remote desktop through the ordinary Mac lock.
3
+ * Off is today's behaviour: with no setting, no marker and an empty proven
4
+ * table this answers "off" and touches nothing.
5
+ *
6
+ * State that must outlive Node lives on the Mac, changed only by the helper
7
+ * under a kernel lock. This class never takes that lock, so a suspended Node
8
+ * cannot hold a relock up. It holds no password and has no route that makes one.
9
+ * Spec: docs/specs/desktop-locked-screen.md.
10
+ */
11
+ import fs from 'node:fs';
12
+ import os from 'node:os';
13
+ import path from 'node:path';
14
+ import { SafeFsExecutor } from './SafeFsExecutor.js';
15
+ import { DegradationReporter } from '../monitoring/DegradationReporter.js';
16
+ import { classifyDesktopLock, isLockedClass } from './DesktopLockState.js';
17
+ import { PROVEN_MACOS_VERSIONS, provenVersion } from './DesktopProvenVersions.js';
18
+ export const RELOCK_WATCH_MS = 120_000;
19
+ const WATCH_SLACK_MS = 30_000;
20
+ const POLICY_TTL_MS = 60_000;
21
+ const SWEEP_MS = 10_000;
22
+ const GUARD_ACK_MS = 3_000;
23
+ const HEARTBEAT_STALE_MS = 5_000;
24
+ export const MAX_GUARD_REPLACEMENTS = 3;
25
+ const RESUME_WINDOW_MS = 30_000;
26
+ export const DISABLE_MARKER_TIMEOUT_MS = 5_000;
27
+ export const RESPAWNS_PER_CHANGE = 3;
28
+ export const RESPAWNS_PER_REQUEST = 8;
29
+ const TERMINAL = new Set(['relocked', 'relock-failed', 'left-unlocked', 'closed-not-applicable']);
30
+ const BLOCKING = new Set(['owed', 'executing', 'watching']);
31
+ /** A dead guard is replaced at most this often for one duty, then the duty fails loudly. */
32
+ export function decideGuardReplacement(replacements) {
33
+ return replacements >= MAX_GUARD_REPLACEMENTS ? 'give-up' : 'replace';
34
+ }
35
+ /** 3 per state change and 8 per request; spends one or refuses. */
36
+ export function decideLockedRespawn(thisChange, total) {
37
+ return thisChange < RESPAWNS_PER_CHANGE && total < RESPAWNS_PER_REQUEST;
38
+ }
39
+ export class DesktopLockedController {
40
+ deps;
41
+ root;
42
+ now;
43
+ proven;
44
+ policy = null;
45
+ lastRawFlag;
46
+ lastOsMajor;
47
+ lastState = 'unknown';
48
+ live = new Map();
49
+ sweepTimer = null;
50
+ sweeping = false;
51
+ lastAdmissionRefusal = null;
52
+ constructor(deps) {
53
+ this.deps = deps;
54
+ this.root = deps.root ?? path.join(os.homedir(), '.instar', 'desktop-helper', 'locked');
55
+ this.now = deps.now ?? Date.now;
56
+ this.proven = deps.provenVersions ?? PROVEN_MACOS_VERSIONS;
57
+ }
58
+ storeExists() { return fs.existsSync(path.join(this.root, 'locked-state.json')); }
59
+ /** The feature needs the owner's setting AND a proven macOS. */
60
+ active(osMajor = this.lastOsMajor) {
61
+ return this.deps.settings().enabled && !!provenVersion(this.proven, osMajor);
62
+ }
63
+ /** Why the enable route refuses. No route can reach past this. */
64
+ enableRefusal(osMajor) {
65
+ return provenVersion(this.proven, osMajor) ? null : 'unsupported-macos';
66
+ }
67
+ /** Tells the host whether to spawn helpers with the feature on. */
68
+ applyMode(osMajor) {
69
+ this.lastOsMajor = osMajor;
70
+ const row = provenVersion(this.proven, osMajor);
71
+ this.deps.host.setLockedMode(this.deps.settings().enabled && row
72
+ ? { root: this.root, refuse: row.refuse, chime: this.deps.settings().chime } : null);
73
+ }
74
+ async policyFor(flag) {
75
+ const fresh = this.policy && this.now() - this.policy.at < POLICY_TTL_MS;
76
+ // Only a change in a raw input refreshes, or a refresh would feed itself.
77
+ const changed = flag !== this.lastRawFlag;
78
+ this.lastRawFlag = flag;
79
+ if (fresh && !changed)
80
+ return this.policy.value;
81
+ const refreshing = this.deps.readPolicy().then(value => {
82
+ this.policy = { value, at: this.now() };
83
+ return value;
84
+ }, () => {
85
+ this.policy = { value: 'unreadable', at: this.now() };
86
+ return 'unreadable';
87
+ });
88
+ return changed ? (void refreshing, 'pending') : refreshing;
89
+ }
90
+ async readState(sample) {
91
+ this.applyMode(sample.osMajor ?? sample.lockInputs?.osMajor);
92
+ const state = classifyDesktopLock(sample, await this.policyFor(sample.screenLocked), this.now());
93
+ this.lastState = state;
94
+ return state;
95
+ }
96
+ wanted() { return this.deps.settings().enabled; }
97
+ async read() {
98
+ if (!this.storeExists())
99
+ return { markers: {}, disabled: false, dirty: false, attempts: { count: 0 } };
100
+ const reply = await this.deps.host.lockedOp({ op: 'read' });
101
+ const state = (reply.state ?? {});
102
+ return { markers: state.markers ?? {}, disabled: state.disabled === true, dirty: !!state.dirty,
103
+ attempts: (reply.attempts ?? { count: 0 }),
104
+ bootSession: reply.bootSession, loginSession: reply.loginSession };
105
+ }
106
+ heartbeatAgeMs(key) {
107
+ try {
108
+ return this.now() - fs.statSync(path.join(this.root, `hb-${key}`)).mtimeMs;
109
+ }
110
+ catch {
111
+ return null;
112
+ } // @silent-fallback-ok — no heartbeat file reads as stale, which replaces the guard.
113
+ }
114
+ renewLease(key) {
115
+ const file = path.join(this.root, `lease-${key}`);
116
+ fs.writeFileSync(file, '', { mode: 0o600 });
117
+ // Truncating an empty file need not move its time; the guard reads the time.
118
+ const stamp = new Date(this.now());
119
+ fs.utimesSync(file, stamp, stamp);
120
+ }
121
+ /** The unlock happened, so nothing is left in a password field. */
122
+ async noteUnlocked() {
123
+ await this.deps.host.lockedOp({ op: 'clear-dirty' });
124
+ }
125
+ stale(marker, key) {
126
+ const deadline = marker.state === 'watching'
127
+ ? (marker.watchStart ?? 0) + RELOCK_WATCH_MS + WATCH_SLACK_MS
128
+ : (marker.deadlineMs ?? 0);
129
+ const age = this.heartbeatAgeMs(key);
130
+ return this.now() >= deadline && (age === null || age > HEARTBEAT_STALE_MS);
131
+ }
132
+ /** Both must be confirmed gone before anything reopens. */
133
+ async stopRecorded(marker) {
134
+ const stop = async (pid, start) => {
135
+ if (!pid || !start)
136
+ return true;
137
+ return (await this.deps.host.lockedOp({ op: 'kill-recorded', pid, start })).gone === true;
138
+ };
139
+ const [guard, typist] = [await stop(marker.guardPid, marker.guardStart), await stop(marker.typistPid, marker.typistStart)];
140
+ return guard && typist;
141
+ }
142
+ /** Null admits. Runs even with the feature off, but only if a marker exists,
143
+ * so a clean Mac stays byte for byte today's path. */
144
+ async admissionRefusal(sameRequestId) {
145
+ if (!this.storeExists())
146
+ return null;
147
+ const { markers, disabled, bootSession, loginSession } = await this.read();
148
+ if (disabled && this.deps.settings().enabled)
149
+ this.lastAdmissionRefusal = 'disabled';
150
+ for (const [key, marker] of Object.entries(markers)) {
151
+ if (marker.requestId === sameRequestId)
152
+ continue;
153
+ // That reboot or logout already ended the session, so no duty remains.
154
+ if (BLOCKING.has(marker.state) && bootSession && (marker.bootSession !== bootSession
155
+ || (loginSession && marker.loginSession !== loginSession))) {
156
+ await this.deps.host.lockedOp({ op: 'close', key, to: 'closed-not-applicable' });
157
+ continue;
158
+ }
159
+ if (marker.state === 'left-unlocked' && marker.producerGone !== true) {
160
+ if (!await this.stopRecorded({ ...marker, guardPid: undefined }))
161
+ return 'relock-failed-producer-alive';
162
+ await this.deps.host.lockedOp({ op: 'set-producer-gone', key });
163
+ continue;
164
+ }
165
+ if (marker.state === 'relock-failed') {
166
+ if (marker.producerGone === false) {
167
+ if (await this.stopRecorded(marker))
168
+ await this.deps.host.lockedOp({ op: 'set-producer-gone', key });
169
+ else
170
+ return 'relock-failed-producer-alive';
171
+ }
172
+ continue;
173
+ }
174
+ if (!BLOCKING.has(marker.state))
175
+ continue;
176
+ if (!this.stale(marker, key))
177
+ return 'relock-pending';
178
+ if (!await this.stopRecorded(marker))
179
+ return 'relock-pending-unconfirmed';
180
+ await this.deps.host.lockedOp({ op: 'close', key, to: 'relock-failed', producerGone: true });
181
+ }
182
+ return null;
183
+ }
184
+ noteGrant(requestId) {
185
+ if (!this.live.has(requestId))
186
+ this.live.set(requestId, { key: `${requestId}.0`, generation: 0 });
187
+ this.startSweep();
188
+ }
189
+ /** Marker first, then guard, then its acknowledgement. Nothing is typed
190
+ * before all three. */
191
+ async prepareSecret(requestId, deadlineMs) {
192
+ // Stop may have landed already. A marker now would outlive its request.
193
+ const entry = this.live.get(requestId);
194
+ if (!entry)
195
+ return { refused: 'grant-ended' };
196
+ let key = entry.key;
197
+ let reply = await this.deps.host.lockedOp({ op: 'marker-create', key, marker: {
198
+ agentId: this.deps.agentId, requestId, deadlineMs, resumeWindowMs: RESUME_WINDOW_MS
199
+ } });
200
+ if (reply.error)
201
+ return { refused: String(reply.error) };
202
+ const existing = reply.marker;
203
+ if (existing?.state === 'relock-failed')
204
+ return { refused: 'relock-failed' };
205
+ if (existing && TERMINAL.has(existing.state)) {
206
+ entry.generation++;
207
+ key = `${requestId}.${entry.generation}`;
208
+ entry.key = key;
209
+ reply = await this.deps.host.lockedOp({ op: 'marker-create', key, marker: {
210
+ agentId: this.deps.agentId, requestId, deadlineMs, resumeWindowMs: RESUME_WINDOW_MS
211
+ } });
212
+ }
213
+ this.renewLease(key);
214
+ const age = this.heartbeatAgeMs(key);
215
+ if (age === null || age > HEARTBEAT_STALE_MS) {
216
+ await this.deps.host.startRelockGuard(key);
217
+ const until = this.now() + GUARD_ACK_MS;
218
+ while (this.now() < until) {
219
+ const seen = this.heartbeatAgeMs(key);
220
+ if (seen !== null && seen <= HEARTBEAT_STALE_MS)
221
+ return { key };
222
+ await new Promise(resolve => setTimeout(resolve, 100));
223
+ }
224
+ return { refused: 'guard-not-alive' };
225
+ }
226
+ return { key };
227
+ }
228
+ /** Stop or the ceiling: relock now. Transport loss renews until the window. */
229
+ async endRequest(requestId, reason) {
230
+ const entry = this.live.get(requestId);
231
+ if (!entry)
232
+ return;
233
+ if (reason === 'stop') {
234
+ this.live.delete(requestId);
235
+ await this.deps.host.lockedOp({ op: 'relock-now', key: entry.key });
236
+ }
237
+ }
238
+ /** Acknowledged only if this tap beat the guard. */
239
+ async leaveUnlocked(requestId) {
240
+ const entry = this.live.get(requestId);
241
+ if (!entry)
242
+ return false;
243
+ const reply = await this.deps.host.lockedOp({ op: 'leave-unlocked', key: entry.key });
244
+ this.deps.audit?.({ kind: 'leave-unlocked', ok: reply.ok === true });
245
+ return reply.ok === true;
246
+ }
247
+ async refundAttempt(requestId) {
248
+ await this.deps.host.lockedOp({ op: 'refund', requestId });
249
+ }
250
+ async enterPostedAt(requestId) {
251
+ const entry = this.live.get(requestId);
252
+ if (!entry)
253
+ return null;
254
+ return (await this.read()).markers[entry.key]?.enterPendingAt ?? null;
255
+ }
256
+ /** The setting and the live grants go off first, so a helper that throws or
257
+ * hangs cannot leave a session running; the Mac-wide marker is attempted last. */
258
+ async disable(endGrants) {
259
+ const next = { ...this.deps.settings(), enabled: false };
260
+ this.deps.saveSettings(next);
261
+ let markerError = null;
262
+ try {
263
+ endGrants?.();
264
+ }
265
+ finally {
266
+ try {
267
+ let timer;
268
+ await Promise.race([
269
+ this.deps.host.lockedOp({ op: 'set-disabled', disabled: true }),
270
+ new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('locked-disable-marker-timeout')), DISABLE_MARKER_TIMEOUT_MS); }),
271
+ ]).finally(() => clearTimeout(timer));
272
+ }
273
+ catch (err) {
274
+ // Surfaced, not swallowed: audited, named in the security item, and re-thrown below.
275
+ markerError = err;
276
+ }
277
+ this.deps.audit?.({ kind: 'locked-disable', markerWritten: markerError === null });
278
+ this.deps.raiseSecurity({ key: 'desktop-locked-disabled', title: 'Remote desktop through the lock was turned off',
279
+ body: markerError === null
280
+ ? 'Any open locked-screen session was ended. The dashboard PIN turns it back on.'
281
+ : 'Any open locked-screen session was ended and the setting is off, but the Mac-wide off marker could not be written. Turn it off again from the dashboard to retry.' });
282
+ }
283
+ if (markerError !== null)
284
+ throw markerError instanceof Error ? markerError : new Error(String(markerError));
285
+ }
286
+ async isDisabled() { return (await this.read()).disabled; }
287
+ async applySettings(patch) {
288
+ const next = { ...this.deps.settings(), ...patch };
289
+ if (patch.enabled === true)
290
+ await this.deps.host.lockedOp({ op: 'set-disabled', disabled: false });
291
+ this.deps.saveSettings(next);
292
+ this.applyMode(this.lastOsMajor);
293
+ return next;
294
+ }
295
+ /** A hint for honest pages. The target still refuses, and a hostile front
296
+ * can draw a box anyway; that limit is stated in the spec. */
297
+ browserBoxShown() {
298
+ return this.deps.settings().browserBox && this.deps.tunnelFirstTierActive();
299
+ }
300
+ /** Null when the password path is ready, else a named reason. */
301
+ passwordRefusal(probe, client, state) {
302
+ if (!this.active(probe.osMajor))
303
+ return 'unsupported-macos';
304
+ if (probe.helperSource !== 'retained')
305
+ return 'retained-helper-required';
306
+ if (probe.inputGrant !== 'own')
307
+ return 'own-input-grant-required';
308
+ if (client === 'browser') {
309
+ if (!this.deps.settings().browserBox)
310
+ return 'browser-box-off';
311
+ if (!this.deps.tunnelFirstTierActive())
312
+ return 'tunnel-not-first-tier';
313
+ }
314
+ return state === 'locked-in-session' ? null : 'not-locked';
315
+ }
316
+ startSweep() {
317
+ if (this.sweepTimer)
318
+ return;
319
+ this.sweepTimer = setInterval(() => {
320
+ void this.sweep().catch((error) => {
321
+ console.warn('[instar] locked-screen sweep failed');
322
+ DegradationReporter.getInstance().report({ feature: 'DesktopLocked.sweep',
323
+ primary: 'Locked-screen relock sweep', fallback: 'The next sweep tick retries',
324
+ reason: `sweep failed: ${error instanceof Error ? error.message : String(error)}`,
325
+ impact: 'A relock or a guard replacement may be late by one sweep interval or more.' });
326
+ });
327
+ }, SWEEP_MS);
328
+ this.sweepTimer.unref?.();
329
+ }
330
+ stop() {
331
+ if (this.sweepTimer)
332
+ clearInterval(this.sweepTimer);
333
+ this.sweepTimer = null;
334
+ }
335
+ /** Covers a watch whose request has already ended, so "tells you" holds. */
336
+ async sweep(boot = false) {
337
+ if (this.sweeping || !this.storeExists())
338
+ return;
339
+ this.sweeping = true;
340
+ // Started before the read, so a slow or failed read cannot end the watching.
341
+ this.startSweep();
342
+ try {
343
+ const untold = await this.reportGuardFailures();
344
+ const { markers } = await this.read();
345
+ const { bootSession, loginSession } = await this.read();
346
+ let open = untold;
347
+ for (const [key, marker] of Object.entries(markers)) {
348
+ if (marker.agentId !== this.deps.agentId)
349
+ continue;
350
+ const sameSession = !bootSession || (marker.bootSession === bootSession
351
+ && (!loginSession || marker.loginSession === loginSession));
352
+ if (BLOCKING.has(marker.state) && !sameSession) {
353
+ await this.deps.host.lockedOp({ op: 'close', key, to: 'closed-not-applicable' });
354
+ continue;
355
+ }
356
+ if (BLOCKING.has(marker.state)) {
357
+ open = true;
358
+ const requestId = marker.requestId ?? '';
359
+ if (this.live.has(requestId))
360
+ this.renewLease(key);
361
+ else if (boot && marker.state === 'owed')
362
+ await this.deps.host.lockedOp({ op: 'relock-now', key });
363
+ const age = this.heartbeatAgeMs(key);
364
+ if (age === null || age > HEARTBEAT_STALE_MS)
365
+ await this.replaceGuard(key, marker);
366
+ }
367
+ else if (marker.state === 'relock-failed' && !marker.reported) {
368
+ open = true;
369
+ if (boot && sameSession)
370
+ await this.retryFailed(key, marker);
371
+ const told = await this.deps.raiseSecurity({ key: `desktop-relock-failed:${key}`, title: 'A Mac may still be unlocked',
372
+ body: 'Instar could not confirm the relock after a remote desktop session. Lock it, or open it to check.' });
373
+ // Unconfirmed stays unreported, so the next sweep tries again.
374
+ if (told)
375
+ await this.deps.host.lockedOp({ op: 'mark-reported', key });
376
+ }
377
+ }
378
+ if (open)
379
+ this.startSweep();
380
+ else if (this.live.size === 0)
381
+ this.stop();
382
+ }
383
+ catch {
384
+ // The guard locks by itself. What fails here is telling the owner, so say so.
385
+ await this.deps.raiseSecurity({ key: 'desktop-locked-store-unreadable', title: 'A Mac may need checking',
386
+ body: 'Instar could not read its relock record for this Mac. Lock it, or open it to check.' });
387
+ }
388
+ finally {
389
+ this.sweeping = false;
390
+ }
391
+ }
392
+ /** A guard that lost its store leaves a file, and has already tried to lock. */
393
+ async reportGuardFailures() {
394
+ let untold = false;
395
+ for (const name of fs.readdirSync(this.root).filter(file => file.startsWith('failed-'))) {
396
+ const told = await this.deps.raiseSecurity({ key: `desktop-relock-${name}`, title: 'A Mac may still be unlocked',
397
+ body: 'Instar lost its relock record after a remote desktop session and tried to lock the Mac. Check it.' });
398
+ if (told)
399
+ SafeFsExecutor.safeRmSync(path.join(this.root, name), { force: true, operation: 'src/core/DesktopLockedController.ts:reportGuardFailures' });
400
+ else
401
+ untold = true;
402
+ }
403
+ return untold;
404
+ }
405
+ async retryFailed(key, marker) {
406
+ const requestId = marker.requestId ?? key.split('.')[0];
407
+ const generation = Number(key.split('.')[1] ?? 0) + 1;
408
+ const next = `${requestId}.${generation}`;
409
+ await this.deps.host.lockedOp({ op: 'marker-create', key: next, marker: {
410
+ agentId: this.deps.agentId, requestId, deadlineMs: this.now(), resumeWindowMs: RESUME_WINDOW_MS
411
+ } });
412
+ await this.deps.host.lockedOp({ op: 'relock-now', key: next });
413
+ await this.deps.host.startRelockGuard(next);
414
+ }
415
+ async replaceGuard(key, marker) {
416
+ const count = marker.guardReplacements ?? 0;
417
+ const guardGone = !marker.guardPid || !marker.guardStart
418
+ || (await this.deps.host.lockedOp({ op: 'kill-recorded', pid: marker.guardPid, start: marker.guardStart })).gone === true;
419
+ if (decideGuardReplacement(count) === 'give-up') {
420
+ const typistGone = !marker.typistPid || !marker.typistStart
421
+ || (await this.deps.host.lockedOp({ op: 'kill-recorded', pid: marker.typistPid, start: marker.typistStart })).gone === true;
422
+ await this.deps.host.lockedOp({ op: 'close', key, to: 'relock-failed', producerGone: guardGone && typistGone });
423
+ return;
424
+ }
425
+ if (!guardGone)
426
+ return;
427
+ await this.deps.host.lockedOp({ op: 'set-guard', key, pid: 0, start: '', replacements: count + 1 });
428
+ await this.deps.host.startRelockGuard(key);
429
+ }
430
+ async status(osMajor) {
431
+ const { markers, disabled, attempts } = await this.read();
432
+ const settings = this.deps.settings();
433
+ return { enabled: settings.enabled, active: this.active(osMajor), disabled,
434
+ browserBox: settings.browserBox, chime: settings.chime,
435
+ refusal: this.enableRefusal(osMajor), lockState: this.lastState,
436
+ attemptsToday: attempts.count ?? 0, lastAdmissionRefusal: this.lastAdmissionRefusal,
437
+ openDuties: Object.values(markers).filter(item => BLOCKING.has(item.state)).length,
438
+ failedRelocks: Object.values(markers).filter(item => item.state === 'relock-failed').length };
439
+ }
440
+ }
441
+ export { isLockedClass };
442
+ //# sourceMappingURL=DesktopLockedController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DesktopLockedController.js","sourceRoot":"","sources":["../../src/core/DesktopLockedController.ts"],"names":[],"mappings":"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"}