@vex-chat/spire 1.3.6 → 1.4.0

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.
@@ -39,13 +39,105 @@ export function createPendingDeviceEnrollmentRequest(userID, devicePayload, noti
39
39
  requestID,
40
40
  status: "pending",
41
41
  });
42
+ // We include the existing user's `userID` so the new (still-
43
+ // unauthenticated) device can fetch its public avatar from the
44
+ // unauthenticated `/avatar/:userID` endpoint and surface an "is
45
+ // this you?" confirmation before continuing with the approval
46
+ // request. The userID is already implicit (the requester typed the
47
+ // username and learned the account exists from this very response),
48
+ // so returning it here doesn't expand the attack surface.
42
49
  return {
43
50
  challenge: challengeHex,
44
51
  expiresAt: new Date(pending.createdAt + DEVICE_REQUEST_TTL_MS).toISOString(),
45
52
  requestID,
46
53
  status: "pending_approval",
54
+ userID,
47
55
  };
48
56
  }
57
+ /**
58
+ * Reusable approve/reject side of a pending device-enrollment
59
+ * request. Lives here so both the device-authenticated router
60
+ * (signs an approval challenge with the approving device's
61
+ * Ed25519 key) and the passkey-authenticated router (relies on
62
+ * the freshness of the passkey JWT instead) can share the same
63
+ * state-machine + enrollment lifecycle.
64
+ *
65
+ * The device-auth caller is expected to have already verified the
66
+ * approving device's signature before invoking this helper.
67
+ */
68
+ export async function resolveDeviceEnrollmentRequest(args) {
69
+ pruneDeviceEnrollmentRequests();
70
+ const pending = deviceEnrollments.get(args.requestID);
71
+ if (!pending || pending.userID !== args.userID) {
72
+ return { error: "Request not found.", kind: "err", status: 404 };
73
+ }
74
+ if (pending.status !== "pending") {
75
+ return {
76
+ error: "Request is not pending.",
77
+ kind: "err",
78
+ status: 409,
79
+ };
80
+ }
81
+ if (Date.now() - pending.createdAt > DEVICE_REQUEST_TTL_MS) {
82
+ pending.status = "expired";
83
+ pending.resolvedAt = Date.now();
84
+ pending.error = "Request expired.";
85
+ deviceEnrollments.set(args.requestID, pending);
86
+ return { error: "Request expired.", kind: "err", status: 410 };
87
+ }
88
+ if (args.action === "reject") {
89
+ pending.status = "rejected";
90
+ pending.resolvedAt = Date.now();
91
+ pending.error = "Rejected.";
92
+ deviceEnrollments.set(args.requestID, pending);
93
+ args.notify(args.userID, "deviceRequest", crypto.randomUUID(), {
94
+ requestID: args.requestID,
95
+ status: "rejected",
96
+ });
97
+ // Caller maps `kind: "ok"` without device to a 200; reuse the
98
+ // ok shape with a placeholder device since the type insists
99
+ // on one. The reject flow doesn't return a body, the caller
100
+ // discards `device`.
101
+ return {
102
+ device: {
103
+ deleted: false,
104
+ deviceID: "",
105
+ lastLogin: "",
106
+ name: "",
107
+ owner: args.userID,
108
+ signKey: "",
109
+ },
110
+ kind: "ok",
111
+ };
112
+ }
113
+ try {
114
+ const device = await args.db.createDevice(args.userID, pending.devicePayload);
115
+ pending.status = "approved";
116
+ pending.approvedDeviceID = device.deviceID;
117
+ pending.resolvedAt = Date.now();
118
+ deviceEnrollments.set(args.requestID, pending);
119
+ args.notify(args.userID, "deviceRequest", crypto.randomUUID(), {
120
+ requestID: args.requestID,
121
+ status: "approved",
122
+ });
123
+ return { device, kind: "ok" };
124
+ }
125
+ catch {
126
+ pending.status = "rejected";
127
+ pending.error = "Could not create approved device.";
128
+ pending.resolvedAt = Date.now();
129
+ deviceEnrollments.set(args.requestID, pending);
130
+ args.notify(args.userID, "deviceRequest", crypto.randomUUID(), {
131
+ requestID: args.requestID,
132
+ status: "rejected",
133
+ });
134
+ return {
135
+ error: "Could not create approved device.",
136
+ kind: "err",
137
+ status: 470,
138
+ };
139
+ }
140
+ }
49
141
  function buildApprovalChallenge(requestID, signKey) {
50
142
  return XUtils.decodeUTF8(`${requestID}:${signKey.toLowerCase()}`);
51
143
  }
