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:
+26
-6
@@ -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");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { CreateConnectionRequestInput } from "../src/index.js";
|
||||
|
||||
const fields = {
|
||||
callbackUrl: "https://app.example/stuffbox/callback",
|
||||
codeChallenge: "c".repeat(43),
|
||||
scopes: ["assets:read"] as const,
|
||||
state: "state-with-enough-entropy",
|
||||
};
|
||||
|
||||
const automatic: CreateConnectionRequestInput = fields;
|
||||
const returning: CreateConnectionRequestInput = { ...fields, clientId: "app_public" };
|
||||
const legacyAutomatic: CreateConnectionRequestInput = { ...fields, selfHosted: true };
|
||||
const legacyReturning: CreateConnectionRequestInput = {
|
||||
...fields,
|
||||
clientId: "app_public",
|
||||
selfHosted: false,
|
||||
};
|
||||
|
||||
// @ts-expect-error An automatic request cannot also send a client ID.
|
||||
const mixed: CreateConnectionRequestInput = { ...fields, clientId: "app_public", selfHosted: true };
|
||||
// @ts-expect-error The old false marker requires a client ID.
|
||||
const missingClient: CreateConnectionRequestInput = { ...fields, selfHosted: false };
|
||||
|
||||
void [automatic, returning, legacyAutomatic, legacyReturning, mixed, missingClient];
|
||||
Reference in New Issue
Block a user