@elevenlabs/elevenlabs-js 2.55.0 → 2.56.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.
package/BaseClient.js CHANGED
@@ -41,8 +41,8 @@ function normalizeClientOptions(options) {
41
41
  const headers = (0, headers_1.mergeHeaders)({
42
42
  "X-Fern-Language": "JavaScript",
43
43
  "X-Fern-SDK-Name": "@elevenlabs/elevenlabs-js",
44
- "X-Fern-SDK-Version": "2.55.0",
45
- "User-Agent": "@elevenlabs/elevenlabs-js/2.55.0",
44
+ "X-Fern-SDK-Version": "2.56.0",
45
+ "User-Agent": "@elevenlabs/elevenlabs-js/2.56.0",
46
46
  "X-Fern-Runtime": core.RUNTIME.type,
47
47
  "X-Fern-Runtime-Version": core.RUNTIME.version,
48
48
  "xi-api-key": options === null || options === void 0 ? void 0 : options.apiKey,
package/README.md CHANGED
@@ -178,6 +178,23 @@ server.start();
178
178
 
179
179
  Both `SpeechEngine.Server` and `speechEngine.attach()` automatically verify the `X-Elevenlabs-Speech-Engine-Authorization` header on every incoming connection, rejecting any requests that were not signed by ElevenLabs. The API key is read from `apiKey` in the options or the `ELEVENLABS_API_KEY` environment variable.
180
180
 
181
+ #### Disabling authentication
182
+
183
+ If you're running behind an infrastructure layer that already restricts incoming traffic to ElevenLabs (typically an IP allowlist scoped to [ElevenLabs' egress ranges](https://elevenlabs.io/docs/overview/capabilities/speech-engine#ip-allowlisting)), you can skip JWT verification by passing `disableAuth: true`:
184
+
185
+ ```ts
186
+ // Standalone — no apiKey required when disableAuth is true
187
+ new SpeechEngine.Server({ port: 3001, disableAuth: true, onTranscript }).start();
188
+
189
+ // Or on attach
190
+ elevenlabs.speechEngine.attach("seng_123", httpServer, "/api/speech-engine/ws", {
191
+ disableAuth: true,
192
+ onTranscript,
193
+ });
194
+ ```
195
+
196
+ When auth is disabled the server accepts any client that can reach it and logs a `console.warn` on startup. **Only use this if you have an IP allowlist or equivalent network-level restriction in front of the server** — without one, anyone on the internet can open a session and consume your compute and downstream LLM quota.
197
+
181
198
  ### Session events
182
199
 
183
200
  | Event | Method | Description |
@@ -41,8 +41,8 @@ function normalizeClientOptions(options) {
41
41
  const headers = (0, headers_1.mergeHeaders)({
42
42
  "X-Fern-Language": "JavaScript",
43
43
  "X-Fern-SDK-Name": "@elevenlabs/elevenlabs-js",
44
- "X-Fern-SDK-Version": "2.55.0",
45
- "User-Agent": "@elevenlabs/elevenlabs-js/2.55.0",
44
+ "X-Fern-SDK-Version": "2.56.0",
45
+ "User-Agent": "@elevenlabs/elevenlabs-js/2.56.0",
46
46
  "X-Fern-Runtime": core.RUNTIME.type,
47
47
  "X-Fern-Runtime-Version": core.RUNTIME.version,
48
48
  "xi-api-key": options === null || options === void 0 ? void 0 : options.apiKey,
@@ -111,9 +111,14 @@ class SpeechEngineResource {
111
111
  * ```
112
112
  */
113
113
  attach(httpServer, path, handler) {
114
- var _a;
114
+ var _a, _b;
115
115
  const debug = (_a = handler.debug) !== null && _a !== void 0 ? _a : false;
116
+ const disableAuth = (_b = handler.disableAuth) !== null && _b !== void 0 ? _b : false;
116
117
  const log = debug ? (...args) => console.log("[SpeechEngine]", ...args) : () => { };
118
+ if (disableAuth) {
119
+ console.warn("[SpeechEngine] authentication is disabled on attach() — incoming connections will NOT be verified. " +
120
+ "Make sure the server is protected by either IP allowlist restricting traffic to ElevenLabs or using custom header values.");
121
+ }
117
122
  const wss = new ws_1.default.Server({ noServer: true });
118
123
  const upgradeListener = (req, socket, head) => __awaiter(this, void 0, void 0, function* () {
119
124
  var _a;
@@ -123,14 +128,19 @@ class SpeechEngineResource {
123
128
  log(`path mismatch: expected ${path}, got ${url.pathname} — skipping`);
124
129
  return;
125
130
  }
126
- if (!(yield this.verifyRequest(req))) {
131
+ if (disableAuth) {
132
+ log("auth disabled, upgrading connection without verification");
133
+ }
134
+ else if (!(yield this.verifyRequest(req))) {
127
135
  // verifyRequest returned false — get the detailed reason for debug logging
128
136
  const reason = yield this.getVerificationFailure(req);
129
137
  log(`rejected connection — ${reason}`);
130
138
  socket.destroy();
131
139
  return;
132
140
  }
133
- log("upgrading connection to WebSocket");
141
+ else {
142
+ log("upgrading connection to WebSocket");
143
+ }
134
144
  wss.handleUpgrade(req, socket, head, (ws) => {
135
145
  log("WebSocket connection established");
136
146
  wss.emit("connection", ws);
@@ -39,36 +39,50 @@ class SpeechEngineServer {
39
39
  * Start the standalone WebSocket server on the configured port.
40
40
  */
41
41
  start() {
42
- var _a, _b, _c;
42
+ var _a, _b, _c, _d;
43
43
  if (this.wss) {
44
44
  throw new Error("Server is already started");
45
45
  }
46
- const apiKey = (_a = this.options.apiKey) !== null && _a !== void 0 ? _a : process.env.ELEVENLABS_API_KEY;
47
- if (!apiKey) {
46
+ const disableAuth = (_a = this.options.disableAuth) !== null && _a !== void 0 ? _a : false;
47
+ const apiKey = (_b = this.options.apiKey) !== null && _b !== void 0 ? _b : process.env.ELEVENLABS_API_KEY;
48
+ if (!apiKey && !disableAuth) {
48
49
  throw new Error("SpeechEngine.Server requires an API key to verify incoming connections. " +
49
- "Pass { apiKey: \"...\" } or set the ELEVENLABS_API_KEY environment variable.");
50
+ "Pass { apiKey: \"...\" } or set the ELEVENLABS_API_KEY environment variable. " +
51
+ "To run without authentication, pass { disableAuth: true } — but only behind an IP allowlist.");
50
52
  }
51
- const debug = (_b = this.options.debug) !== null && _b !== void 0 ? _b : false;
53
+ const debug = (_c = this.options.debug) !== null && _c !== void 0 ? _c : false;
52
54
  const log = debug ? (...args) => console.log("[SpeechEngine]", ...args) : () => { };
55
+ if (disableAuth) {
56
+ console.warn("[SpeechEngine] authentication is disabled — incoming connections will NOT be verified. " +
57
+ "Make sure the server is protected by an IP allowlist restricting traffic to ElevenLabs.");
58
+ }
53
59
  const httpServer = (0, node_http_1.createServer)();
54
60
  const wss = new ws_1.default.Server({ noServer: true });
61
+ const verifyToken = disableAuth
62
+ ? null
63
+ : (token) => (0, SpeechEngineResource_1.verifySpeechEngineJwt)(token, apiKey);
55
64
  httpServer.on("upgrade", (req, socket, head) => {
56
- const headerValue = req.headers["x-elevenlabs-speech-engine-authorization"];
57
- const token = Array.isArray(headerValue) ? headerValue[0] : headerValue;
58
- if (!token) {
59
- log("rejected connection — missing X-Elevenlabs-Speech-Engine-Authorization header");
60
- socket.destroy();
61
- return;
62
- }
63
- try {
64
- (0, SpeechEngineResource_1.verifySpeechEngineJwt)(token, apiKey);
65
+ if (verifyToken) {
66
+ const headerValue = req.headers["x-elevenlabs-speech-engine-authorization"];
67
+ const token = Array.isArray(headerValue) ? headerValue[0] : headerValue;
68
+ if (!token) {
69
+ log("rejected connection — missing X-Elevenlabs-Speech-Engine-Authorization header");
70
+ socket.destroy();
71
+ return;
72
+ }
73
+ try {
74
+ verifyToken(token);
75
+ }
76
+ catch (err) {
77
+ log(`rejected connection — ${err instanceof Error ? err.message : String(err)}`);
78
+ socket.destroy();
79
+ return;
80
+ }
81
+ log("verified connection, upgrading to WebSocket");
65
82
  }
66
- catch (err) {
67
- log(`rejected connection ${err instanceof Error ? err.message : String(err)}`);
68
- socket.destroy();
69
- return;
83
+ else {
84
+ log("auth disabled, upgrading connection without verification");
70
85
  }
71
- log("verified connection, upgrading to WebSocket");
72
86
  wss.handleUpgrade(req, socket, head, (ws) => {
73
87
  wss.emit("connection", ws);
74
88
  });
@@ -76,7 +90,7 @@ class SpeechEngineServer {
76
90
  wss.on("connection", (ws) => {
77
91
  this.handleConnection(ws);
78
92
  });
79
- httpServer.listen((_c = this.options.port) !== null && _c !== void 0 ? _c : 3001);
93
+ httpServer.listen((_d = this.options.port) !== null && _d !== void 0 ? _d : 3001);
80
94
  this.wss = wss;
81
95
  this.httpServer = httpServer;
82
96
  }
@@ -45,6 +45,17 @@ export type SpeechEngineEventName = keyof SpeechEngineEventMap;
45
45
  export interface SpeechEngineCallbacks {
46
46
  /** Enable debug logging. */
47
47
  debug?: boolean;
48
+ /**
49
+ * Disable verification of the `X-Elevenlabs-Speech-Engine-Authorization`
50
+ * JWT on incoming connections. When `true`, any client that can reach the
51
+ * server will be accepted.
52
+ *
53
+ * **Insecure.** Only enable this if you are protecting the server through
54
+ * another layer — typically an IP allowlist restricting traffic to
55
+ * ElevenLabs' egress ranges. Without that, anyone on the internet can
56
+ * open a session and consume your compute and downstream LLM quota.
57
+ */
58
+ disableAuth?: boolean;
48
59
  /** Fired once when the session is initialized with a conversation ID. */
49
60
  onInit?(conversationId: string, session: SpeechEngineSession): void;
50
61
  /** Fired each time the Speech Engine API sends a user transcript. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevenlabs/elevenlabs-js",
3
- "version": "2.55.0",
3
+ "version": "2.56.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -111,9 +111,14 @@ class SpeechEngineResource {
111
111
  * ```
112
112
  */
113
113
  attach(httpServer, path, handler) {
114
- var _a;
114
+ var _a, _b;
115
115
  const debug = (_a = handler.debug) !== null && _a !== void 0 ? _a : false;
116
+ const disableAuth = (_b = handler.disableAuth) !== null && _b !== void 0 ? _b : false;
116
117
  const log = debug ? (...args) => console.log("[SpeechEngine]", ...args) : () => { };
118
+ if (disableAuth) {
119
+ console.warn("[SpeechEngine] authentication is disabled on attach() — incoming connections will NOT be verified. " +
120
+ "Make sure the server is protected by either IP allowlist restricting traffic to ElevenLabs or using custom header values.");
121
+ }
117
122
  const wss = new ws_1.default.Server({ noServer: true });
118
123
  const upgradeListener = (req, socket, head) => __awaiter(this, void 0, void 0, function* () {
119
124
  var _a;
@@ -123,14 +128,19 @@ class SpeechEngineResource {
123
128
  log(`path mismatch: expected ${path}, got ${url.pathname} — skipping`);
124
129
  return;
125
130
  }
126
- if (!(yield this.verifyRequest(req))) {
131
+ if (disableAuth) {
132
+ log("auth disabled, upgrading connection without verification");
133
+ }
134
+ else if (!(yield this.verifyRequest(req))) {
127
135
  // verifyRequest returned false — get the detailed reason for debug logging
128
136
  const reason = yield this.getVerificationFailure(req);
129
137
  log(`rejected connection — ${reason}`);
130
138
  socket.destroy();
131
139
  return;
132
140
  }
133
- log("upgrading connection to WebSocket");
141
+ else {
142
+ log("upgrading connection to WebSocket");
143
+ }
134
144
  wss.handleUpgrade(req, socket, head, (ws) => {
135
145
  log("WebSocket connection established");
136
146
  wss.emit("connection", ws);
@@ -39,36 +39,50 @@ class SpeechEngineServer {
39
39
  * Start the standalone WebSocket server on the configured port.
40
40
  */
41
41
  start() {
42
- var _a, _b, _c;
42
+ var _a, _b, _c, _d;
43
43
  if (this.wss) {
44
44
  throw new Error("Server is already started");
45
45
  }
46
- const apiKey = (_a = this.options.apiKey) !== null && _a !== void 0 ? _a : process.env.ELEVENLABS_API_KEY;
47
- if (!apiKey) {
46
+ const disableAuth = (_a = this.options.disableAuth) !== null && _a !== void 0 ? _a : false;
47
+ const apiKey = (_b = this.options.apiKey) !== null && _b !== void 0 ? _b : process.env.ELEVENLABS_API_KEY;
48
+ if (!apiKey && !disableAuth) {
48
49
  throw new Error("SpeechEngine.Server requires an API key to verify incoming connections. " +
49
- "Pass { apiKey: \"...\" } or set the ELEVENLABS_API_KEY environment variable.");
50
+ "Pass { apiKey: \"...\" } or set the ELEVENLABS_API_KEY environment variable. " +
51
+ "To run without authentication, pass { disableAuth: true } — but only behind an IP allowlist.");
50
52
  }
51
- const debug = (_b = this.options.debug) !== null && _b !== void 0 ? _b : false;
53
+ const debug = (_c = this.options.debug) !== null && _c !== void 0 ? _c : false;
52
54
  const log = debug ? (...args) => console.log("[SpeechEngine]", ...args) : () => { };
55
+ if (disableAuth) {
56
+ console.warn("[SpeechEngine] authentication is disabled — incoming connections will NOT be verified. " +
57
+ "Make sure the server is protected by an IP allowlist restricting traffic to ElevenLabs.");
58
+ }
53
59
  const httpServer = (0, node_http_1.createServer)();
54
60
  const wss = new ws_1.default.Server({ noServer: true });
61
+ const verifyToken = disableAuth
62
+ ? null
63
+ : (token) => (0, SpeechEngineResource_1.verifySpeechEngineJwt)(token, apiKey);
55
64
  httpServer.on("upgrade", (req, socket, head) => {
56
- const headerValue = req.headers["x-elevenlabs-speech-engine-authorization"];
57
- const token = Array.isArray(headerValue) ? headerValue[0] : headerValue;
58
- if (!token) {
59
- log("rejected connection — missing X-Elevenlabs-Speech-Engine-Authorization header");
60
- socket.destroy();
61
- return;
62
- }
63
- try {
64
- (0, SpeechEngineResource_1.verifySpeechEngineJwt)(token, apiKey);
65
+ if (verifyToken) {
66
+ const headerValue = req.headers["x-elevenlabs-speech-engine-authorization"];
67
+ const token = Array.isArray(headerValue) ? headerValue[0] : headerValue;
68
+ if (!token) {
69
+ log("rejected connection — missing X-Elevenlabs-Speech-Engine-Authorization header");
70
+ socket.destroy();
71
+ return;
72
+ }
73
+ try {
74
+ verifyToken(token);
75
+ }
76
+ catch (err) {
77
+ log(`rejected connection — ${err instanceof Error ? err.message : String(err)}`);
78
+ socket.destroy();
79
+ return;
80
+ }
81
+ log("verified connection, upgrading to WebSocket");
65
82
  }
66
- catch (err) {
67
- log(`rejected connection ${err instanceof Error ? err.message : String(err)}`);
68
- socket.destroy();
69
- return;
83
+ else {
84
+ log("auth disabled, upgrading connection without verification");
70
85
  }
71
- log("verified connection, upgrading to WebSocket");
72
86
  wss.handleUpgrade(req, socket, head, (ws) => {
73
87
  wss.emit("connection", ws);
74
88
  });
@@ -76,7 +90,7 @@ class SpeechEngineServer {
76
90
  wss.on("connection", (ws) => {
77
91
  this.handleConnection(ws);
78
92
  });
79
- httpServer.listen((_c = this.options.port) !== null && _c !== void 0 ? _c : 3001);
93
+ httpServer.listen((_d = this.options.port) !== null && _d !== void 0 ? _d : 3001);
80
94
  this.wss = wss;
81
95
  this.httpServer = httpServer;
82
96
  }
@@ -45,6 +45,17 @@ export type SpeechEngineEventName = keyof SpeechEngineEventMap;
45
45
  export interface SpeechEngineCallbacks {
46
46
  /** Enable debug logging. */
47
47
  debug?: boolean;
48
+ /**
49
+ * Disable verification of the `X-Elevenlabs-Speech-Engine-Authorization`
50
+ * JWT on incoming connections. When `true`, any client that can reach the
51
+ * server will be accepted.
52
+ *
53
+ * **Insecure.** Only enable this if you are protecting the server through
54
+ * another layer — typically an IP allowlist restricting traffic to
55
+ * ElevenLabs' egress ranges. Without that, anyone on the internet can
56
+ * open a session and consume your compute and downstream LLM quota.
57
+ */
58
+ disableAuth?: boolean;
48
59
  /** Fired once when the session is initialized with a conversation ID. */
49
60
  onInit?(conversationId: string, session: SpeechEngineSession): void;
50
61
  /** Fired each time the Speech Engine API sends a user transcript. */