@whooshbang/sdk 5.0.0 → 6.0.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/README.md +232 -83
- package/dist/cli/commands.js +2 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/client.d.ts +209 -1
- package/dist/client.js +540 -5
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js.map +1 -1
- package/dist/interactions.js +18 -3
- package/dist/interactions.js.map +1 -1
- package/dist/recipient/element.js +641 -14
- package/dist/recipient/element.js.map +1 -1
- package/dist/recipient/i18n/ar.js +77 -0
- package/dist/recipient/i18n/ar.js.map +1 -1
- package/dist/recipient/i18n/catalog.d.ts +75 -0
- package/dist/recipient/i18n/catalog.js.map +1 -1
- package/dist/recipient/i18n/de.js +82 -0
- package/dist/recipient/i18n/de.js.map +1 -1
- package/dist/recipient/i18n/en.js +82 -0
- package/dist/recipient/i18n/en.js.map +1 -1
- package/dist/recipient/i18n/es.js +82 -0
- package/dist/recipient/i18n/es.js.map +1 -1
- package/dist/recipient/i18n/fa.js +77 -0
- package/dist/recipient/i18n/fa.js.map +1 -1
- package/dist/recipient/i18n/fr.js +82 -0
- package/dist/recipient/i18n/fr.js.map +1 -1
- package/dist/recipient/i18n/hi.js +82 -0
- package/dist/recipient/i18n/hi.js.map +1 -1
- package/dist/recipient/i18n/id.js +82 -0
- package/dist/recipient/i18n/id.js.map +1 -1
- package/dist/recipient/i18n/it.js +82 -0
- package/dist/recipient/i18n/it.js.map +1 -1
- package/dist/recipient/i18n/nl.js +82 -0
- package/dist/recipient/i18n/nl.js.map +1 -1
- package/dist/recipient/i18n/pl.js +82 -0
- package/dist/recipient/i18n/pl.js.map +1 -1
- package/dist/recipient/i18n/pt-BR.js +82 -0
- package/dist/recipient/i18n/pt-BR.js.map +1 -1
- package/dist/recipient/i18n/ru.js +82 -0
- package/dist/recipient/i18n/ru.js.map +1 -1
- package/dist/recipient/i18n/tr.js +82 -0
- package/dist/recipient/i18n/tr.js.map +1 -1
- package/dist/recipient/i18n/uk.js +82 -0
- package/dist/recipient/i18n/uk.js.map +1 -1
- package/dist/recipient/i18n/zh-Hans.js +77 -0
- package/dist/recipient/i18n/zh-Hans.js.map +1 -1
- package/dist/recipient/order-section.d.ts +41 -0
- package/dist/recipient/order-section.js +547 -0
- package/dist/recipient/order-section.js.map +1 -0
- package/dist/recipient/order-view.d.ts +123 -0
- package/dist/recipient/order-view.js +304 -0
- package/dist/recipient/order-view.js.map +1 -0
- package/dist/recipient/platform-mark.d.ts +1 -0
- package/dist/recipient/platform-mark.js +57 -0
- package/dist/recipient/platform-mark.js.map +1 -0
- package/dist/recipient/quiet-section.d.ts +47 -0
- package/dist/recipient/quiet-section.js +490 -0
- package/dist/recipient/quiet-section.js.map +1 -0
- package/dist/recipient/quiet-view.d.ts +84 -0
- package/dist/recipient/quiet-view.js +250 -0
- package/dist/recipient/quiet-view.js.map +1 -0
- package/dist/recipient/view.d.ts +2 -0
- package/dist/recipient/view.js.map +1 -1
- package/dist/webhooks.d.ts +30 -1
- package/dist/webhooks.js +57 -4
- package/dist/webhooks.js.map +1 -1
- package/package.json +12 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A person's quiet hours, as the "Quiet hours" tab edits them (FXO-2103).
|
|
3
|
+
*
|
|
4
|
+
* Pure, so the rules — what a save sends, what counts as a change, which
|
|
5
|
+
* field an error belongs to — are testable without a browser and shared by
|
|
6
|
+
* the subscriber panel and the dashboard, which cannot then drift apart.
|
|
7
|
+
*/
|
|
8
|
+
/** The channels quiet hours set a behaviour for, in the order they show. */
|
|
9
|
+
export const QUIET_CHANNELS = ["telegram", "slack", "email"];
|
|
10
|
+
/** ISO weekdays, Monday first. */
|
|
11
|
+
export const QUIET_DAYS = [1, 2, 3, 4, 5, 6, 7];
|
|
12
|
+
export const QUIET_WINDOWS_MAX = 7;
|
|
13
|
+
/** What a new period suggests: every night, 22:00 to 07:00. */
|
|
14
|
+
export const QUIET_SUGGESTED_WINDOW = {
|
|
15
|
+
days: [...QUIET_DAYS],
|
|
16
|
+
end: "07:00",
|
|
17
|
+
start: "22:00",
|
|
18
|
+
};
|
|
19
|
+
/** The browser's own named time zone, or UTC when it has none. */
|
|
20
|
+
export function browserTimeZone() {
|
|
21
|
+
try {
|
|
22
|
+
const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
23
|
+
return zone.length > 0 ? zone : "UTC";
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return "UTC";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The zone the times are shown in: the one quiet hours follow, else the browser's. */
|
|
30
|
+
export function quietTimeZone(quiet, fallback) {
|
|
31
|
+
return quiet.effective_time_zone ?? quiet.time_zone ?? fallback;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether the person picks their own time zone. One an administrator set, or
|
|
35
|
+
* one their application supplies, wins over a saved one, so a picker there
|
|
36
|
+
* would change nothing.
|
|
37
|
+
*/
|
|
38
|
+
export function quietTimeZoneEditable(quiet) {
|
|
39
|
+
return (quiet.time_zone_source !== "administrator" &&
|
|
40
|
+
quiet.time_zone_source !== "application");
|
|
41
|
+
}
|
|
42
|
+
export function startQuietDraft(quiet, fallbackTimeZone) {
|
|
43
|
+
const saved = quiet.quiet_channel?.binding_id;
|
|
44
|
+
const offered = saved !== undefined &&
|
|
45
|
+
quiet.quiet_channel_options.some((option) => option.binding_id === saved);
|
|
46
|
+
return {
|
|
47
|
+
channels: {
|
|
48
|
+
email: quiet.channels.email,
|
|
49
|
+
slack: quiet.channels.slack,
|
|
50
|
+
telegram: quiet.channels.telegram,
|
|
51
|
+
},
|
|
52
|
+
criticalBreakthrough: quiet.critical_breakthrough,
|
|
53
|
+
quietChannelBindingId: offered ? saved : undefined,
|
|
54
|
+
timeZone: quietTimeZone(quiet, fallbackTimeZone),
|
|
55
|
+
whenWithheld: quiet.when_withheld,
|
|
56
|
+
// Nothing saved yet: suggest every night, so turning quiet hours on is
|
|
57
|
+
// one press. Saved and empty stays empty.
|
|
58
|
+
windows: quiet.configured
|
|
59
|
+
? quiet.windows.map((window) => ({
|
|
60
|
+
days: [...window.days],
|
|
61
|
+
end: window.end,
|
|
62
|
+
start: window.start,
|
|
63
|
+
}))
|
|
64
|
+
: [QUIET_SUGGESTED_WINDOW],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function signature(draft) {
|
|
68
|
+
return JSON.stringify([
|
|
69
|
+
draft.windows.map((window) => [
|
|
70
|
+
[...window.days].sort((a, b) => a - b),
|
|
71
|
+
window.start,
|
|
72
|
+
window.end,
|
|
73
|
+
]),
|
|
74
|
+
QUIET_CHANNELS.map((channel) => draft.channels[channel]),
|
|
75
|
+
draft.criticalBreakthrough,
|
|
76
|
+
draft.whenWithheld,
|
|
77
|
+
draft.whenWithheld === "quiet_channel" ? draft.quietChannelBindingId : null,
|
|
78
|
+
draft.timeZone,
|
|
79
|
+
]);
|
|
80
|
+
}
|
|
81
|
+
/** Whether the person changed anything since the tab showed what is saved. */
|
|
82
|
+
export function quietEdited(draft, quiet, fallbackTimeZone) {
|
|
83
|
+
return (draft !== null &&
|
|
84
|
+
signature(draft) !== signature(startQuietDraft(quiet, fallbackTimeZone)));
|
|
85
|
+
}
|
|
86
|
+
/** Whether Save would change anything. Nothing saved yet always would. */
|
|
87
|
+
export function quietChanged(draft, quiet, fallbackTimeZone) {
|
|
88
|
+
return !quiet.configured || quietEdited(draft, quiet, fallbackTimeZone);
|
|
89
|
+
}
|
|
90
|
+
/** Whether any channel keeps messages back, so "where they go" matters. */
|
|
91
|
+
export function quietWithholds(draft) {
|
|
92
|
+
return QUIET_CHANNELS.some((channel) => draft.channels[channel] === "withhold");
|
|
93
|
+
}
|
|
94
|
+
export function quietSaveRequest(draft) {
|
|
95
|
+
return {
|
|
96
|
+
channels: { ...draft.channels },
|
|
97
|
+
critical_breakthrough: draft.criticalBreakthrough,
|
|
98
|
+
...(draft.whenWithheld === "quiet_channel" &&
|
|
99
|
+
draft.quietChannelBindingId !== undefined
|
|
100
|
+
? { quiet_channel_binding_id: draft.quietChannelBindingId }
|
|
101
|
+
: {}),
|
|
102
|
+
time_zone: draft.timeZone,
|
|
103
|
+
when_withheld: draft.whenWithheld,
|
|
104
|
+
windows: draft.windows.map((window) => ({
|
|
105
|
+
days: [...window.days].sort((a, b) => a - b),
|
|
106
|
+
end: window.end,
|
|
107
|
+
start: window.start,
|
|
108
|
+
})),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const TIME = /^(?:[01]\d|2[0-3]):[0-5]\d$/u;
|
|
112
|
+
/**
|
|
113
|
+
* The mistakes the panel can see before asking: a period with no days, a
|
|
114
|
+
* missing time, a period that starts and ends together, and a quiet channel
|
|
115
|
+
* not chosen. The service checks everything again.
|
|
116
|
+
*/
|
|
117
|
+
export function quietDraftErrors(draft) {
|
|
118
|
+
const errors = {};
|
|
119
|
+
if (draft.windows.length > QUIET_WINDOWS_MAX)
|
|
120
|
+
errors["/windows"] = "window_limit";
|
|
121
|
+
draft.windows.forEach((window, index) => {
|
|
122
|
+
const at = `/windows/${String(index)}`;
|
|
123
|
+
if (window.days.length === 0)
|
|
124
|
+
errors[`${at}/days`] = "window_days_invalid";
|
|
125
|
+
if (!TIME.test(window.start))
|
|
126
|
+
errors[`${at}/start`] = "window_time_invalid";
|
|
127
|
+
if (!TIME.test(window.end))
|
|
128
|
+
errors[`${at}/end`] = "window_time_invalid";
|
|
129
|
+
else if (window.start === window.end)
|
|
130
|
+
errors[`${at}/end`] = "window_empty";
|
|
131
|
+
});
|
|
132
|
+
if (draft.whenWithheld === "quiet_channel" &&
|
|
133
|
+
draft.quietChannelBindingId === undefined)
|
|
134
|
+
errors["/quiet_channel_binding_id"] = "quiet_channel_required";
|
|
135
|
+
return errors;
|
|
136
|
+
}
|
|
137
|
+
/** The service's field errors, by field, from a `request_invalid` problem. */
|
|
138
|
+
export function quietProblemErrors(problem) {
|
|
139
|
+
const errors = {};
|
|
140
|
+
for (const error of problem.field_errors ?? [])
|
|
141
|
+
errors[error.field.startsWith("/") ? error.field : `/${error.field}`] ??=
|
|
142
|
+
error.code;
|
|
143
|
+
return errors;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* The control a field error belongs to, by the `data-action` both editors
|
|
147
|
+
* give it, so focus can go there after a refused save.
|
|
148
|
+
*/
|
|
149
|
+
export function quietErrorControl(field, draft) {
|
|
150
|
+
const window = /^\/windows\/(\d+)\/(days|start|end)/u.exec(field);
|
|
151
|
+
if (window) {
|
|
152
|
+
const [, index = "0", part = "days"] = window;
|
|
153
|
+
return part === "days"
|
|
154
|
+
? `quiet:day:${index}:${String(QUIET_DAYS[0])}`
|
|
155
|
+
: `quiet:${part}:${index}`;
|
|
156
|
+
}
|
|
157
|
+
const channel = /^\/channels\/(telegram|slack|email)/u.exec(field)?.[1];
|
|
158
|
+
if (channel !== undefined)
|
|
159
|
+
return `quiet:channel:${channel}:${draft.channels[channel]}`;
|
|
160
|
+
if (field === "/windows")
|
|
161
|
+
return "quiet:add";
|
|
162
|
+
if (field.startsWith("/quiet_channel"))
|
|
163
|
+
return draft.whenWithheld === "quiet_channel"
|
|
164
|
+
? "quiet:quiet-channel"
|
|
165
|
+
: "quiet:withheld:quiet_channel";
|
|
166
|
+
if (field === "/time_zone")
|
|
167
|
+
return "quiet:time-zone";
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
/** A period ending at or before its start runs past midnight. */
|
|
171
|
+
export function quietOvernight(window) {
|
|
172
|
+
return TIME.test(window.start) && TIME.test(window.end)
|
|
173
|
+
? window.end < window.start
|
|
174
|
+
: false;
|
|
175
|
+
}
|
|
176
|
+
export function setQuietWindow(draft, index, change) {
|
|
177
|
+
return {
|
|
178
|
+
...draft,
|
|
179
|
+
windows: draft.windows.map((window, position) => position === index ? { ...window, ...change } : window),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
export function toggleQuietDay(draft, index, day) {
|
|
183
|
+
const window = draft.windows[index];
|
|
184
|
+
if (window === undefined)
|
|
185
|
+
return draft;
|
|
186
|
+
const days = window.days.includes(day)
|
|
187
|
+
? window.days.filter((candidate) => candidate !== day)
|
|
188
|
+
: [...window.days, day].sort((a, b) => a - b);
|
|
189
|
+
return setQuietWindow(draft, index, { days });
|
|
190
|
+
}
|
|
191
|
+
export function addQuietWindow(draft) {
|
|
192
|
+
if (draft.windows.length >= QUIET_WINDOWS_MAX)
|
|
193
|
+
return draft;
|
|
194
|
+
return { ...draft, windows: [...draft.windows, QUIET_SUGGESTED_WINDOW] };
|
|
195
|
+
}
|
|
196
|
+
export function removeQuietWindow(draft, index) {
|
|
197
|
+
return {
|
|
198
|
+
...draft,
|
|
199
|
+
windows: draft.windows.filter((_, position) => position !== index),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** Day names in the reader's language: short for the toggle, long for its name. */
|
|
203
|
+
export function quietDayName(locale, day, width) {
|
|
204
|
+
// 1 January 2024 was a Monday.
|
|
205
|
+
const date = new Date(Date.UTC(2024, 0, day));
|
|
206
|
+
try {
|
|
207
|
+
return new Intl.DateTimeFormat(locale, {
|
|
208
|
+
timeZone: "UTC",
|
|
209
|
+
weekday: width,
|
|
210
|
+
}).format(date);
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return new Intl.DateTimeFormat("en", {
|
|
214
|
+
timeZone: "UTC",
|
|
215
|
+
weekday: width,
|
|
216
|
+
}).format(date);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* When quiet hours end, as the person reads a clock in their zone: "07:00",
|
|
221
|
+
* or with the day when it is more than a day away.
|
|
222
|
+
*/
|
|
223
|
+
export function quietEndsText(locale, endsAt, timeZone, now = new Date()) {
|
|
224
|
+
const end = new Date(endsAt);
|
|
225
|
+
const options = {
|
|
226
|
+
hour: "2-digit",
|
|
227
|
+
minute: "2-digit",
|
|
228
|
+
...(end.getTime() - now.getTime() > 24 * 60 * 60 * 1000
|
|
229
|
+
? { weekday: "short" }
|
|
230
|
+
: {}),
|
|
231
|
+
};
|
|
232
|
+
try {
|
|
233
|
+
return new Intl.DateTimeFormat(locale, { ...options, timeZone }).format(end);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return new Intl.DateTimeFormat(locale, options).format(end);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/** Every named zone the browser knows, with the current one always included. */
|
|
240
|
+
export function quietTimeZones(current) {
|
|
241
|
+
let zones;
|
|
242
|
+
try {
|
|
243
|
+
zones = Intl.supportedValuesOf("timeZone");
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
zones = [];
|
|
247
|
+
}
|
|
248
|
+
return [...new Set([...zones, "UTC", current])].sort((a, b) => a.localeCompare(b));
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=quiet-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quiet-view.js","sourceRoot":"","sources":["../../src/recipient/quiet-view.ts"],"names":[],"mappings":"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"}
|
package/dist/recipient/view.d.ts
CHANGED
|
@@ -27,6 +27,8 @@ export interface RecipientCategoryView {
|
|
|
27
27
|
readonly description?: string;
|
|
28
28
|
readonly enabled: boolean;
|
|
29
29
|
readonly canTurnOff: boolean;
|
|
30
|
+
/** The urgency its messages escalate at, for "Used for" (FXO-3672). */
|
|
31
|
+
readonly level?: "low" | "normal" | "high" | "critical";
|
|
30
32
|
}
|
|
31
33
|
export interface RecipientView {
|
|
32
34
|
readonly accentColor: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/recipient/view.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oCAAoC,GAIrC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/recipient/view.ts"],"names":[],"mappings":"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"}
|
package/dist/webhooks.d.ts
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
import { verifyWebhookSignature } from "@whooshbang/contracts";
|
|
2
2
|
import type { VerifyWebhookSignatureOptions, WebhookVerificationFailureReason, WhooshBangEventV1ContractDocument } from "@whooshbang/contracts";
|
|
3
|
+
/** A signed event this SDK knows, typed by its `type`. */
|
|
3
4
|
export interface VerifiedWhooshBangEvent {
|
|
4
5
|
readonly attempt: number;
|
|
5
6
|
readonly event: WhooshBangEventV1ContractDocument;
|
|
6
7
|
readonly eventId: string;
|
|
8
|
+
readonly recognized: true;
|
|
9
|
+
readonly timestamp: number;
|
|
10
|
+
readonly verified: true;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A correctly signed event of a type newer than this SDK. Answer it with a
|
|
14
|
+
* 2xx: a 4xx stops its delivery and holds the endpoint's backlog behind it.
|
|
15
|
+
*/
|
|
16
|
+
export interface UnrecognizedWhooshBangEvent {
|
|
17
|
+
readonly created_at: string;
|
|
18
|
+
readonly data: Readonly<Record<string, unknown>>;
|
|
19
|
+
readonly environment: string;
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly organization_id: string;
|
|
22
|
+
readonly project_id: string;
|
|
23
|
+
readonly schema: "whooshbang.event.v1";
|
|
24
|
+
readonly type: string;
|
|
25
|
+
}
|
|
26
|
+
export interface VerifiedUnrecognizedWhooshBangEvent {
|
|
27
|
+
readonly attempt: number;
|
|
28
|
+
readonly event: UnrecognizedWhooshBangEvent;
|
|
29
|
+
readonly eventId: string;
|
|
30
|
+
readonly recognized: false;
|
|
7
31
|
readonly timestamp: number;
|
|
8
32
|
readonly verified: true;
|
|
9
33
|
}
|
|
@@ -11,7 +35,7 @@ export interface RejectedWhooshBangEvent {
|
|
|
11
35
|
readonly reason: WebhookVerificationFailureReason | "event_contract_mismatch" | "event_id_mismatch";
|
|
12
36
|
readonly verified: false;
|
|
13
37
|
}
|
|
14
|
-
export type WhooshBangEventVerification = RejectedWhooshBangEvent | VerifiedWhooshBangEvent;
|
|
38
|
+
export type WhooshBangEventVerification = RejectedWhooshBangEvent | VerifiedUnrecognizedWhooshBangEvent | VerifiedWhooshBangEvent;
|
|
15
39
|
/**
|
|
16
40
|
* Verifies a signed customer event and returns its typed body.
|
|
17
41
|
*
|
|
@@ -23,6 +47,11 @@ export type WhooshBangEventVerification = RejectedWhooshBangEvent | VerifiedWhoo
|
|
|
23
47
|
* checks pass, so unsigned or stale bytes are never decoded. Supplying both
|
|
24
48
|
* the previous and the current secret verifies through a rotation-overlap
|
|
25
49
|
* window without a gap.
|
|
50
|
+
*
|
|
51
|
+
* Newer events stay verifiable, the same way API responses do. A known type
|
|
52
|
+
* with fields or enum values added after this SDK was built verifies as that
|
|
53
|
+
* type, with the new values kept. A type this SDK has never seen verifies as
|
|
54
|
+
* `recognized: false` with only the shared envelope checked; answer it 2xx.
|
|
26
55
|
*/
|
|
27
56
|
export declare function verifyWhooshBangEvent(options: VerifyWebhookSignatureOptions): Promise<WhooshBangEventVerification>;
|
|
28
57
|
/** Signature-only verification over the exact raw request bytes. */
|
package/dist/webhooks.js
CHANGED
|
@@ -1,4 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validateAgentBindingDegradedEvent, validateEscalationClosedEvent, validateInteractionExpiredEvent, validateInteractionReceivedEvent, validateMessageDeliveredEvent, validateMessageExpiredEvent, validateMessageFailedEvent, validateMessageProviderAcceptedEvent, validateSubscriptionActivatedEvent, validateSubscriptionAssertedEvent, validateSubscriptionAssertedRevokedEvent, validateSubscriptionRevokedEvent, verifyWebhookSignature, } from "@whooshbang/contracts";
|
|
2
|
+
import { validateAdditiveCompatible } from "./additive-compatibility.js";
|
|
3
|
+
/**
|
|
4
|
+
* Each event type this SDK version knows, with its own validator. The `Record`
|
|
5
|
+
* makes the compiler refuse a contract update that adds a type without one.
|
|
6
|
+
*/
|
|
7
|
+
const EVENT_VALIDATORS = {
|
|
8
|
+
"agent_binding.degraded": validateAgentBindingDegradedEvent,
|
|
9
|
+
"escalation.closed": validateEscalationClosedEvent,
|
|
10
|
+
"interaction.expired": validateInteractionExpiredEvent,
|
|
11
|
+
"interaction.received": validateInteractionReceivedEvent,
|
|
12
|
+
"message.delivered": validateMessageDeliveredEvent,
|
|
13
|
+
"message.expired": validateMessageExpiredEvent,
|
|
14
|
+
"message.failed": validateMessageFailedEvent,
|
|
15
|
+
"message.provider_accepted": validateMessageProviderAcceptedEvent,
|
|
16
|
+
"subscription.activated": validateSubscriptionActivatedEvent,
|
|
17
|
+
"subscription.asserted": validateSubscriptionAssertedEvent,
|
|
18
|
+
"subscription.asserted_revoked": validateSubscriptionAssertedRevokedEvent,
|
|
19
|
+
"subscription.revoked": validateSubscriptionRevokedEvent,
|
|
20
|
+
};
|
|
21
|
+
function isKnownEventType(type) {
|
|
22
|
+
return typeof type === "string" && Object.hasOwn(EVENT_VALIDATORS, type);
|
|
23
|
+
}
|
|
24
|
+
function isNonEmptyString(value) {
|
|
25
|
+
return typeof value === "string" && value.length > 0;
|
|
26
|
+
}
|
|
27
|
+
/** The version-1 envelope every event shares, whatever its type. */
|
|
28
|
+
function isEventEnvelope(value) {
|
|
29
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const event = value;
|
|
33
|
+
return (event.schema === "whooshbang.event.v1" &&
|
|
34
|
+
isNonEmptyString(event.id) &&
|
|
35
|
+
isNonEmptyString(event.type) &&
|
|
36
|
+
isNonEmptyString(event.created_at) &&
|
|
37
|
+
isNonEmptyString(event.organization_id) &&
|
|
38
|
+
isNonEmptyString(event.project_id) &&
|
|
39
|
+
isNonEmptyString(event.environment) &&
|
|
40
|
+
typeof event.data === "object" &&
|
|
41
|
+
event.data !== null &&
|
|
42
|
+
!Array.isArray(event.data));
|
|
43
|
+
}
|
|
2
44
|
/**
|
|
3
45
|
* Verifies a signed customer event and returns its typed body.
|
|
4
46
|
*
|
|
@@ -10,6 +52,11 @@ import { validateWhooshBangEvent, verifyWebhookSignature, } from "@whooshbang/co
|
|
|
10
52
|
* checks pass, so unsigned or stale bytes are never decoded. Supplying both
|
|
11
53
|
* the previous and the current secret verifies through a rotation-overlap
|
|
12
54
|
* window without a gap.
|
|
55
|
+
*
|
|
56
|
+
* Newer events stay verifiable, the same way API responses do. A known type
|
|
57
|
+
* with fields or enum values added after this SDK was built verifies as that
|
|
58
|
+
* type, with the new values kept. A type this SDK has never seen verifies as
|
|
59
|
+
* `recognized: false` with only the shared envelope checked; answer it 2xx.
|
|
13
60
|
*/
|
|
14
61
|
export async function verifyWhooshBangEvent(options) {
|
|
15
62
|
const verification = await verifyWebhookSignature(options);
|
|
@@ -23,7 +70,7 @@ export async function verifyWhooshBangEvent(options) {
|
|
|
23
70
|
catch {
|
|
24
71
|
return { reason: "event_contract_mismatch", verified: false };
|
|
25
72
|
}
|
|
26
|
-
if (!
|
|
73
|
+
if (!isEventEnvelope(parsed)) {
|
|
27
74
|
return { reason: "event_contract_mismatch", verified: false };
|
|
28
75
|
}
|
|
29
76
|
// The signed `webhook-id` and the body's own identifier must agree, or a
|
|
@@ -32,13 +79,19 @@ export async function verifyWhooshBangEvent(options) {
|
|
|
32
79
|
if (parsed.id !== verification.eventId) {
|
|
33
80
|
return { reason: "event_id_mismatch", verified: false };
|
|
34
81
|
}
|
|
35
|
-
|
|
82
|
+
const delivery = {
|
|
36
83
|
attempt: verification.attempt,
|
|
37
|
-
event: parsed,
|
|
38
84
|
eventId: verification.eventId,
|
|
39
85
|
timestamp: verification.timestamp,
|
|
40
86
|
verified: true,
|
|
41
87
|
};
|
|
88
|
+
if (!isKnownEventType(parsed.type)) {
|
|
89
|
+
return { ...delivery, event: parsed, recognized: false };
|
|
90
|
+
}
|
|
91
|
+
if (!validateAdditiveCompatible(parsed, EVENT_VALIDATORS[parsed.type])) {
|
|
92
|
+
return { reason: "event_contract_mismatch", verified: false };
|
|
93
|
+
}
|
|
94
|
+
return { ...delivery, event: parsed, recognized: true };
|
|
42
95
|
}
|
|
43
96
|
/** Signature-only verification over the exact raw request bytes. */
|
|
44
97
|
export async function verifyWhooshBangWebhook(options) {
|
package/dist/webhooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whooshbang/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "JavaScript client and browser recipient settings UI for WhooshBang V1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,6 +52,16 @@
|
|
|
52
52
|
"import": "./dist/recipient/i18n/catalog.js",
|
|
53
53
|
"default": "./dist/recipient/i18n/catalog.js"
|
|
54
54
|
},
|
|
55
|
+
"./recipient/order": {
|
|
56
|
+
"types": "./dist/recipient/order-view.d.ts",
|
|
57
|
+
"import": "./dist/recipient/order-view.js",
|
|
58
|
+
"default": "./dist/recipient/order-view.js"
|
|
59
|
+
},
|
|
60
|
+
"./recipient/quiet": {
|
|
61
|
+
"types": "./dist/recipient/quiet-view.d.ts",
|
|
62
|
+
"import": "./dist/recipient/quiet-view.js",
|
|
63
|
+
"default": "./dist/recipient/quiet-view.js"
|
|
64
|
+
},
|
|
55
65
|
"./package.json": "./package.json"
|
|
56
66
|
},
|
|
57
67
|
"bin": {
|
|
@@ -64,7 +74,7 @@
|
|
|
64
74
|
"type-check": "tsc --noEmit -p tsconfig.json"
|
|
65
75
|
},
|
|
66
76
|
"dependencies": {
|
|
67
|
-
"@whooshbang/contracts": "
|
|
77
|
+
"@whooshbang/contracts": "5.0.0"
|
|
68
78
|
},
|
|
69
79
|
"engines": {
|
|
70
80
|
"node": ">=22.13.0"
|