@@ -1 +1 @@
1
- {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/server/user.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/server/user.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,16 @@ declare global {
18
18
  bearerToken?: string;
19
19
  device?: Device;
20
20
  exp?: number;
21
+ /**
22
+ * Set by `checkPasskey` middleware when the bearer token is
23
+ * a passkey-scoped JWT. The presence of `req.passkey`
24
+ * (without `req.device`) marks an admin-only request that
25
+ * may list/delete devices and approve enrollments, but
26
+ * cannot send mail or do anything device-specific.
27
+ */
28
+ passkey?: {
29
+ passkeyID: string;
30
+ };
21
31
  user?: User;
22
32
  }
23
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/types/express.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/types/express.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgCH,OAAO,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vex-chat/spire",
3
- "version": "1.3.6",
3
+ "version": "1.4.0",
4
4
  "description": "Vex server implementation in NodeJS.",
5
5
  "type": "module",
6
6
  "files": [
@@ -55,8 +55,8 @@
55
55
  "typescript": "6.0.2",
56
56
  "typescript-eslint": "8.58.1",
57
57
  "vitest": "4.1.4",
58
- "@vex-chat/eslint-config": "0.0.1",
59
- "@vex-chat/libvex": "^6.1.8"
58
+ "@vex-chat/libvex": "^6.2.0",
59
+ "@vex-chat/eslint-config": "0.0.1"
60
60
  },
61
61
  "typeCoverage": {
62
62
  "atLeast": 95,
@@ -65,6 +65,7 @@
65
65
  "dependencies": {
66
66
  "@asyncapi/web-component": "2.6.5",
67
67
  "@scalar/express-api-reference": "0.9.7",
68
+ "@simplewebauthn/server": "^13.3.0",
68
69
  "argon2": "0.44.0",
69
70
  "better-sqlite3": "11.10.0",
70
71
  "cors": "2.8.6",
@@ -83,8 +84,8 @@
83
84
  "uuid": "^14.0.0",
84
85
  "ws": "8.20.0",
85
86
  "zod": "^4.3.6",
86
- "@vex-chat/types": "^3.1.0",
87
- "@vex-chat/crypto": "^4.0.1"
87
+ "@vex-chat/types": "^3.2.0",
88
+ "@vex-chat/crypto": "^5.0.0"
88
89
  },
89
90
  "scripts": {
90
91
  "rebuild:sqlite": "pnpm rebuild better-sqlite3",
package/src/Database.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Commercial licenses available at vex.wtf
5
5
  */
6
6
 
7
- import type { ServerDatabase } from "./db/schema.ts";
7
+ import type { PasskeyRow, ServerDatabase } from "./db/schema.ts";
8
8
  import type { SpireOptions } from "./Spire.ts";
9
9
  import type {
10
10
  Channel,
@@ -16,6 +16,7 @@ import type {
16
16
  KeyBundle,
17
17
  MailSQL,
18
18
  MailWS,
19
+ Passkey,
19
20
  Permission,
20
21
  PreKeysSQL,
21
22
  PreKeysWS,
@@ -253,6 +254,50 @@ export class Database extends EventEmitter {
253
254
  return invite;
254
255
  }
255
256
 
257
+ /**
258
+ * Insert a new passkey for `userID`. Caller is responsible for
259
+ * having verified the WebAuthn attestation and serialised the
260
+ * credential public key as hex (typically the COSE_Key bytes
261
+ * returned by the authenticator). Returns the public passkey
262
+ * shape — never the credentialID/publicKey/algorithm internals,
263
+ * which stay server-private.
264
+ */
265
+ public async createPasskey(
266
+ userID: string,
267
+ name: string,
268
+ credentialID: string,
269
+ publicKeyHex: string,
270
+ algorithm: number,
271
+ transports: string[],
272
+ ): Promise<Passkey> {
273
+ const passkeyID = crypto.randomUUID();
274
+ const createdAt = new Date().toISOString();
275
+ await this.db
276
+ .insertInto("passkeys")
277
+ .values({
278
+ algorithm,
279
+ createdAt,
280
+ credentialID,
281
+ lastUsedAt: null,
282
+ name,
283
+ passkeyID,
284
+ publicKey: publicKeyHex,
285
+ signCount: 0,
286
+ transports: transports.join(","),
287
+ userID,
288
+ })
289
+ .execute();
290
+
291
+ return {
292
+ createdAt,
293
+ lastUsedAt: null,
294
+ name,
295
+ passkeyID,
296
+ transports,
297
+ userID,
298
+ };
299
+ }
300
+
256
301
  public async createPermission(
257
302
  userID: string,
258
303
  resourceType: string,
@@ -405,6 +450,13 @@ export class Database extends EventEmitter {
405
450
  .execute();
406
451
  }
407
452
 
453
+ public async deletePasskey(passkeyID: string): Promise<void> {
454
+ await this.db
455
+ .deleteFrom("passkeys")
456
+ .where("passkeyID", "=", passkeyID)
457
+ .execute();
458
+ }
459
+
408
460
  public async deletePermission(permissionID: string): Promise<void> {
409
461
  await this.db
410
462
  .deleteFrom("permissions")
@@ -620,6 +672,26 @@ export class Database extends EventEmitter {
620
672
  .execute();
621
673
  }
622
674
 
675
+ /**
676
+ * Bump the WebAuthn signature counter and lastUsedAt timestamp
677
+ * after a successful assertion. The counter is monotonic per the
678
+ * WebAuthn spec (FIDO authenticators that report 0 signal they
679
+ * don't track a counter — callers should treat 0→0 as legitimate).
680
+ */
681
+ public async markPasskeyUsed(
682
+ passkeyID: string,
683
+ signCount: number,
684
+ ): Promise<void> {
685
+ await this.db
686
+ .updateTable("passkeys")
687
+ .set({
688
+ lastUsedAt: new Date().toISOString(),
689
+ signCount,
690
+ })
691
+ .where("passkeyID", "=", passkeyID)
692
+ .execute();
693
+ }
694
+
623
695
  public async markUserSeen(user: UserRecord): Promise<void> {
624
696
  await this.db
625
697
  .updateTable("users")
@@ -819,6 +891,53 @@ export class Database extends EventEmitter {
819
891
  return allMail;
820
892
  }
821
893
 
894
+ /**
895
+ * Look up a passkey row by its WebAuthn credentialID. Used during
896
+ * the assertion verification step of `/auth/passkey/finish`.
897
+ */
898
+ public async retrievePasskeyByCredentialID(
899
+ credentialID: string,
900
+ ): Promise<null | PasskeyRow> {
901
+ const rows = await this.db
902
+ .selectFrom("passkeys")
903
+ .selectAll()
904
+ .where("credentialID", "=", credentialID)
905
+ .limit(1)
906
+ .execute();
907
+ return rows[0] ?? null;
908
+ }
909
+
910
+ /**
911
+ * Look up a passkey row including server-only fields (publicKey,
912
+ * algorithm, signCount). For listing back to clients prefer
913
+ * {@link retrievePasskeysByUser}, which only returns the public
914
+ * shape.
915
+ */
916
+ public async retrievePasskeyInternal(
917
+ passkeyID: string,
918
+ ): Promise<null | PasskeyRow> {
919
+ const rows = await this.db
920
+ .selectFrom("passkeys")
921
+ .selectAll()
922
+ .where("passkeyID", "=", passkeyID)
923
+ .limit(1)
924
+ .execute();
925
+ return rows[0] ?? null;
926
+ }
927
+
928
+ /**
929
+ * List all passkeys belonging to `userID` in their public form
930
+ * (no key material).
931
+ */
932
+ public async retrievePasskeysByUser(userID: string): Promise<Passkey[]> {
933
+ const rows = await this.db
934
+ .selectFrom("passkeys")
935
+ .selectAll()
936
+ .where("userID", "=", userID)
937
+ .execute();
938
+ return rows.map(toPasskey);
939
+ }
940
+
822
941
  public async retrievePermission(
823
942
  permissionID: string,
824
943
  ): Promise<null | Permission> {
@@ -1133,6 +1252,20 @@ function toMailSQL(row: {
1133
1252
  };
1134
1253
  }
1135
1254
 
1255
+ function toPasskey(row: PasskeyRow): Passkey {
1256
+ return {
1257
+ createdAt: row.createdAt,
1258
+ lastUsedAt: row.lastUsedAt,
1259
+ name: row.name,
1260
+ passkeyID: row.passkeyID,
1261
+ transports:
1262
+ row.transports.length > 0
1263
+ ? row.transports.split(",").filter((s) => s.length > 0)
1264
+ : [],
1265
+ userID: row.userID,
1266
+ };
1267
+ }
1268
+
1136
1269
  function toServer(row: {
1137
1270
  icon: null | string;
1138
1271
  name: string;
package/src/Spire.ts CHANGED
@@ -52,6 +52,13 @@ import { spireXSignOpenAsync } from "./utils/spireXSignOpenAsync.ts";
52
52
  export const TOKEN_EXPIRY = 1000 * 60 * 10;
53
53
  export const JWT_EXPIRY = "7d";
54
54
  export const DEVICE_AUTH_JWT_EXPIRY = "7d";
55
+ /**
56
+ * Passkey-scoped JWTs grant destructive admin powers (delete a
57
+ * device, approve a device enrollment) without further user
58
+ * verification, so they expire fast — the user re-does the
59
+ * WebAuthn ceremony on each session.
60
+ */
61
+ export const JWT_EXPIRY_PASSKEY = "5m";
55
62
  const DEVICE_CHALLENGE_EXPIRY = 1000 * 60; // 60 seconds
56
63
 
57
64
  // 3-19 chars long
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Copyright (c) 2020-2026 Vex Heavy Industries LLC
3
+ * Licensed under AGPL-3.0. See LICENSE for details.
4
+ * Commercial licenses available at vex.wtf
5
+ */
6
+
7
+ import type { SpireOptions } from "../Spire.ts";
8
+
9
+ import { describe, expect, it, vi } from "vitest";
10
+
11
+ import { Database } from "../Database.ts";
12
+
13
+ vi.mock("uuid", () => ({
14
+ parse: (s: string) => {
15
+ const matches = s.replace(/-/g, "").match(/.{2}/g);
16
+ if (!matches) throw new Error("Invalid UUID");
17
+ return Uint8Array.from(matches.map((b) => parseInt(b, 16)));
18
+ },
19
+ stringify: (b: Uint8Array) => {
20
+ const hex = Array.from(b)
21
+ .map((x) => x.toString(16).padStart(2, "0"))
22
+ .join("");
23
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
24
+ },
25
+ v4: vi.fn(() => "93ce482b-a0f2-4f6e-b1df-3aed61073552"),
26
+ validate: () => true,
27
+ }));
28
+
29
+ const options: SpireOptions = {
30
+ dbType: "sqlite3mem",
31
+ };
32
+
33
+ const userID = "4e67b90f-cbf8-44bc-8ce3-d3b248f033f1";
34
+
35
+ const samplePasskey = {
36
+ algorithm: -7,
37
+ credentialID: "credential-id-base64url",
38
+ name: "Yubikey 5C",
39
+ publicKeyHex:
40
+ "30c2d0294c1cfdbb73c6b3bbe6010088c2dba8384b04ff2e2b92172431d66b5e",
41
+ transports: ["usb", "nfc"],
42
+ };
43
+
44
+ async function withDb<T>(fn: (db: Database) => Promise<T>): Promise<T> {
45
+ const provider = new Database(options);
46
+ return new Promise<T>((resolve, reject) => {
47
+ provider.once("ready", () => {
48
+ void (async () => {
49
+ try {
50
+ const result = await fn(provider);
51
+ await provider.close();
52
+ resolve(result);
53
+ } catch (e: unknown) {
54
+ await provider.close().catch(() => {
55
+ // best-effort cleanup; ignore close failures here
56
+ // so we surface the original error instead.
57
+ });
58
+ reject(e instanceof Error ? e : new Error(String(e)));
59
+ }
60
+ })();
61
+ });
62
+ });
63
+ }
64
+
65
+ describe("Database passkeys", () => {
66
+ describe("createPasskey", () => {
67
+ it("inserts a passkey and returns the public shape (no key material)", async () => {
68
+ expect.assertions(7);
69
+ await withDb(async (db) => {
70
+ const created = await db.createPasskey(
71
+ userID,
72
+ samplePasskey.name,
73
+ samplePasskey.credentialID,
74
+ samplePasskey.publicKeyHex,
75
+ samplePasskey.algorithm,
76
+ samplePasskey.transports,
77
+ );
78
+
79
+ expect(created.userID).toBe(userID);
80
+ expect(created.name).toBe(samplePasskey.name);
81
+ expect(created.transports).toEqual(samplePasskey.transports);
82
+ expect(created.lastUsedAt).toBeNull();
83
+ expect(typeof created.passkeyID).toBe("string");
84
+ expect(created.passkeyID.length).toBeGreaterThan(0);
85
+ // Internal fields should NOT be on the public shape
86
+ expect(
87
+ (created as unknown as Record<string, unknown>)[
88
+ "publicKey"
89
+ ],
90
+ ).toBeUndefined();
91
+ });
92
+ });
93
+ });
94
+
95
+ describe("retrievePasskeyByCredentialID", () => {
96
+ it("returns the row including key material when looked up by credentialID", async () => {
97
+ expect.assertions(4);
98
+ await withDb(async (db) => {
99
+ await db.createPasskey(
100
+ userID,
101
+ samplePasskey.name,
102
+ samplePasskey.credentialID,
103
+ samplePasskey.publicKeyHex,
104
+ samplePasskey.algorithm,
105
+ samplePasskey.transports,
106
+ );
107
+
108
+ const row = await db.retrievePasskeyByCredentialID(
109
+ samplePasskey.credentialID,
110
+ );
111
+
112
+ expect(row).not.toBeNull();
113
+ if (row === null) return;
114
+ expect(row.publicKey).toBe(samplePasskey.publicKeyHex);
115
+ expect(row.algorithm).toBe(samplePasskey.algorithm);
116
+ expect(row.signCount).toBe(0);
117
+ });
118
+ });
119
+
120
+ it("returns null for an unknown credentialID", async () => {
121
+ expect.assertions(1);
122
+ await withDb(async (db) => {
123
+ const row =
124
+ await db.retrievePasskeyByCredentialID("does-not-exist");
125
+ expect(row).toBeNull();
126
+ });
127
+ });
128
+ });
129
+
130
+ describe("retrievePasskeysByUser", () => {
131
+ it("returns all passkeys for the user in public shape", async () => {
132
+ expect.assertions(3);
133
+ await withDb(async (db) => {
134
+ await db.createPasskey(
135
+ userID,
136
+ "yubikey",
137
+ "cred-1",
138
+ samplePasskey.publicKeyHex,
139
+ -7,
140
+ ["usb"],
141
+ );
142
+ await db.createPasskey(
143
+ userID,
144
+ "iCloud",
145
+ "cred-2",
146
+ samplePasskey.publicKeyHex,
147
+ -7,
148
+ [],
149
+ );
150
+
151
+ const list = await db.retrievePasskeysByUser(userID);
152
+ expect(list).toHaveLength(2);
153
+ const names = list.map((p) => p.name).sort();
154
+ expect(names).toEqual(["iCloud", "yubikey"]);
155
+ // empty transports column should decode to []
156
+ const icloud = list.find((p) => p.name === "iCloud");
157
+ expect(icloud?.transports).toEqual([]);
158
+ });
159
+ });
160
+
161
+ it("returns an empty array for users with no passkeys", async () => {
162
+ expect.assertions(1);
163
+ await withDb(async (db) => {
164
+ const list = await db.retrievePasskeysByUser(userID);
165
+ expect(list).toEqual([]);
166
+ });
167
+ });
168
+ });
169
+
170
+ describe("markPasskeyUsed", () => {
171
+ it("bumps the signature counter and lastUsedAt timestamp", async () => {
172
+ expect.assertions(3);
173
+ await withDb(async (db) => {
174
+ const created = await db.createPasskey(
175
+ userID,
176
+ samplePasskey.name,
177
+ samplePasskey.credentialID,
178
+ samplePasskey.publicKeyHex,
179
+ samplePasskey.algorithm,
180
+ samplePasskey.transports,
181
+ );
182
+
183
+ await db.markPasskeyUsed(created.passkeyID, 42);
184
+ const row = await db.retrievePasskeyInternal(created.passkeyID);
185
+
186
+ expect(row).not.toBeNull();
187
+ if (row === null) return;
188
+ expect(row.signCount).toBe(42);
189
+ expect(row.lastUsedAt).not.toBeNull();
190
+ });
191
+ });
192
+ });
193
+
194
+ describe("deletePasskey", () => {
195
+ it("removes the passkey row", async () => {
196
+ expect.assertions(2);
197
+ await withDb(async (db) => {
198
+ const created = await db.createPasskey(
199
+ userID,
200
+ samplePasskey.name,
201
+ samplePasskey.credentialID,
202
+ samplePasskey.publicKeyHex,
203
+ samplePasskey.algorithm,
204
+ samplePasskey.transports,
205
+ );
206
+
207
+ await db.deletePasskey(created.passkeyID);
208
+
209
+ const row = await db.retrievePasskeyInternal(created.passkeyID);
210
+ expect(row).toBeNull();
211
+
212
+ const list = await db.retrievePasskeysByUser(userID);
213
+ expect(list).toEqual([]);
214
+ });
215
+ });
216
+ });
217
+ });