ldrouter 1.11.0 → 1.11.3

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/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/) and the project adheres to
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [1.11.3] - 2026-09-03
8
+
9
+ ### Fixed
10
+
11
+ - **Model Test streaming endpoint no longer returns an opaque 500 "Gateway error"**: when the provider credential can't be decrypted (master-key mismatch after backup restore), it now returns a readable `authentication_error` prompting to re-save the provider API key.
12
+ - **Docker container restart no longer causes data loss**: added `docker-entrypoint.sh` that removes stale SQLite WAL/SHM files on startup and performs a checkpoint to ensure all data is persisted to the main database file before starting the gateway.
13
+
14
+ ## [1.11.2] - 2026-09-02
15
+
16
+ ### Fixed
17
+
18
+ - **Custom API keys without an `ld-` prefix now authenticate**: the API-key creation form accepts any custom key value, but gateway authentication rejected every key not starting with `ld-` (401 "Invalid API key format"), making custom keys unusable. Authentication now accepts any stored secret verbatim — auto-generated keys still use the `ld-<base64url(32 bytes)>` format.
19
+
7
20
  ## [1.11.0] - 2026-09-01
8
21
 
9
22
  ### Added
@@ -37,9 +37,8 @@ export function authenticateGatewayKey(req) {
37
37
  candidate = anthropic;
38
38
  if (!candidate)
39
39
  return null;
40
- if (!candidate.startsWith('ld-')) {
41
- throw new GatewayError('authentication_error', 'Invalid API key format', { status: 401 });
42
- }
40
+ // Custom keys are stored verbatim (no prefix requirement); auto-generated
41
+ // keys start with ld-, but authentication must accept any stored secret.
43
42
  const digest = sha256Hex(candidate);
44
43
  const db = getDb();
45
44
  const row = db.select().from(schema.apiKeys).where(eq(schema.apiKeys.keyDigest, digest)).get();
@@ -188,7 +188,8 @@ export const modelAliases = sqliteTable('model_aliases', {
188
188
  aliasIdx: uniqueIndex('uniq_alias').on(t.alias),
189
189
  }));
190
190
  // ============================================================================
191
- // API keys (gateway keys with ld- prefix)
191
+ // API keys (gateway keys; auto-generated ones start with ld-, but custom
192
+ // values without prefix are now supported)
192
193
  // ============================================================================
193
194
  export const apiKeys = sqliteTable('api_keys', {
194
195
  id: text('id').primaryKey(),
@@ -232,8 +232,9 @@ export async function registerModelRoutes(app) {
232
232
  protocol: 'openai',
233
233
  endpoint: 'chat/completions',
234
234
  };
235
+ let outcome;
235
236
  try {
236
- const outcome = await runner.execute(gatewayReq, ctx);
237
+ outcome = await runner.execute(gatewayReq, ctx);
237
238
  // Runner already wrote [DONE]. Append our own test_meta event so the
238
239
  // client knows the test finished with full stats.
239
240
  send('test_meta', {
@@ -251,6 +252,10 @@ export async function registerModelRoutes(app) {
251
252
  });
252
253
  }
253
254
  catch (e) {
255
+ // Never let a raw non-GatewayError (e.g. MasterKeyError from credential
256
+ // decryption) escape into the global handler as an opaque "Gateway error".
257
+ if (e instanceof GatewayError)
258
+ throw e;
254
259
  send('test_error', { message: e.message });
255
260
  }
256
261
  finally {
@@ -39,7 +39,7 @@ const DEFAULT_SECRET_KEYS = [
39
39
  ];
40
40
  const SECRET_KEY_REGEX = /(authorization|api[-_]?key|api[-_]?secret|password|passwd|secret|token|cookie|master[-_]?key|totp|recovery|private[-_]?key|session)/i;
41
41
  const PLAINTEXT_PATTERNS = [
42
- /\bld-[A-Za-z0-9_-]{20,}\b/g, // gateway api keys
42
+ /\bld-[A-Za-z0-9_-]{20,}\b/g, // auto-generated gateway api keys (custom keys are covered by the Bearer/x-api-key patterns below)
43
43
  /(Bearer|Basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,
44
44
  /sk-[A-Za-z0-9_-]{12,}/g, // OpenAI-style
45
45
  /anthropic[_-]?[A-Za-z0-9_-]{20,}/gi,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ldrouter",
3
- "version": "1.11.0",
3
+ "version": "1.11.3",
4
4
  "description": "LateDev Router — lightweight self-hosted LLM gateway with admin UI",
5
5
  "type": "module",
6
6
  "license": "MIT",