@vex-chat/spire 4.1.1 → 5.0.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.
@@ -7,13 +7,11 @@
7
7
  import { describe, expect, it } from "vitest";
8
8
 
9
9
  import {
10
- isSpireFipsEnabled,
11
10
  normalizeEnvValue,
12
11
  validateSpireRuntimeEnv,
13
12
  } from "../utils/loadEnv.ts";
14
13
 
15
14
  const TWEETNACL_SPK = "ab".repeat(64);
16
- const FIPS_SPK = "cd".repeat(90);
17
15
  const JWT_SECRET = "ef".repeat(32);
18
16
 
19
17
  describe("normalizeEnvValue", () => {
@@ -30,22 +28,11 @@ describe("normalizeEnvValue", () => {
30
28
  });
31
29
  });
32
30
 
33
- describe("isSpireFipsEnabled", () => {
34
- it("accepts true and 1 only", () => {
35
- expect(isSpireFipsEnabled("true")).toBe(true);
36
- expect(isSpireFipsEnabled('"true"')).toBe(true);
37
- expect(isSpireFipsEnabled("1")).toBe(true);
38
- expect(isSpireFipsEnabled("false")).toBe(false);
39
- expect(isSpireFipsEnabled(undefined)).toBe(false);
40
- });
41
- });
42
-
43
31
  describe("validateSpireRuntimeEnv", () => {
44
32
  it("accepts quoted compose-safe tweetnacl keys", () => {
45
33
  expect(() => {
46
34
  validateSpireRuntimeEnv({
47
35
  JWT_SECRET: `"${JWT_SECRET}"`,
48
- SPIRE_FIPS: "false",
49
36
  SPK: `"${TWEETNACL_SPK}"`,
50
37
  });
51
38
  }).not.toThrow();
@@ -60,22 +47,11 @@ describe("validateSpireRuntimeEnv", () => {
60
47
  }).toThrow(/SPK must be an even-length hex string/);
61
48
  });
62
49
 
63
- it("rejects a FIPS flag with a tweetnacl-sized SPK", () => {
64
- expect(() => {
65
- validateSpireRuntimeEnv({
66
- JWT_SECRET,
67
- SPIRE_FIPS: "true",
68
- SPK: TWEETNACL_SPK,
69
- });
70
- }).toThrow(/requires an SPK from .*gen-spk-fips/);
71
- });
72
-
73
- it("rejects a FIPS-sized SPK without the FIPS flag", () => {
50
+ it("rejects an SPK with the wrong length", () => {
74
51
  expect(() => {
75
52
  validateSpireRuntimeEnv({
76
53
  JWT_SECRET,
77
- SPIRE_FIPS: "false",
78
- SPK: FIPS_SPK,
54
+ SPK: "cd".repeat(90),
79
55
  });
80
56
  }).toThrow(/SPK must be 128 hex characters/);
81
57
  });
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  import {
8
- setCryptoProfile,
9
8
  xBoxKeyPairAsync,
10
9
  xPreKeySignaturePayload,
11
10
  xSignAsync,
@@ -13,7 +12,7 @@ import {
13
12
  XUtils,
14
13
  } from "@vex-chat/crypto";
15
14
 
16
- import { beforeEach, describe, expect, it } from "vitest";
15
+ import { describe, expect, it } from "vitest";
17
16
 
18
17
  import {
19
18
  verifyDevicePayloadPreKeySignature,
@@ -31,10 +30,6 @@ async function makeSignedPreKey() {
31
30
  }
32
31
 
33
32
  describe("prekey signature validation", () => {
34
- beforeEach(() => {
35
- setCryptoProfile("tweetnacl");
36
- });
37
-
38
33
  it("accepts a prekey signed by the device signing key", async () => {
39
34
  const { preKey, signature, signKeys } = await makeSignedPreKey();
40
35
 
@@ -12,7 +12,7 @@ import {
12
12
  } from "../spireListenPort.ts";
13
13
 
14
14
  describe("resolveSpireListenPort", () => {
15
- it("uses default for tweetnacl and fips when no explicit port", () => {
15
+ it("uses the default when no explicit port is provided", () => {
16
16
  expect(resolveSpireListenPort(undefined)).toBe(DEFAULT_SPIRE_API_PORT);
17
17
  });
18
18
 
package/src/run.ts CHANGED
@@ -9,7 +9,7 @@ import type { SpireOptions } from "./Spire.ts";
9
9
  import { Spire } from "./Spire.ts";
10
10
  import { loadEnv } from "./utils/loadEnv.ts";
11
11
 
12
- async function main() {
12
+ function main() {
13
13
  // load the environment variables — loadEnv() exits if required vars are missing
14
14
  loadEnv();
15
15
 
@@ -29,21 +29,12 @@ async function main() {
29
29
  }
30
30
  }
31
31
  const dbType = parseDbType(process.env["DB_TYPE"]);
32
- const fips =
33
- process.env["SPIRE_FIPS"] === "1" ||
34
- process.env["SPIRE_FIPS"] === "true";
35
-
36
32
  const options: SpireOptions = {
37
33
  ...(apiPort !== undefined ? { apiPort } : {}),
38
34
  ...(dbType !== undefined ? { dbType } : {}),
39
- ...(fips ? { cryptoProfile: "fips" } : {}),
40
35
  };
41
36
 
42
- if (fips) {
43
- await Spire.createAsync(spk, options);
44
- } else {
45
- new Spire(spk, options);
46
- }
37
+ new Spire(spk, options);
47
38
  }
48
39
 
49
40
  function parseDbType(value: string | undefined): SpireOptions["dbType"] {
@@ -58,7 +49,9 @@ function parseDbType(value: string | undefined): SpireOptions["dbType"] {
58
49
  }
59
50
  }
60
51
 
61
- void main().catch((err: unknown) => {
52
+ try {
53
+ main();
54
+ } catch (err: unknown) {
62
55
  console.error(err);
63
56
  process.exit(1);
64
- });
57
+ }
@@ -5,8 +5,7 @@
5
5
  */
6
6
 
7
7
  /**
8
- * Default HTTP/WS port for the Spire API (tweetnacl and FIPS), unless
9
- * `API_PORT` / `apiPort` is set. Clients can tell profiles apart via `GET /status`.
8
+ * Default HTTP/WS port for the Spire API unless `API_PORT` / `apiPort` is set.
10
9
  */
11
10
  export const DEFAULT_SPIRE_API_PORT = 16777;
12
11
 
@@ -11,7 +11,6 @@ const NORMALIZED_ENV_VARS = [
11
11
  ...REQUIRED_ENV_VARS,
12
12
  "API_PORT",
13
13
  "SPIRE_TRUST_PROXY_HOPS",
14
- "SPIRE_FIPS",
15
14
  "SPIRE_PASSKEY_RP_ID",
16
15
  "SPIRE_PASSKEY_RP_NAME",
17
16
  "SPIRE_PASSKEY_ORIGINS",
@@ -22,11 +21,6 @@ const NORMALIZED_ENV_VARS = [
22
21
  const HEX_BYTES_RE = /^(?:[0-9a-fA-F]{2})+$/;
23
22
  const TWEETNACL_SPK_HEX_LENGTH = 128;
24
23
 
25
- export function isSpireFipsEnabled(value: string | undefined): boolean {
26
- const normalized = value == null ? "" : normalizeEnvValue(value);
27
- return normalized === "1" || normalized === "true";
28
- }
29
-
30
24
  /* Populate process.env with vars from .env and verify required vars are present. */
31
25
  export function loadEnv(): void {
32
26
  config();
@@ -62,25 +56,19 @@ export function validateSpireRuntimeEnv(
62
56
  const jwtSecret = normalizeEnvValue(env["JWT_SECRET"] ?? "");
63
57
  if (!HEX_BYTES_RE.test(spk)) {
64
58
  throw new Error(
65
- "SPK must be an even-length hex string. Generate one with `pnpm --filter @vex-chat/spire gen-spk` or `gen-spk-fips`.",
59
+ "SPK must be an even-length hex string. Generate one with `pnpm --filter @vex-chat/spire gen-spk`.",
66
60
  );
67
61
  }
68
62
 
69
- if (isSpireFipsEnabled(env["SPIRE_FIPS"])) {
70
- if (spk.length === TWEETNACL_SPK_HEX_LENGTH) {
71
- throw new Error(
72
- "SPIRE_FIPS=true requires an SPK from `pnpm --filter @vex-chat/spire gen-spk-fips`; the configured SPK looks like a tweetnacl key.",
73
- );
74
- }
75
- } else if (spk.length !== TWEETNACL_SPK_HEX_LENGTH) {
63
+ if (spk.length !== TWEETNACL_SPK_HEX_LENGTH) {
76
64
  throw new Error(
77
- "SPIRE_FIPS is not enabled, so SPK must be 128 hex characters from `pnpm --filter @vex-chat/spire gen-spk`.",
65
+ "SPK must be 128 hex characters from `pnpm --filter @vex-chat/spire gen-spk`.",
78
66
  );
79
67
  }
80
68
 
81
69
  if (jwtSecret.length === 0) {
82
70
  throw new Error(
83
- "JWT_SECRET must be set. Generate one with `pnpm --filter @vex-chat/spire gen-spk` or `gen-spk-fips`.",
71
+ "JWT_SECRET must be set. Generate one with `pnpm --filter @vex-chat/spire gen-spk`.",
84
72
  );
85
73
  }
86
74
  if (jwtSecret.length < 32) {
@@ -4,17 +4,12 @@
4
4
  * Commercial licenses available at vex.wtf
5
5
  */
6
6
 
7
- import { getCryptoProfile, xSignOpen, xSignOpenAsync } from "@vex-chat/crypto";
7
+ import { xSignOpen } from "@vex-chat/crypto";
8
8
 
9
- /**
10
- * Ed25519 detached-verify open: sync on tweetnacl, async for FIPS (Web Crypto).
11
- */
12
- export async function spireXSignOpenAsync(
9
+ /** Ed25519 detached-verify open. */
10
+ export function spireXSignOpenAsync(
13
11
  signedMessage: Uint8Array,
14
12
  publicKey: Uint8Array,
15
13
  ): Promise<null | Uint8Array> {
16
- if (getCryptoProfile() === "fips") {
17
- return xSignOpenAsync(signedMessage, publicKey);
18
- }
19
- return xSignOpen(signedMessage, publicKey);
14
+ return Promise.resolve(xSignOpen(signedMessage, publicKey));
20
15
  }