@vex-chat/spire 1.0.0 → 1.0.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.
- package/README.md +37 -38
- package/dist/ClientManager.d.ts +1 -3
- package/dist/ClientManager.js +6 -48
- package/dist/ClientManager.js.map +1 -1
- package/dist/Database.d.ts +25 -5
- package/dist/Database.js +54 -16
- package/dist/Database.js.map +1 -1
- package/dist/Spire.d.ts +0 -3
- package/dist/Spire.js +35 -73
- package/dist/Spire.js.map +1 -1
- package/dist/__tests__/Database.spec.js +0 -14
- package/dist/__tests__/Database.spec.js.map +1 -1
- package/dist/db/schema.d.ts +1 -0
- package/dist/migrations/2026-04-14_argon2id-password-hashing.d.ts +3 -0
- package/dist/migrations/2026-04-14_argon2id-password-hashing.js +12 -0
- package/dist/migrations/2026-04-14_argon2id-password-hashing.js.map +1 -0
- package/dist/run.js +0 -1
- package/dist/run.js.map +1 -1
- package/dist/server/avatar.d.ts +1 -3
- package/dist/server/avatar.js +7 -11
- package/dist/server/avatar.js.map +1 -1
- package/dist/server/errors.d.ts +3 -6
- package/dist/server/errors.js +2 -28
- package/dist/server/errors.js.map +1 -1
- package/dist/server/file.d.ts +1 -2
- package/dist/server/file.js +5 -7
- package/dist/server/file.js.map +1 -1
- package/dist/server/index.d.ts +1 -2
- package/dist/server/index.js +22 -33
- package/dist/server/index.js.map +1 -1
- package/dist/server/invite.d.ts +1 -2
- package/dist/server/invite.js +1 -1
- package/dist/server/invite.js.map +1 -1
- package/dist/server/rateLimit.d.ts +3 -3
- package/dist/server/rateLimit.js +6 -6
- package/dist/server/rateLimit.js.map +1 -1
- package/dist/server/user.d.ts +1 -2
- package/dist/server/user.js +3 -5
- package/dist/server/user.js.map +1 -1
- package/dist/utils/jwtSecret.d.ts +3 -3
- package/dist/utils/jwtSecret.js +5 -6
- package/dist/utils/jwtSecret.js.map +1 -1
- package/dist/utils/loadEnv.js +1 -1
- package/dist/utils/loadEnv.js.map +1 -1
- package/package.json +6 -4
- package/src/ClientManager.ts +6 -58
- package/src/Database.ts +83 -21
- package/src/Spire.ts +37 -108
- package/src/__tests__/Database.spec.ts +0 -17
- package/src/db/schema.ts +1 -0
- package/src/migrations/2026-04-14_argon2id-password-hashing.ts +18 -0
- package/src/run.ts +0 -1
- package/src/server/avatar.ts +7 -14
- package/src/server/errors.ts +3 -32
- package/src/server/file.ts +5 -10
- package/src/server/index.ts +23 -37
- package/src/server/invite.ts +0 -2
- package/src/server/rateLimit.ts +6 -6
- package/src/server/user.ts +2 -6
- package/src/utils/jwtSecret.ts +5 -6
- package/src/utils/loadEnv.ts +1 -1
- package/dist/utils/createLogger.d.ts +0 -5
- package/dist/utils/createLogger.js +0 -35
- package/dist/utils/createLogger.js.map +0 -1
- package/src/utils/createLogger.ts +0 -47
package/README.md
CHANGED
|
@@ -1,56 +1,52 @@
|
|
|
1
1
|
# @vex-chat/spire
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@vex-chat/spire)
|
|
4
|
-
[](https://github.com/vex-protocol/spire/actions/workflows/build.yml)
|
|
5
|
-
[](https://github.com/vex-protocol/spire/releases)
|
|
4
|
+
[](https://github.com/vex-protocol/spire-js/actions/workflows/build.yml)
|
|
5
|
+
[](https://github.com/vex-protocol/spire-js/releases)
|
|
6
6
|
[](./LICENSE)
|
|
7
|
-
[](https://github.com/plantain-00/type-coverage)
|
|
7
|
+
[](https://github.com/plantain-00/type-coverage)
|
|
8
8
|
[](./package.json)
|
|
9
|
-
[](https://securityscorecards.dev/viewer/?uri=github.com/vex-protocol/spire)
|
|
9
|
+
[](https://securityscorecards.dev/viewer/?uri=github.com/vex-protocol/spire-js)
|
|
10
10
|
[](https://socket.dev/npm/package/@vex-chat/spire)
|
|
11
11
|
|
|
12
|
-
Reference server implementation for the [Vex](https://vex.wtf)
|
|
12
|
+
Reference server implementation for the [Vex](https://vex.wtf) protocol.
|
|
13
13
|
|
|
14
14
|
## What's in the box
|
|
15
15
|
|
|
16
|
-
- **REST API** (Express 5) for auth, registration, users, servers, channels, invites, and file upload.
|
|
17
|
-
- **WebSocket server** (native `ws`) for real-time messaging, presence, and push notifications. Frames are msgpack-encoded per the AsyncAPI spec in `@vex-chat/types`.
|
|
18
|
-
- **SQLite persistence** via Kysely + better-sqlite3. Single-file DB, zero external services.
|
|
19
|
-
- **Runtime validation** on every trust boundary: every request body, query string, and WebSocket payload is parsed through a Zod schema before any logic runs.
|
|
20
|
-
- **Interactive docs** — [Scalar](https://scalar.com) at `/docs` for the OpenAPI spec, the [AsyncAPI web component](https://www.asyncapi.com) at `/async-docs` for the WebSocket protocol. Both production-gated for security.
|
|
21
|
-
- **Authentication** via `@vex-chat/crypto` signing keys plus JWT session tokens. Password hashing via native `node:crypto` PBKDF2.
|
|
16
|
+
- **REST API** (Express 5) for full e2e messaging including auth, registration, users, servers, channels, invites, and file upload.
|
|
22
17
|
|
|
23
18
|
## Install
|
|
24
19
|
|
|
25
|
-
From public npm:
|
|
26
|
-
|
|
27
|
-
```sh
|
|
28
|
-
npm install @vex-chat/spire
|
|
29
|
-
```
|
|
30
|
-
|
|
31
20
|
Or clone the repo:
|
|
32
21
|
|
|
33
22
|
```sh
|
|
34
|
-
git clone git@github.com:vex-protocol/spire
|
|
35
|
-
cd spire
|
|
23
|
+
git clone git@github.com:vex-protocol/spire-js
|
|
24
|
+
cd spire-js
|
|
36
25
|
npm ci
|
|
37
26
|
```
|
|
38
27
|
|
|
39
|
-
## Running the server
|
|
28
|
+
## Running the server (Docker)
|
|
40
29
|
|
|
41
|
-
|
|
30
|
+
From a clone, with Docker and Docker Compose installed:
|
|
42
31
|
|
|
43
32
|
```sh
|
|
44
|
-
|
|
33
|
+
cp .env.example .env
|
|
34
|
+
# set SPK, JWT_SECRET, DB_TYPE, … (see Configuration)
|
|
35
|
+
docker compose up --build
|
|
45
36
|
```
|
|
46
37
|
|
|
47
|
-
|
|
38
|
+
Compose builds the image from this repo’s `Dockerfile`, starts Spire with a persistent **`spire-data`** volume mounted at `/data` (SQLite + `files/`, `avatars/`, `emoji/`), and fronts it with **nginx** on **port 8080**. Use **http://localhost:8080** for HTTP and WebSocket.
|
|
39
|
+
|
|
40
|
+
## Running without Docker
|
|
41
|
+
|
|
42
|
+
For local development or if you installed from npm, Spire runs with `node --experimental-strip-types` (no separate compile step):
|
|
48
43
|
|
|
49
44
|
```sh
|
|
50
|
-
|
|
45
|
+
npm start
|
|
46
|
+
# or: node --experimental-strip-types src/run.ts
|
|
51
47
|
```
|
|
52
48
|
|
|
53
|
-
From an npm install,
|
|
49
|
+
From an npm install, sources live under `node_modules/@vex-chat/spire/src/`:
|
|
54
50
|
|
|
55
51
|
```sh
|
|
56
52
|
node --experimental-strip-types node_modules/@vex-chat/spire/src/run.ts
|
|
@@ -58,30 +54,33 @@ node --experimental-strip-types node_modules/@vex-chat/spire/src/run.ts
|
|
|
58
54
|
|
|
59
55
|
## Configuration
|
|
60
56
|
|
|
61
|
-
Spire reads configuration from environment variables.
|
|
57
|
+
Spire reads configuration from environment variables. **Docker Compose:** put them in a `.env` file next to `docker-compose.yml` (the `env_file` entry injects them into the container). **Bare Node:** `dotenv` loads `.env` from the process working directory when you run `src/run.ts`.
|
|
62
58
|
|
|
63
59
|
### Required
|
|
64
60
|
|
|
65
|
-
| Variable
|
|
66
|
-
|
|
|
67
|
-
| `SPK`
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
61
|
+
| Variable | Description |
|
|
62
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| `SPK` | Server private key, hex-encoded. Generate with `npm run gen-spk` (prints `SPK` and `JWT_SECRET` lines). Used for server identity signing (NaCl). |
|
|
64
|
+
| `JWT_SECRET` | Hex or string used as the **HMAC secret for JWTs** — **required** and must be **separate from `SPK`**. `npm run gen-spk` emits a dedicated value; do not reuse `SPK` here. |
|
|
65
|
+
| `DB_TYPE` | `sqlite`, `sqlite3`, or `sqlite3mem`. All values use **SQLite** via `better-sqlite3` (file or `:memory:`). `sqlite3mem` is for tests. The string `mysql` is still accepted for compatibility but maps to the same SQLite setup as the default (there is no MySQL driver). |
|
|
70
66
|
|
|
71
67
|
### Optional
|
|
72
68
|
|
|
73
|
-
| Variable
|
|
74
|
-
|
|
|
75
|
-
| `API_PORT`
|
|
76
|
-
| `NODE_ENV`
|
|
77
|
-
| `
|
|
69
|
+
| Variable | Default | Description |
|
|
70
|
+
| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `API_PORT` | `16777` | Port for the REST API and WebSocket server (see `Spire` default in code if unset). |
|
|
72
|
+
| `NODE_ENV` | _(unset)_ | Set to `production` to disable interactive `/docs` / `/async-docs`. If unset or any other value, doc viewers are mounted. `helmet()` runs in all modes. |
|
|
73
|
+
| `CORS_ORIGINS` | _(empty)_ | Comma-separated allowed `Origin` values for `cors`. If unset or empty, **no cross-origin browser access** (`origin: false`). |
|
|
74
|
+
| `CANARY` | _(unset)_ | |
|
|
78
75
|
|
|
79
76
|
### Sample `.env`
|
|
80
77
|
|
|
81
78
|
```sh
|
|
82
|
-
|
|
79
|
+
# Run `npm run gen-spk` and paste the two lines it prints (SPK + JWT_SECRET).
|
|
80
|
+
SPK=a1b2c3...
|
|
81
|
+
JWT_SECRET=d4e5f6...
|
|
83
82
|
DB_TYPE=sqlite
|
|
84
|
-
CANARY=
|
|
83
|
+
# CANARY=true
|
|
85
84
|
API_PORT=16777
|
|
86
85
|
NODE_ENV=production
|
|
87
86
|
```
|
package/dist/ClientManager.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { Database } from "./Database.ts";
|
|
|
2
2
|
import type { BaseMsg, Device, User, UserRecord } from "@vex-chat/types";
|
|
3
3
|
import type WebSocket from "ws";
|
|
4
4
|
import { EventEmitter } from "events";
|
|
5
|
-
import { type SpireOptions } from "./Spire.ts";
|
|
6
5
|
export declare const POWER_LEVELS: {
|
|
7
6
|
CREATE: number;
|
|
8
7
|
DELETE: number;
|
|
@@ -17,11 +16,10 @@ export declare class ClientManager extends EventEmitter {
|
|
|
17
16
|
private db;
|
|
18
17
|
private device;
|
|
19
18
|
private failed;
|
|
20
|
-
private log;
|
|
21
19
|
private notify;
|
|
22
20
|
private user;
|
|
23
21
|
private userDetails;
|
|
24
|
-
constructor(ws: WebSocket, db: Database, notify: (userID: string, event: string, transmissionID: string) => void, userDetails: User
|
|
22
|
+
constructor(ws: WebSocket, db: Database, notify: (userID: string, event: string, transmissionID: string) => void, userDetails: User);
|
|
25
23
|
getDevice(): Device;
|
|
26
24
|
getUser(): UserRecord;
|
|
27
25
|
send(msg: BaseMsg, header?: Uint8Array): void;
|
package/dist/ClientManager.js
CHANGED
|
@@ -3,10 +3,8 @@ import { setTimeout as sleep } from "node:timers/promises";
|
|
|
3
3
|
import { xConcat, XUtils } from "@vex-chat/crypto";
|
|
4
4
|
import { xSignOpen } from "@vex-chat/crypto";
|
|
5
5
|
import { MailWSSchema, SocketAuthErrors } from "@vex-chat/types";
|
|
6
|
-
import pc from "picocolors";
|
|
7
6
|
import { parse as uuidParse, validate as uuidValidate } from "uuid";
|
|
8
7
|
import { TOKEN_EXPIRY } from "./Spire.js";
|
|
9
|
-
import { createLogger } from "./utils/createLogger.js";
|
|
10
8
|
import { createUint8UUID } from "./utils/createUint8UUID.js";
|
|
11
9
|
import { msgpack } from "./utils/msgpack.js";
|
|
12
10
|
export const POWER_LEVELS = {
|
|
@@ -27,11 +25,10 @@ export class ClientManager extends EventEmitter {
|
|
|
27
25
|
db;
|
|
28
26
|
device;
|
|
29
27
|
failed = false;
|
|
30
|
-
log;
|
|
31
28
|
notify;
|
|
32
29
|
user;
|
|
33
30
|
userDetails;
|
|
34
|
-
constructor(ws, db, notify, userDetails
|
|
31
|
+
constructor(ws, db, notify, userDetails) {
|
|
35
32
|
super();
|
|
36
33
|
this.conn = ws;
|
|
37
34
|
this.db = db;
|
|
@@ -39,7 +36,6 @@ export class ClientManager extends EventEmitter {
|
|
|
39
36
|
this.userDetails = userDetails;
|
|
40
37
|
this.device = null;
|
|
41
38
|
this.notify = notify;
|
|
42
|
-
this.log = createLogger("client-manager", options?.logLevel || "error");
|
|
43
39
|
this.initListeners();
|
|
44
40
|
this.challenge();
|
|
45
41
|
}
|
|
@@ -56,25 +52,12 @@ export class ClientManager extends EventEmitter {
|
|
|
56
52
|
return this.user;
|
|
57
53
|
}
|
|
58
54
|
send(msg, header) {
|
|
59
|
-
if (header) {
|
|
60
|
-
this.log.debug(pc.bold(pc.red("OUTH")), header.toString());
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
this.log.debug(pc.bold(pc.red("OUTH")), emptyHeader.toString());
|
|
64
|
-
}
|
|
65
55
|
const packedMessage = packMessage(msg, header);
|
|
66
|
-
this.log.info(pc.bold("⟶ ") +
|
|
67
|
-
responseColor(msg.type.toUpperCase()) +
|
|
68
|
-
" " +
|
|
69
|
-
this.toString() +
|
|
70
|
-
" " +
|
|
71
|
-
pc.yellow(Buffer.byteLength(packedMessage)));
|
|
72
|
-
this.log.debug(pc.bold(pc.red("OUT")), msg);
|
|
73
56
|
try {
|
|
74
57
|
this.conn.send(packedMessage);
|
|
75
58
|
}
|
|
76
|
-
catch (
|
|
77
|
-
|
|
59
|
+
catch (_err) {
|
|
60
|
+
// debugger: WS send failed
|
|
78
61
|
this.fail();
|
|
79
62
|
}
|
|
80
63
|
}
|
|
@@ -103,7 +86,6 @@ export class ClientManager extends EventEmitter {
|
|
|
103
86
|
if (this.failed) {
|
|
104
87
|
return;
|
|
105
88
|
}
|
|
106
|
-
this.log.warn("Connection closed.");
|
|
107
89
|
this.conn.close();
|
|
108
90
|
this.failed = true;
|
|
109
91
|
this.emit("fail");
|
|
@@ -124,23 +106,15 @@ export class ClientManager extends EventEmitter {
|
|
|
124
106
|
this.fail();
|
|
125
107
|
});
|
|
126
108
|
this.conn.on("message", (message) => {
|
|
127
|
-
const [header, msg] = unpackMessage(message);
|
|
128
109
|
const size = Buffer.byteLength(message);
|
|
129
110
|
if (size > MAX_MSG_SIZE) {
|
|
130
|
-
this.sendErr(
|
|
111
|
+
this.sendErr("00000000-0000-0000-0000-000000000000", "Message is too big. Received size " +
|
|
131
112
|
String(size) +
|
|
132
113
|
" while max size is " +
|
|
133
114
|
String(MAX_MSG_SIZE));
|
|
134
115
|
return;
|
|
135
116
|
}
|
|
136
|
-
|
|
137
|
-
pc.bold(msg.type.toUpperCase()) +
|
|
138
|
-
" " +
|
|
139
|
-
this.toString() +
|
|
140
|
-
" " +
|
|
141
|
-
pc.yellow(String(size)));
|
|
142
|
-
this.log.debug(pc.bold(pc.red("INH")), header.toString());
|
|
143
|
-
this.log.debug(pc.bold(pc.red("IN")), msg);
|
|
117
|
+
const [header, msg] = unpackMessage(message);
|
|
144
118
|
if (!msg.type) {
|
|
145
119
|
this.sendErr(msg.transmissionID, "Message type is required.");
|
|
146
120
|
return;
|
|
@@ -173,7 +147,6 @@ export class ClientManager extends EventEmitter {
|
|
|
173
147
|
void this.verifyResponse(msg);
|
|
174
148
|
break;
|
|
175
149
|
default:
|
|
176
|
-
this.log.info("unsupported message %s", msg.type);
|
|
177
150
|
break;
|
|
178
151
|
}
|
|
179
152
|
});
|
|
@@ -191,7 +164,6 @@ export class ClientManager extends EventEmitter {
|
|
|
191
164
|
const mail = mailResult.data;
|
|
192
165
|
try {
|
|
193
166
|
await this.db.saveMail(mail, header, this.getDevice().deviceID, this.getUser().userID);
|
|
194
|
-
this.log.info("Received mail for " + mail.recipient);
|
|
195
167
|
const deviceDetails = await this.db.retrieveDevice(mail.recipient);
|
|
196
168
|
if (!deviceDetails) {
|
|
197
169
|
this.sendErr(msg.transmissionID, "No associated user record found for device.");
|
|
@@ -201,13 +173,12 @@ export class ClientManager extends EventEmitter {
|
|
|
201
173
|
this.notify(deviceDetails.owner, "mail", msg.transmissionID, null, mail.recipient);
|
|
202
174
|
}
|
|
203
175
|
catch (err) {
|
|
204
|
-
this.log.error(String(err));
|
|
205
176
|
this.sendErr(msg.transmissionID, String(err));
|
|
206
177
|
}
|
|
207
178
|
}
|
|
208
179
|
break;
|
|
209
180
|
default:
|
|
210
|
-
|
|
181
|
+
break;
|
|
211
182
|
}
|
|
212
183
|
}
|
|
213
184
|
ping() {
|
|
@@ -279,7 +250,6 @@ export class ClientManager extends EventEmitter {
|
|
|
279
250
|
}
|
|
280
251
|
}
|
|
281
252
|
if (!message) {
|
|
282
|
-
this.log.warn("Signature verification failed!");
|
|
283
253
|
this.sendAuthError(SocketAuthErrors.BadSignature);
|
|
284
254
|
this.fail();
|
|
285
255
|
return;
|
|
@@ -289,12 +259,10 @@ export class ClientManager extends EventEmitter {
|
|
|
289
259
|
this.authorize(msg.transmissionID);
|
|
290
260
|
}
|
|
291
261
|
else {
|
|
292
|
-
this.log.warn("Token is bad!");
|
|
293
262
|
this.sendAuthError(SocketAuthErrors.InvalidToken);
|
|
294
263
|
}
|
|
295
264
|
}
|
|
296
265
|
else {
|
|
297
|
-
this.log.info("User is not registered.");
|
|
298
266
|
this.sendAuthError(SocketAuthErrors.UserNotRegistered);
|
|
299
267
|
this.fail();
|
|
300
268
|
}
|
|
@@ -312,14 +280,4 @@ function unpackMessage(msg) {
|
|
|
312
280
|
const msgb = msgpack.decode(msgp.slice(32));
|
|
313
281
|
return [msgh, msgb];
|
|
314
282
|
}
|
|
315
|
-
const responseColor = (status) => {
|
|
316
|
-
switch (status) {
|
|
317
|
-
case "ERROR":
|
|
318
|
-
return pc.bold(pc.red(status));
|
|
319
|
-
case "SUCCESS":
|
|
320
|
-
return pc.bold(pc.green(status));
|
|
321
|
-
default:
|
|
322
|
-
return status;
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
283
|
//# sourceMappingURL=ClientManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClientManager.js","sourceRoot":"","sources":["../src/ClientManager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ClientManager.js","sourceRoot":"","sources":["../src/ClientManager.ts"],"names":[],"mappings":"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"}
|
package/dist/Database.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { SpireOptions } from "./Spire.ts";
|
|
2
2
|
import type { Channel, Device, DevicePayload, Emoji, FileSQL, Invite, KeyBundle, MailWS, Permission, PreKeysWS, RegistrationPayload, Server, UserRecord } from "@vex-chat/types";
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
|
-
|
|
4
|
+
/** Internal record that includes the hash algorithm discriminator. */
|
|
5
|
+
export interface InternalUserRecord extends UserRecord {
|
|
6
|
+
hashAlgo: string;
|
|
7
|
+
}
|
|
5
8
|
export declare class Database extends EventEmitter {
|
|
6
9
|
private db;
|
|
7
|
-
private log;
|
|
8
10
|
constructor(options?: SpireOptions);
|
|
9
11
|
close(): Promise<void>;
|
|
10
12
|
createChannel(name: string, serverID: string): Promise<Channel>;
|
|
@@ -32,6 +34,7 @@ export declare class Database extends EventEmitter {
|
|
|
32
34
|
isHealthy(): Promise<boolean>;
|
|
33
35
|
markDeviceLogin(device: Device): Promise<void>;
|
|
34
36
|
markUserSeen(user: UserRecord): Promise<void>;
|
|
37
|
+
rehashPassword(userID: string, newHash: string): Promise<void>;
|
|
35
38
|
/**
|
|
36
39
|
* Retrives a list of users that should be notified when a specific resourceID
|
|
37
40
|
* experiences changes.
|
|
@@ -54,11 +57,28 @@ export declare class Database extends EventEmitter {
|
|
|
54
57
|
retrieveServer(serverID: string): Promise<null | Server>;
|
|
55
58
|
retrieveServerInvites(serverID: string): Promise<Invite[]>;
|
|
56
59
|
retrieveServers(userID: string): Promise<Server[]>;
|
|
57
|
-
retrieveUser(userIdentifier: string): Promise<
|
|
60
|
+
retrieveUser(userIdentifier: string): Promise<InternalUserRecord | null>;
|
|
58
61
|
retrieveUserDeviceList(userIDs: string[]): Promise<Device[]>;
|
|
59
|
-
retrieveUsers(): Promise<
|
|
62
|
+
retrieveUsers(): Promise<InternalUserRecord[]>;
|
|
60
63
|
saveMail(mail: MailWS, header: Uint8Array, deviceID: string, userID: string): Promise<void>;
|
|
61
64
|
saveOTK(userID: string, deviceID: string, otks: PreKeysWS[]): Promise<void>;
|
|
62
65
|
private init;
|
|
63
66
|
}
|
|
64
|
-
|
|
67
|
+
/**
|
|
68
|
+
* Hash a password with Argon2id (new default).
|
|
69
|
+
* Returns the encoded hash string which embeds salt, params, and digest.
|
|
70
|
+
*/
|
|
71
|
+
export declare function hashPasswordArgon2(password: string): Promise<string>;
|
|
72
|
+
/**
|
|
73
|
+
* Verify a password against either Argon2id or legacy PBKDF2 storage.
|
|
74
|
+
* Returns `{ valid, needsRehash }` — callers should rehash on success
|
|
75
|
+
* when `needsRehash` is true.
|
|
76
|
+
*/
|
|
77
|
+
export declare function verifyPassword(password: string, stored: {
|
|
78
|
+
hashAlgo: string;
|
|
79
|
+
passwordHash: string;
|
|
80
|
+
passwordSalt: string;
|
|
81
|
+
}): Promise<{
|
|
82
|
+
needsRehash: boolean;
|
|
83
|
+
valid: boolean;
|
|
84
|
+
}>;
|
package/dist/Database.js
CHANGED
|
@@ -11,8 +11,9 @@ import { pbkdf2Sync } from "node:crypto";
|
|
|
11
11
|
import * as fs from "node:fs/promises";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
14
|
-
import {
|
|
14
|
+
import { XUtils } from "@vex-chat/crypto";
|
|
15
15
|
import { MailType } from "@vex-chat/types";
|
|
16
|
+
import argon2 from "argon2";
|
|
16
17
|
/**
|
|
17
18
|
* Narrow a plain integer from the `mailType` SQL column to the
|
|
18
19
|
* `MailType` union (0 = initial, 1 = subsequent). Throws if the
|
|
@@ -30,7 +31,6 @@ function parseMailType(n) {
|
|
|
30
31
|
import BetterSqlite3 from "better-sqlite3";
|
|
31
32
|
import { Kysely, Migrator, sql, SqliteDialect } from "kysely";
|
|
32
33
|
import { stringify as uuidStringify, validate as uuidValidate } from "uuid";
|
|
33
|
-
import { createLogger } from "./utils/createLogger.js";
|
|
34
34
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
35
35
|
const migrationFolder = path.join(__dirname, "migrations");
|
|
36
36
|
/**
|
|
@@ -80,16 +80,12 @@ function isMigration(mod) {
|
|
|
80
80
|
typeof mod.up === "function");
|
|
81
81
|
}
|
|
82
82
|
const pubkeyRegex = /[0-9a-f]{64}/;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// SQLite stores booleans as integers and dates as strings, but the
|
|
86
|
-
// @vex-chat/types interfaces expect boolean / Date.
|
|
83
|
+
/** Legacy iteration count kept only for verifying old PBKDF2 hashes. */
|
|
84
|
+
const PBKDF2_ITERATIONS = 1000;
|
|
87
85
|
export class Database extends EventEmitter {
|
|
88
86
|
db;
|
|
89
|
-
log;
|
|
90
87
|
constructor(options) {
|
|
91
88
|
super();
|
|
92
|
-
this.log = createLogger("spire-db", options?.logLevel || "error");
|
|
93
89
|
const dbType = options?.dbType || "sqlite3";
|
|
94
90
|
let filename;
|
|
95
91
|
switch (dbType) {
|
|
@@ -117,7 +113,6 @@ export class Database extends EventEmitter {
|
|
|
117
113
|
void this.init();
|
|
118
114
|
}
|
|
119
115
|
async close() {
|
|
120
|
-
this.log.info("Closing database.");
|
|
121
116
|
await this.db.destroy();
|
|
122
117
|
}
|
|
123
118
|
async createChannel(name, serverID) {
|
|
@@ -211,12 +206,11 @@ export class Database extends EventEmitter {
|
|
|
211
206
|
}
|
|
212
207
|
async createUser(regKey, regPayload) {
|
|
213
208
|
try {
|
|
214
|
-
const
|
|
215
|
-
const passwordHash = hashPassword(regPayload.password, salt);
|
|
209
|
+
const passwordHash = await hashPasswordArgon2(regPayload.password);
|
|
216
210
|
const user = {
|
|
217
211
|
lastSeen: new Date().toISOString(),
|
|
218
|
-
passwordHash
|
|
219
|
-
passwordSalt:
|
|
212
|
+
passwordHash,
|
|
213
|
+
passwordSalt: "",
|
|
220
214
|
userID: uuidStringify(regKey),
|
|
221
215
|
username: regPayload.username,
|
|
222
216
|
};
|
|
@@ -224,6 +218,7 @@ export class Database extends EventEmitter {
|
|
|
224
218
|
.insertInto("users")
|
|
225
219
|
.values({
|
|
226
220
|
...user,
|
|
221
|
+
hashAlgo: "argon2id",
|
|
227
222
|
lastSeen: user.lastSeen,
|
|
228
223
|
})
|
|
229
224
|
.execute();
|
|
@@ -401,8 +396,8 @@ export class Database extends EventEmitter {
|
|
|
401
396
|
await sql `select 1 as ok`.execute(this.db);
|
|
402
397
|
return true;
|
|
403
398
|
}
|
|
404
|
-
catch (
|
|
405
|
-
|
|
399
|
+
catch (_err) {
|
|
400
|
+
// debugger: health check failed
|
|
406
401
|
return false;
|
|
407
402
|
}
|
|
408
403
|
}
|
|
@@ -420,6 +415,17 @@ export class Database extends EventEmitter {
|
|
|
420
415
|
.where("userID", "=", user.userID)
|
|
421
416
|
.execute();
|
|
422
417
|
}
|
|
418
|
+
async rehashPassword(userID, newHash) {
|
|
419
|
+
await this.db
|
|
420
|
+
.updateTable("users")
|
|
421
|
+
.set({
|
|
422
|
+
hashAlgo: "argon2id",
|
|
423
|
+
passwordHash: newHash,
|
|
424
|
+
passwordSalt: "",
|
|
425
|
+
})
|
|
426
|
+
.where("userID", "=", userID)
|
|
427
|
+
.execute();
|
|
428
|
+
}
|
|
423
429
|
/**
|
|
424
430
|
* Retrives a list of users that should be notified when a specific resourceID
|
|
425
431
|
* experiences changes.
|
|
@@ -708,6 +714,39 @@ export class Database extends EventEmitter {
|
|
|
708
714
|
this.emit("ready");
|
|
709
715
|
}
|
|
710
716
|
}
|
|
717
|
+
/**
|
|
718
|
+
* Hash a password with Argon2id (new default).
|
|
719
|
+
* Returns the encoded hash string which embeds salt, params, and digest.
|
|
720
|
+
*/
|
|
721
|
+
export async function hashPasswordArgon2(password) {
|
|
722
|
+
return argon2.hash(password, {
|
|
723
|
+
memoryCost: 65536,
|
|
724
|
+
parallelism: 4,
|
|
725
|
+
timeCost: 3,
|
|
726
|
+
type: argon2.argon2id,
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Verify a password against either Argon2id or legacy PBKDF2 storage.
|
|
731
|
+
* Returns `{ valid, needsRehash }` — callers should rehash on success
|
|
732
|
+
* when `needsRehash` is true.
|
|
733
|
+
*/
|
|
734
|
+
export async function verifyPassword(password, stored) {
|
|
735
|
+
if (stored.hashAlgo === "argon2id") {
|
|
736
|
+
const valid = await argon2.verify(stored.passwordHash, password);
|
|
737
|
+
return { needsRehash: false, valid };
|
|
738
|
+
}
|
|
739
|
+
// Legacy PBKDF2 path
|
|
740
|
+
const salt = XUtils.decodeHex(stored.passwordSalt);
|
|
741
|
+
const computed = pbkdf2Sync(password, salt, PBKDF2_ITERATIONS, 32, "sha512");
|
|
742
|
+
const storedBuf = XUtils.decodeHex(stored.passwordHash);
|
|
743
|
+
if (computed.length !== storedBuf.length) {
|
|
744
|
+
return { needsRehash: false, valid: false };
|
|
745
|
+
}
|
|
746
|
+
const { timingSafeEqual } = await import("node:crypto");
|
|
747
|
+
const valid = timingSafeEqual(computed, storedBuf);
|
|
748
|
+
return { needsRehash: valid, valid };
|
|
749
|
+
}
|
|
711
750
|
function toDevice(row) {
|
|
712
751
|
return { ...row, deleted: Boolean(row.deleted) };
|
|
713
752
|
}
|
|
@@ -730,5 +769,4 @@ function toServer(row) {
|
|
|
730
769
|
function toUserRecord(row) {
|
|
731
770
|
return { ...row };
|
|
732
771
|
}
|
|
733
|
-
export const hashPassword = (password, salt) => pbkdf2Sync(password, salt, ITERATIONS, 32, "sha512");
|
|
734
772
|
//# sourceMappingURL=Database.js.map
|