@vellumai/vellum-gateway 0.4.30 → 0.4.31
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/package.json
CHANGED
|
@@ -9,9 +9,9 @@ describe("matchContactsControlPlaneRoute", () => {
|
|
|
9
9
|
expect(matchContactsControlPlaneRoute("/v1/contacts", "POST")).toEqual({
|
|
10
10
|
kind: "upsertContact",
|
|
11
11
|
});
|
|
12
|
-
expect(
|
|
13
|
-
|
|
14
|
-
);
|
|
12
|
+
expect(
|
|
13
|
+
matchContactsControlPlaneRoute("/v1/contacts/merge", "POST"),
|
|
14
|
+
).toEqual({ kind: "mergeContacts" });
|
|
15
15
|
expect(
|
|
16
16
|
matchContactsControlPlaneRoute("/v1/contacts/channels/ch_1", "PATCH"),
|
|
17
17
|
).toEqual({ kind: "updateContactChannel", channelId: "ch_1" });
|
|
@@ -21,6 +21,27 @@ describe("matchContactsControlPlaneRoute", () => {
|
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
+
test("matches verify contact channel route", () => {
|
|
25
|
+
expect(
|
|
26
|
+
matchContactsControlPlaneRoute(
|
|
27
|
+
"/v1/contacts/ct_1/channels/ch_1/verify",
|
|
28
|
+
"POST",
|
|
29
|
+
),
|
|
30
|
+
).toEqual({
|
|
31
|
+
kind: "verifyContactChannel",
|
|
32
|
+
contactId: "ct_1",
|
|
33
|
+
channelId: "ch_1",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Only POST is supported
|
|
37
|
+
expect(
|
|
38
|
+
matchContactsControlPlaneRoute(
|
|
39
|
+
"/v1/contacts/ct_1/channels/ch_1/verify",
|
|
40
|
+
"GET",
|
|
41
|
+
),
|
|
42
|
+
).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
|
|
24
45
|
test("returns null for unsupported methods on contact routes", () => {
|
|
25
46
|
expect(matchContactsControlPlaneRoute("/v1/contacts", "DELETE")).toBeNull();
|
|
26
47
|
// GET /v1/contacts/channels/ch_1 does not match (PATCH only)
|
|
@@ -31,10 +52,12 @@ describe("matchContactsControlPlaneRoute", () => {
|
|
|
31
52
|
|
|
32
53
|
test("GET /v1/contacts/merge falls through to getContact", () => {
|
|
33
54
|
// No GET handler for /merge, so the contactId catch-all picks it up
|
|
34
|
-
expect(matchContactsControlPlaneRoute("/v1/contacts/merge", "GET")).toEqual(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
expect(matchContactsControlPlaneRoute("/v1/contacts/merge", "GET")).toEqual(
|
|
56
|
+
{
|
|
57
|
+
kind: "getContact",
|
|
58
|
+
contactId: "merge",
|
|
59
|
+
},
|
|
60
|
+
);
|
|
38
61
|
});
|
|
39
62
|
|
|
40
63
|
test("matches redeem invite only for POST", () => {
|
|
@@ -121,6 +121,18 @@ export function createContactsControlPlaneProxyHandler(config: GatewayConfig) {
|
|
|
121
121
|
return proxyToRuntime(req, `/v1/contacts/channels/${channelId}`, "");
|
|
122
122
|
},
|
|
123
123
|
|
|
124
|
+
async handleVerifyContactChannel(
|
|
125
|
+
req: Request,
|
|
126
|
+
contactId: string,
|
|
127
|
+
channelId: string,
|
|
128
|
+
): Promise<Response> {
|
|
129
|
+
return proxyToRuntime(
|
|
130
|
+
req,
|
|
131
|
+
`/v1/contacts/${contactId}/channels/${channelId}/verify`,
|
|
132
|
+
"",
|
|
133
|
+
);
|
|
134
|
+
},
|
|
135
|
+
|
|
124
136
|
// ── Invite routes ──
|
|
125
137
|
async handleListInvites(req: Request): Promise<Response> {
|
|
126
138
|
const url = new URL(req.url);
|
|
@@ -7,7 +7,8 @@ export type ContactsControlPlaneRoute =
|
|
|
7
7
|
| { kind: "listInvites" }
|
|
8
8
|
| { kind: "createInvite" }
|
|
9
9
|
| { kind: "redeemInvite" }
|
|
10
|
-
| { kind: "revokeInvite"; inviteId: string }
|
|
10
|
+
| { kind: "revokeInvite"; inviteId: string }
|
|
11
|
+
| { kind: "verifyContactChannel"; contactId: string; channelId: string };
|
|
11
12
|
|
|
12
13
|
export function matchContactsControlPlaneRoute(
|
|
13
14
|
pathname: string,
|
|
@@ -30,6 +31,18 @@ export function matchContactsControlPlaneRoute(
|
|
|
30
31
|
return { kind: "updateContactChannel", channelId: channelMatch[1] };
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
// Trusted channel verification
|
|
35
|
+
const verifyMatch = pathname.match(
|
|
36
|
+
/^\/v1\/contacts\/([^/]+)\/channels\/([^/]+)\/verify$/,
|
|
37
|
+
);
|
|
38
|
+
if (verifyMatch && method === "POST") {
|
|
39
|
+
return {
|
|
40
|
+
kind: "verifyContactChannel",
|
|
41
|
+
contactId: verifyMatch[1],
|
|
42
|
+
channelId: verifyMatch[2],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
// ── Invite routes ──
|
|
34
47
|
if (pathname === "/v1/contacts/invites") {
|
|
35
48
|
if (method === "GET") return { kind: "listInvites" };
|
package/src/index.ts
CHANGED
|
@@ -373,6 +373,17 @@ function main() {
|
|
|
373
373
|
handler: (req, params) =>
|
|
374
374
|
contactsControlPlaneProxy.handleUpdateContactChannel(req, params[0]),
|
|
375
375
|
},
|
|
376
|
+
{
|
|
377
|
+
path: /^\/v1\/contacts\/([^/]+)\/channels\/([^/]+)\/verify$/,
|
|
378
|
+
method: "POST",
|
|
379
|
+
auth: "edge",
|
|
380
|
+
handler: (req, params) =>
|
|
381
|
+
contactsControlPlaneProxy.handleVerifyContactChannel(
|
|
382
|
+
req,
|
|
383
|
+
params[0],
|
|
384
|
+
params[1],
|
|
385
|
+
),
|
|
386
|
+
},
|
|
376
387
|
|
|
377
388
|
// ── Contacts/invites control plane ──
|
|
378
389
|
{
|