diff --git a/docs/tasks/streams.mdx b/docs/tasks/streams.mdx index edf92aa95..8be0c9786 100644 --- a/docs/tasks/streams.mdx +++ b/docs/tasks/streams.mdx @@ -688,6 +688,7 @@ Examples: - ❌ `\u2007///\u2007` (empty after trimming wrapper whitespace) - ❌ `\u205F///\u205F` (empty after trimming wrapper whitespace) - ❌ `\u3000///\u3000` (empty after trimming wrapper whitespace) +- ❌ `\n\thttps://api.trigger.dev/base/?query=1\t\n` (query is still rejected after trimming wrappers) - ❌ `https://api.trigger.dev/\ninternal` - ❌ `https://api.trigger.dev/in valid` - ❌ `https://api.trigger.dev/\tinternal` diff --git a/packages/ai/README.md b/packages/ai/README.md index 2d0c726e2..3686bf8aa 100644 --- a/packages/ai/README.md +++ b/packages/ai/README.md @@ -195,6 +195,7 @@ Examples: - ❌ `\u2007///\u2007` (empty after trimming wrapper whitespace) - ❌ `\u205F///\u205F` (empty after trimming wrapper whitespace) - ❌ `\u3000///\u3000` (empty after trimming wrapper whitespace) +- ❌ `\n\thttps://api.trigger.dev/base/?query=1\t\n` (query is still rejected after trimming wrappers) - ❌ `https://api.trigger.dev/\ninternal` (internal whitespace characters) - ❌ `https://api.trigger.dev/in valid` (internal space characters) - ❌ `https://api.trigger.dev/\tinternal` (internal tab characters) diff --git a/packages/ai/src/chatTransport.test.ts b/packages/ai/src/chatTransport.test.ts index 7ff8adbb0..2978d43ca 100644 --- a/packages/ai/src/chatTransport.test.ts +++ b/packages/ai/src/chatTransport.test.ts @@ -1105,6 +1105,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not include query parameters or hash fragments"); }); + it("throws when newline-and-tab wrapped baseURL includes query parameters", function () { + expect(function () { + new TriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\n\thttps://example.com/base/?query=1\t\n", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not include query parameters or hash fragments"); + }); + it("throws query/hash validation after trimming wrapper whitespace", function () { expect(function () { new TriggerChatTransport({ @@ -1138,6 +1149,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not include query parameters or hash fragments"); }); + it("throws when newline-and-tab wrapped baseURL includes hash fragments", function () { + expect(function () { + new TriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\n\thttps://example.com/base/#fragment\t\n", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not include query parameters or hash fragments"); + }); + it("throws when baseURL includes username or password credentials", function () { expect(function () { new TriggerChatTransport({ @@ -1226,6 +1248,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not include username or password credentials"); }); + it("throws when newline-and-tab wrapped baseURL includes username or password credentials", function () { + expect(function () { + new TriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\n\thttps://user:pass@example.com/base/\t\n", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not include username or password credentials"); + }); + it("accepts https baseURL values without throwing", function () { expect(function () { new TriggerChatTransport({ @@ -4064,6 +4097,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not include query parameters or hash fragments"); }); + it("throws from factory when newline-and-tab wrapped baseURL includes query parameters", function () { + expect(function () { + createTriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\n\thttps://example.com/base/?query=1\t\n", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not include query parameters or hash fragments"); + }); + it("throws query/hash validation after trimming wrapper whitespace in factory", function () { expect(function () { createTriggerChatTransport({ @@ -4097,6 +4141,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not include query parameters or hash fragments"); }); + it("throws from factory when newline-and-tab wrapped baseURL includes hash fragments", function () { + expect(function () { + createTriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\n\thttps://example.com/base/#fragment\t\n", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not include query parameters or hash fragments"); + }); + it("throws from factory when baseURL includes username or password credentials", function () { expect(function () { createTriggerChatTransport({ @@ -4185,6 +4240,17 @@ describe("TriggerChatTransport", function () { }).toThrowError("baseURL must not include username or password credentials"); }); + it("throws from factory when newline-and-tab wrapped baseURL includes username or password credentials", function () { + expect(function () { + createTriggerChatTransport({ + task: "chat-task", + accessToken: "pk_trigger", + baseURL: "\n\thttps://user:pass@example.com/base/\t\n", + stream: "chat-stream", + }); + }).toThrowError("baseURL must not include username or password credentials"); + }); + it("accepts https baseURL values from factory without throwing", function () { expect(function () { createTriggerChatTransport({