@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 +2 -2
- package/README.md +17 -0
- package/dist/BaseClient.js +2 -2
- package/dist/wrapper/speech-engine/SpeechEngineResource.js +13 -3
- package/dist/wrapper/speech-engine/SpeechEngineServer.js +34 -20
- package/dist/wrapper/speech-engine/types.d.ts +11 -0
- package/package.json +1 -1
- package/wrapper/speech-engine/SpeechEngineResource.js +13 -3
- package/wrapper/speech-engine/SpeechEngineServer.js +34 -20
- package/wrapper/speech-engine/types.d.ts +11 -0
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.
|
|
45
|
-
"User-Agent": "@elevenlabs/elevenlabs-js/2.
|
|
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 |
|
package/dist/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.
|
|
45
|
-
"User-Agent": "@elevenlabs/elevenlabs-js/2.
|
|
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 (
|
|
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
|
-
|
|
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
|
|
47
|
-
|
|
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 = (
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
67
|
-
log(
|
|
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((
|
|
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
|
@@ -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 (
|
|
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
|
-
|
|
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
|
|
47
|
-
|
|
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 = (
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
67
|
-
log(
|
|
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((
|
|
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. */
|