Release automatic callback setup in SDK 0.2.0

Hop-State: A_06FPARPGMNVEAN3XBVH0QD8
Hop-Proposal: R_06FPARNXMP3DGP5VQGGX4Z8
Hop-Task: T_06FPAR9KH2V5ED7V65JEN00
Hop-Attempt: AT_06FPAR9KH3NZ1CV8RGPJDSG
This commit is contained in:
2026-07-15 03:46:42 -07:00
committed by Hop
parent 73a3279d5c
commit bb04d47a29
9 changed files with 88 additions and 33 deletions
+26 -6
View File
@@ -61,7 +61,7 @@ describe("StuffboxClient", () => {
});
});
it("automatically registers a self-hosted callback and returns its client ID", async () => {
it("automatically creates a callback identity when the client ID is omitted", async () => {
const fetcher = vi.fn<FetchLike>().mockResolvedValue(
json({
request_id: "cr_self_hosted",
@@ -78,7 +78,6 @@ describe("StuffboxClient", () => {
await expect(
client.createConnectionRequest({
selfHosted: true,
callbackUrl: "https://synapsis.test/stuffbox/callback",
codeChallenge: "c".repeat(43),
scopes: ["assets:read", "assets:write"],
@@ -93,7 +92,6 @@ describe("StuffboxClient", () => {
});
expect(JSON.parse(String(fetcher.mock.calls[0][1]?.body))).toEqual({
registration_mode: "self_hosted",
callback_url: "https://synapsis.test/stuffbox/callback",
code_challenge: "c".repeat(43),
code_challenge_method: "S256",
@@ -102,6 +100,31 @@ describe("StuffboxClient", () => {
});
});
it("keeps the deprecated selfHosted option wire-compatible", async () => {
const fetcher = vi.fn<FetchLike>().mockResolvedValue(
json({
request_id: "cr_legacy",
client_id: "app_legacy_0123456789abcdef",
callback_url: "https://legacy.test/stuffbox/callback",
authorization_url: "https://stuffbox.test/authorize/cr_legacy",
expires_at: "2026-01-01T00:05:00.000Z",
}),
);
const client = new StuffboxClient({ baseUrl: "https://stuffbox.test", fetch: fetcher });
await client.createConnectionRequest({
selfHosted: true,
callbackUrl: "https://legacy.test/stuffbox/callback",
codeChallenge: "c".repeat(43),
scopes: ["assets:read"],
state: "state-with-enough-entropy",
});
expect(JSON.parse(String(fetcher.mock.calls[0][1]?.body))).toMatchObject({
registration_mode: "self_hosted",
});
});
it("rejects a connection response that omits the client ID", async () => {
const fetcher = vi.fn<FetchLike>().mockResolvedValue(
json({
@@ -118,7 +141,6 @@ describe("StuffboxClient", () => {
const error = await client
.createConnectionRequest({
selfHosted: true,
callbackUrl: "https://synapsis.test/stuffbox/callback",
codeChallenge: "c".repeat(43),
scopes: ["assets:read"],
@@ -149,7 +171,6 @@ describe("StuffboxClient", () => {
const error = await client
.createConnectionRequest({
selfHosted: true,
callbackUrl: "https://synapsis.test/stuffbox/callback",
codeChallenge: "c".repeat(43),
scopes: ["assets:read"],
@@ -397,4 +418,3 @@ describe("StuffboxClient", () => {
expect(fetcher.mock.calls[1][1]?.method).toBe("DELETE");
});
});