@volter/teams 0.1.37 → 0.1.38
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.
- package/machine-core.mjs +18 -5
- package/package.json +1 -1
package/machine-core.mjs
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
// It decides nothing on anyone's behalf. Every act is logged.
|
|
9
9
|
import { createServer, connect as netConnect } from 'node:net';
|
|
10
10
|
import { EventEmitter } from 'node:events';
|
|
11
|
-
import { existsSync, mkdirSync, rmSync, chmodSync } from 'node:fs';
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, chmodSync, statSync } from 'node:fs';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
12
13
|
import { randomBytes } from 'node:crypto';
|
|
13
14
|
import { WebSocket, createWebSocketStream } from 'ws';
|
|
14
15
|
import { Channel, NODE_PROTOCOL } from './channel.mjs';
|
|
@@ -89,13 +90,22 @@ export class MachineCore extends EventEmitter {
|
|
|
89
90
|
await clearStaleSocket(this.socketPath);
|
|
90
91
|
await this.beforeListen();
|
|
91
92
|
this.server = createServer((socket) => this.#accept(socket));
|
|
93
|
+
// A Unix socket is bound under a name of this daemon's own and then renamed into place: Node unlinks the name it
|
|
94
|
+
// bound when the server closes, and that name must never be the shared path, which a later daemon may serve from a
|
|
95
|
+
// file of its own (a daemon stopping later deleted the serving daemon's socket and cut it off).
|
|
96
|
+
const bindPath = isNamedPipe(this.socketPath) ? this.socketPath : join(dirname(this.socketPath), `.m${process.pid.toString(36)}`);
|
|
97
|
+
if (bindPath !== this.socketPath) rmSync(bindPath, { force: true });
|
|
92
98
|
await new Promise((resolveListen, reject) => {
|
|
93
99
|
this.server.once('error', reject);
|
|
94
|
-
this.server.listen(
|
|
100
|
+
this.server.listen(bindPath, () => { this.server.off('error', reject); resolveListen(); });
|
|
95
101
|
});
|
|
96
102
|
// Owner-only: the socket is the local door, and whoever opens it is this OS user. A named pipe's default
|
|
97
103
|
// access already admits only its owner (and SYSTEM and Administrators) to connect.
|
|
98
|
-
if (!isNamedPipe(this.socketPath))
|
|
104
|
+
if (!isNamedPipe(this.socketPath)) {
|
|
105
|
+
chmodSync(bindPath, 0o600);
|
|
106
|
+
this.socketInode = statSync(bindPath).ino;
|
|
107
|
+
renameSync(bindPath, this.socketPath);
|
|
108
|
+
}
|
|
99
109
|
this.address = this.socketPath;
|
|
100
110
|
writeJson(this.p.machine, { pid: process.pid, id: this.id, socket: this.socketPath, startedAt: Date.now(), version: MACHINE_VERSION, protocol: NODE_PROTOCOL, floor: this.floor, server: this.link?.server ?? null });
|
|
101
111
|
this.emit('listening', this.socketPath);
|
|
@@ -116,8 +126,11 @@ export class MachineCore extends EventEmitter {
|
|
|
116
126
|
for (const { channel } of this.connections.values()) channel.close();
|
|
117
127
|
this.server?.close();
|
|
118
128
|
await this.afterStop();
|
|
119
|
-
|
|
120
|
-
if (
|
|
129
|
+
// Only this daemon's own socket and record: a daemon that has since taken the path over keeps them.
|
|
130
|
+
if (!isNamedPipe(this.socketPath) && this.socketInode !== undefined) {
|
|
131
|
+
try { if (statSync(this.socketPath).ino === this.socketInode) rmSync(this.socketPath, { force: true }); } catch { /* already gone */ }
|
|
132
|
+
}
|
|
133
|
+
try { if (JSON.parse(readFileSync(this.p.machine, 'utf8')).pid === process.pid) rmSync(this.p.machine); } catch { /* absent or unreadable */ }
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
/** Before the connections close: a product finishes or abandons what is in flight. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/teams",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Volter Teams, the neutral team plane: machine identity and daemon core, the local door and server link, admission from machine grants, product doors, and the Teams server's neutral routes (company RFC 0008).",
|
|
6
6
|
"license": "MIT",
|