@usequeek/app-sdk 0.5.1 → 0.6.1

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.
Files changed (76) hide show
  1. package/README.md +179 -12
  2. package/dist/app-auth.d.ts +9 -1
  3. package/dist/app-auth.d.ts.map +1 -1
  4. package/dist/app-auth.js +11 -1
  5. package/dist/app-auth.js.map +1 -1
  6. package/dist/auth-fetch.d.ts +91 -0
  7. package/dist/auth-fetch.d.ts.map +1 -0
  8. package/dist/auth-fetch.js +263 -0
  9. package/dist/auth-fetch.js.map +1 -0
  10. package/dist/browser.d.ts +25 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +27 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/client.d.ts +32 -10
  15. package/dist/client.d.ts.map +1 -1
  16. package/dist/client.js +6 -2
  17. package/dist/client.js.map +1 -1
  18. package/dist/frame.d.ts +233 -4
  19. package/dist/frame.d.ts.map +1 -1
  20. package/dist/frame.js +694 -19
  21. package/dist/frame.js.map +1 -1
  22. package/dist/handoff.d.ts +32 -2
  23. package/dist/handoff.d.ts.map +1 -1
  24. package/dist/handoff.js +2 -1
  25. package/dist/handoff.js.map +1 -1
  26. package/dist/hono.d.ts +13 -0
  27. package/dist/hono.d.ts.map +1 -1
  28. package/dist/hono.js +15 -0
  29. package/dist/hono.js.map +1 -1
  30. package/dist/index.d.ts +11 -7
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +10 -6
  33. package/dist/index.js.map +1 -1
  34. package/dist/install-handlers.d.ts +33 -8
  35. package/dist/install-handlers.d.ts.map +1 -1
  36. package/dist/install-handlers.js +133 -15
  37. package/dist/install-handlers.js.map +1 -1
  38. package/dist/merchant-schema.d.ts +1550 -68
  39. package/dist/merchant-schema.d.ts.map +1 -1
  40. package/dist/merchant-schema.js +1 -1
  41. package/dist/proxy.d.ts +122 -0
  42. package/dist/proxy.d.ts.map +1 -0
  43. package/dist/proxy.js +204 -0
  44. package/dist/proxy.js.map +1 -0
  45. package/dist/react.d.ts +78 -0
  46. package/dist/react.d.ts.map +1 -0
  47. package/dist/react.js +262 -0
  48. package/dist/react.js.map +1 -0
  49. package/dist/scopes.d.ts +174 -0
  50. package/dist/scopes.d.ts.map +1 -0
  51. package/dist/scopes.js +297 -0
  52. package/dist/scopes.js.map +1 -0
  53. package/dist/server.d.ts +1 -1
  54. package/dist/server.js +1 -1
  55. package/dist/session.d.ts +17 -5
  56. package/dist/session.d.ts.map +1 -1
  57. package/dist/session.js +35 -16
  58. package/dist/session.js.map +1 -1
  59. package/dist/store.d.ts +33 -0
  60. package/dist/store.d.ts.map +1 -1
  61. package/dist/store.js +114 -4
  62. package/dist/store.js.map +1 -1
  63. package/dist/theme.d.ts +100 -0
  64. package/dist/theme.d.ts.map +1 -0
  65. package/dist/theme.js +162 -0
  66. package/dist/theme.js.map +1 -0
  67. package/dist/tokens.d.ts +30 -15
  68. package/dist/tokens.d.ts.map +1 -1
  69. package/dist/tokens.js +57 -19
  70. package/dist/tokens.js.map +1 -1
  71. package/dist/webhooks.d.ts.map +1 -1
  72. package/dist/webhooks.js +1 -1
  73. package/dist/webhooks.js.map +1 -1
  74. package/package.json +21 -5
  75. package/CHANGELOG.md +0 -162
  76. package/openapi/merchant.json +0 -21452
package/dist/scopes.js ADDED
@@ -0,0 +1,297 @@
1
+ import { isInstallationGone, UnknownInstallationError } from "./app-auth.js";
2
+ import { newIdempotencyKey, QueekApiError, queekApiErrorFromResponse } from "./client.js";
3
+ import { isAllowedOpenTarget } from "./frame.js";
4
+ import { installationScopesEqual } from "./install-handlers.js";
5
+ import { resolveAppApiBase } from "./tokens.js";
6
+ /**
7
+ * Optional scopes (plan item 6, Shopify `scopes.query / request / revoke`
8
+ * parity — symbol names cited only).
9
+ *
10
+ * - `queryScopes`: the cached effective grant split against the app's own
11
+ * declared-optional list. Store-read only, never a fetch: the app-credential
12
+ * surface exposes the effective grant but no declared-optional list, so
13
+ * the split needs the app's manifest knowledge (passed at client
14
+ * construction). No network, no guessing.
15
+ * - `requestScopes`: builds the dashboard deep link that opens the
16
+ * merchant's consent screen in the dashboard. The SDK never renders
17
+ * consent — it hands the app a link shaped like the bridge
18
+ * `open`/`navigate` targets (dashboard-relative path, or an absolute URL
19
+ * under a given dashboard origin) for the app to open via `sendOpen` or
20
+ * redirect to. The consent screen itself ships with the dashboard (plan
21
+ * item 8), which honours this link shape.
22
+ * - `revokeScopes`: `POST
23
+ * /api/v1/apps/installations/{installation}/scopes/revoke` with the app
24
+ * JWT (same credential as mint/resync — never auth:sanctum, never the
25
+ * installation token). Body `{scopes[]}` (1–50, backend
26
+ * `RevokeAppScopesRequest`); an `Idempotency-Key` rides the write for
27
+ * discipline (generated when the caller does not supply one — the client
28
+ * write discipline), though the route is naturally idempotent: revoking
29
+ * a never-granted optional scope is 200 with no change. Required scopes
30
+ * refuse 422 `app_scope_required` (surfaced as `AppScopeRequiredError`).
31
+ * On 200 the cached grant is refreshed from the response and the cached
32
+ * token dropped only when the grant moved (same compare-and-clear as the
33
+ * scopes_update handler — the backend rewrites live token rows in place,
34
+ * so the drop is backstop, not mechanism).
35
+ *
36
+ * Types here are hand-written: the revoke endpoint and the scopes_update
37
+ * handoff live on the app-credential surface, which the frozen
38
+ * `openapi/merchant.json` does not cover (types are generated app-side by
39
+ * `queek app codegen`; the merchant spec file is never hand-edited).
40
+ */
41
+ /** 422 on the revoke endpoint: required scopes are never revocable (uninstall is the remedy). */
42
+ export const APP_SCOPE_REQUIRED_CODE = "app_scope_required";
43
+ /** 422 on the approve path: the scope is not declared by the live manifest version. */
44
+ export const APP_SCOPE_UNDECLARED_CODE = "app_scope_undeclared";
45
+ /** True for a required-scope refusal on the revoke endpoint (422 `app_scope_required`). */
46
+ export function isAppScopeRequired(status, code) {
47
+ return status === 422 && code === APP_SCOPE_REQUIRED_CODE;
48
+ }
49
+ /**
50
+ * A required-scope refusal, typed so callers switch on the class (or
51
+ * `code`), never on `message`. Carries the offending scopes when the
52
+ * backend named them.
53
+ */
54
+ export class AppScopeRequiredError extends QueekApiError {
55
+ scopes;
56
+ constructor(status, message, scopes) {
57
+ super({ status, code: APP_SCOPE_REQUIRED_CODE, message });
58
+ this.name = "AppScopeRequiredError";
59
+ this.scopes = scopes;
60
+ }
61
+ }
62
+ /** Build an `AppScopeRequiredError` from a parsed 422, tolerantly reading the named scopes. */
63
+ export function appScopeRequiredFromError(error) {
64
+ return new AppScopeRequiredError(error.status, error.message, readErrorScopes(error.errors));
65
+ }
66
+ function readErrorScopes(errors) {
67
+ if (typeof errors !== "object" || errors === null)
68
+ return [];
69
+ const scopes = errors.scopes;
70
+ if (!Array.isArray(scopes))
71
+ return [];
72
+ return scopes.filter((entry) => typeof entry === "string" && entry !== "");
73
+ }
74
+ /** Thrown when a scope list fails client-side validation — before any fetch. */
75
+ export class InvalidScopesError extends Error {
76
+ code = "invalid_scopes";
77
+ constructor(message) {
78
+ super(message);
79
+ this.name = "InvalidScopesError";
80
+ }
81
+ }
82
+ /** Backend `RevokeAppScopesRequest` bounds, mirrored client-side. */
83
+ export const MAX_SCOPE_LIST = 50;
84
+ export const MAX_SCOPE_LENGTH = 120;
85
+ /**
86
+ * Validate + normalise a scope list (trim, drop empties, dedupe keeping
87
+ * first order). Mirrors the backend contract (`required array min:1
88
+ * max:50`, string items) so a malformed call fails before any fetch.
89
+ */
90
+ export function normaliseScopeList(scopes) {
91
+ if (!Array.isArray(scopes)) {
92
+ throw new InvalidScopesError("Expected a scopes array.");
93
+ }
94
+ const cleaned = [];
95
+ for (const entry of scopes) {
96
+ if (typeof entry !== "string") {
97
+ throw new InvalidScopesError("Every scope must be a string.");
98
+ }
99
+ const trimmed = entry.trim();
100
+ if (trimmed === "" || cleaned.includes(trimmed))
101
+ continue;
102
+ if (trimmed.length > MAX_SCOPE_LENGTH) {
103
+ throw new InvalidScopesError(`Scope ${JSON.stringify(trimmed.slice(0, 40))} exceeds 120 characters.`);
104
+ }
105
+ cleaned.push(trimmed);
106
+ }
107
+ if (cleaned.length === 0) {
108
+ throw new InvalidScopesError("Name at least one scope.");
109
+ }
110
+ if (cleaned.length > MAX_SCOPE_LIST) {
111
+ throw new InvalidScopesError(`Too many scopes (max ${MAX_SCOPE_LIST}).`);
112
+ }
113
+ return cleaned;
114
+ }
115
+ /**
116
+ * Split a cached grant against the app's declared-optional list (the app's
117
+ * own manifest knowledge). Pure — no store, no network.
118
+ */
119
+ export function splitInstallationScopes(granted, declaredOptional = []) {
120
+ const declared = new Set(declaredOptional);
121
+ return {
122
+ granted: [...granted],
123
+ optional: granted.filter((scope) => declared.has(scope)),
124
+ };
125
+ }
126
+ /** App-API path of the revoke endpoint below the app base (sibling of the mint path). */
127
+ export function revokeScopesPath(installationId) {
128
+ return `/installations/${encodeURIComponent(installationId)}/scopes/revoke`;
129
+ }
130
+ /**
131
+ * Build the dashboard deep link that opens the merchant's consent screen
132
+ * in the dashboard. Pure — no store, no network. Shaped like the bridge
133
+ * `open` targets: a dashboard-relative path, or an absolute https URL
134
+ * under `dashboardOrigin` (refused exactly like `sendOpen` refuses a bad
135
+ * target).
136
+ *
137
+ * Link shape (the SDK↔dashboard contract the consent screen honours —
138
+ * the only query route the dashboard `AppsPage` serves):
139
+ * `/apps?app={slug}&view=scopes&scopes={a},{b}` (each scope
140
+ * URL-encoded, comma-separated). The link carries the slug + the scope
141
+ * list only: the dashboard resolves the installation from the signed-in
142
+ * store.
143
+ */
144
+ export function buildScopeRequestLink(options) {
145
+ const slug = options.appSlug.trim();
146
+ if (slug === "" || slug.includes("/") || slug.includes("\\")) {
147
+ throw new InvalidScopesError("A dashboard app slug is required to build the scope-request link.");
148
+ }
149
+ const requested = normaliseScopeList(options.scopes);
150
+ const path = `/apps?app=${encodeURIComponent(slug)}&view=scopes&scopes=${requested.map((scope) => encodeURIComponent(scope)).join(",")}`;
151
+ const origin = options.dashboardOrigin?.trim();
152
+ if (!origin)
153
+ return path;
154
+ let url;
155
+ try {
156
+ url = new URL(path, origin);
157
+ }
158
+ catch {
159
+ throw new InvalidScopesError("The dashboard origin is not a valid URL.");
160
+ }
161
+ const link = url.toString();
162
+ if (!isAllowedOpenTarget(link, origin)) {
163
+ throw new InvalidScopesError("The dashboard origin refuses the scope-request link.");
164
+ }
165
+ return link;
166
+ }
167
+ export function createInstallationScopesClient(options) {
168
+ if (!options.installationId || options.installationId.trim() === "") {
169
+ throw new InvalidScopesError("An installation id is required.");
170
+ }
171
+ if (!options.store) {
172
+ throw new InvalidScopesError("An InstallationStore is required.");
173
+ }
174
+ if (typeof options.signJwt !== "function") {
175
+ throw new InvalidScopesError("An app-JWT signer is required (e.g. `() => provider.signJwt()`).");
176
+ }
177
+ const fetchImpl = options.fetchImpl ?? fetch;
178
+ const userAgent = options.userAgent ?? "queek-app/1.0";
179
+ const allowedApiHosts = options.allowedApiHosts ?? [];
180
+ /**
181
+ * The cached grant split — store-read only, never a fetch. The optional
182
+ * half needs the app's declared-optional list (the app's own manifest
183
+ * knowledge: the app surface exposes the effective grant but no declared
184
+ * list), from the per-call option, the client option, or empty.
185
+ */
186
+ async function queryScopes(queryOptions = {}) {
187
+ const row = await options.store.getInstallation(options.installationId);
188
+ if (!row)
189
+ throw new UnknownInstallationError(options.installationId);
190
+ return splitInstallationScopes(row.scopes, queryOptions.optionalScopes ?? options.optionalScopes ?? []);
191
+ }
192
+ /**
193
+ * The dashboard deep link that opens the merchant's consent screen in
194
+ * the dashboard. Pure (no store, no network): the app opens it via
195
+ * `sendOpen` or a redirect and the merchant consents in the dashboard
196
+ * (shipped with dashboard item 8). Shaped like the bridge `open`
197
+ * targets — dashboard-relative, or absolute under the dashboard origin
198
+ * when one is configured.
199
+ */
200
+ function requestScopes(scopes, linkOptions = {}) {
201
+ const appSlug = linkOptions.appSlug ?? options.appSlug;
202
+ if (!appSlug) {
203
+ throw new InvalidScopesError("requestScopes needs the app slug: pass `appSlug` or per-call `appSlug`.");
204
+ }
205
+ return buildScopeRequestLink({
206
+ appSlug,
207
+ scopes,
208
+ dashboardOrigin: linkOptions.dashboardOrigin ?? options.dashboardOrigin,
209
+ });
210
+ }
211
+ /**
212
+ * App-initiated revoke of optional scopes (backend
213
+ * `AppInstallationController::revokeScopes`): the app JWT signs the call
214
+ * (same credential as mint/resync), an `Idempotency-Key` rides the write
215
+ * for discipline only (the route is naturally idempotent), and on 200
216
+ * the cached grant is refreshed from the response with the cached token
217
+ * dropped only when the grant moved (same compare-and-clear as the
218
+ * scopes_update handler — backstop, since the backend rewrites live
219
+ * token rows in place). A required scope refuses 422
220
+ * `app_scope_required` as `AppScopeRequiredError`; a gone installation
221
+ * purges the local row and rethrows; anything else propagates untouched.
222
+ * A 401 never halts here — the mint path owns that mapping and halts on
223
+ * its next call.
224
+ */
225
+ async function revokeScopes(scopes, revokeOptions = {}) {
226
+ const requested = normaliseScopeList(scopes);
227
+ const row = await options.store.getInstallation(options.installationId);
228
+ if (!row)
229
+ throw new UnknownInstallationError(options.installationId);
230
+ const appBase = resolveAppApiBase(row.apiBase, allowedApiHosts);
231
+ // Signed per attempt (never reused past its ≤10-min window, never logged).
232
+ const jwt = options.signJwt();
233
+ const url = `${appBase}${revokeScopesPath(options.installationId)}`;
234
+ const headers = new Headers();
235
+ headers.set("Authorization", `Bearer ${jwt}`);
236
+ headers.set("Accept", "application/json");
237
+ headers.set("Content-Type", "application/json");
238
+ headers.set("User-Agent", userAgent);
239
+ headers.set("Idempotency-Key", revokeOptions.idempotencyKey ?? newIdempotencyKey());
240
+ let response;
241
+ try {
242
+ response = await fetchImpl(url, {
243
+ method: "POST",
244
+ headers,
245
+ body: JSON.stringify({ scopes: requested }),
246
+ signal: revokeOptions.signal,
247
+ });
248
+ }
249
+ catch (cause) {
250
+ throw new QueekApiError({
251
+ status: 0,
252
+ code: "network_error",
253
+ message: cause instanceof Error ? `Could not reach Queek: ${cause.message}` : "Could not reach Queek.",
254
+ });
255
+ }
256
+ const text = await response.text();
257
+ const parsed = text === "" ? null : tryParseJson(text);
258
+ if (!response.ok) {
259
+ const error = queekApiErrorFromResponse(response.status, parsed, response.headers);
260
+ if (isAppScopeRequired(error.status, error.code))
261
+ throw appScopeRequiredFromError(error);
262
+ if (error.status === 404 && isInstallationGone(error.code)) {
263
+ await options.store.deleteInstallation(options.installationId);
264
+ }
265
+ throw error;
266
+ }
267
+ const updated = parseRevokeBody(parsed);
268
+ // Same compare-and-clear as the scopes_update handler: an unchanged
269
+ // grant (e.g. revoking a never-granted scope — idempotent 200) keeps
270
+ // the cached token, since it still matches the live grant.
271
+ const grantChanged = !installationScopesEqual(row.scopes, updated);
272
+ await options.store.saveInstallation({ ...row, scopes: updated, updatedAt: new Date().toISOString() });
273
+ if (grantChanged) {
274
+ await options.store.clearCachedToken(options.installationId);
275
+ }
276
+ return updated;
277
+ }
278
+ return { queryScopes, requestScopes, revokeScopes };
279
+ }
280
+ /** Read the 200 revoke response (`{installation: {p_id}, scopes}`) — the refreshed effective grant. */
281
+ function parseRevokeBody(body) {
282
+ const record = (typeof body === "object" && body !== null ? body : {});
283
+ const scopes = record.scopes;
284
+ if (!Array.isArray(scopes) || !scopes.every((scope) => typeof scope === "string")) {
285
+ throw new Error("Malformed revoke response: expected {scopes: string[]}.");
286
+ }
287
+ return [...scopes];
288
+ }
289
+ function tryParseJson(text) {
290
+ try {
291
+ return JSON.parse(text);
292
+ }
293
+ catch {
294
+ return { message: text.slice(0, 500) };
295
+ }
296
+ }
297
+ //# sourceMappingURL=scopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"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"}
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Server-only entry (S4 stage 2): session-token verification needs the
2
+ * Server-only entry: session-token verification needs the
3
3
  * per-installation `embsec_…` secret, which must never enter a browser
4
4
  * bundle. Import the verifier from `@usequeek/app-sdk/server`, never from
5
5
  * the main entry.
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Server-only entry (S4 stage 2): session-token verification needs the
2
+ * Server-only entry: session-token verification needs the
3
3
  * per-installation `embsec_…` secret, which must never enter a browser
4
4
  * bundle. Import the verifier from `@usequeek/app-sdk/server`, never from
5
5
  * the main entry.
package/dist/session.d.ts CHANGED
@@ -1,8 +1,16 @@
1
1
  /**
2
- * Dashboard session tokens (S4 stage 2): short-lived HS256 JWTs the backend
3
- * mints per installation for the framed merchant page. The app backend
4
- * verifies them with the per-installation `embsec_…` secret before trusting
5
- * any call that carries one.
2
+ * Dashboard session tokens: short-lived HS256 JWTs the backend mints per
3
+ * installation for the framed merchant page. The app backend verifies them
4
+ * with the per-installation `embsec_…` secret before trusting any call
5
+ * that carries one.
6
+ *
7
+ * ONE token type, exactly Shopify's `id_token` shape: the dashboard puts
8
+ * the same token in the first-load URL param (`queek_token`, stripped on
9
+ * arrival) and answers bridge `ready` requests with it, so the app's
10
+ * exchange endpoint verifies first-load and refresh tokens with this one
11
+ * verifier. No purpose split: extra claims the mint may carry are ignored,
12
+ * never gated — identity binding (installation, audience, issuer, expiry)
13
+ * is the whole check.
6
14
  *
7
15
  * Server-only: the secret must never enter a browser bundle, so this module
8
16
  * ships behind the `./server` export, not the main entry. Style mirrors
@@ -36,7 +44,11 @@ export interface VerifySessionTokenOptions {
36
44
  secret: string;
37
45
  /** Single expected audience: the app slug. */
38
46
  audience: string;
39
- /** Expected issuer: the Queek api_base. */
47
+ /**
48
+ * Expected issuer: the handoff `api_base` VERBATIM
49
+ * (`installation.apiBase` — it equals the bare `app.url` the backend
50
+ * signs as `iss`). Never a prefix or a suffix of it.
51
+ */
40
52
  issuer: string;
41
53
  /**
42
54
  * The installation row the token must belong to (the app backend's own
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,mEAAmE;AACnE,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,cAAc,GACd,kBAAkB,CAAC;AAEvB,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAC,CA2ChG;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC,mEAAmE;AACnE,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAElD,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,SAAS,GACT,eAAe,GACf,gBAAgB,GAChB,cAAc,GACd,kBAAkB,CAAC;AAEvB,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAUhG;AAkDD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOvE"}
package/dist/session.js CHANGED
@@ -1,9 +1,17 @@
1
1
  import { decodeJwt, decodeProtectedHeader, jwtVerify } from "jose";
2
2
  /**
3
- * Dashboard session tokens (S4 stage 2): short-lived HS256 JWTs the backend
4
- * mints per installation for the framed merchant page. The app backend
5
- * verifies them with the per-installation `embsec_…` secret before trusting
6
- * any call that carries one.
3
+ * Dashboard session tokens: short-lived HS256 JWTs the backend mints per
4
+ * installation for the framed merchant page. The app backend verifies them
5
+ * with the per-installation `embsec_…` secret before trusting any call
6
+ * that carries one.
7
+ *
8
+ * ONE token type, exactly Shopify's `id_token` shape: the dashboard puts
9
+ * the same token in the first-load URL param (`queek_token`, stripped on
10
+ * arrival) and answers bridge `ready` requests with it, so the app's
11
+ * exchange endpoint verifies first-load and refresh tokens with this one
12
+ * verifier. No purpose split: extra claims the mint may carry are ignored,
13
+ * never gated — identity binding (installation, audience, issuer, expiry)
14
+ * is the whole check.
7
15
  *
8
16
  * Server-only: the secret must never enter a browser bundle, so this module
9
17
  * ships behind the `./server` export, not the main entry. Style mirrors
@@ -20,6 +28,22 @@ export async function verifySessionToken(token, options) {
20
28
  return result.ok;
21
29
  }
22
30
  export async function verifySessionTokenDetailed(token, options) {
31
+ const envelope = await verifyTokenEnvelope(token, options);
32
+ if (!envelope.ok)
33
+ return envelope;
34
+ const claims = readSessionClaims(envelope.payload);
35
+ const { expected } = options;
36
+ if (!claims || !bindingMatches(claims, expected)) {
37
+ return { ok: false, reason: "binding_mismatch" };
38
+ }
39
+ return { ok: true, claims };
40
+ }
41
+ /**
42
+ * Envelope verification: presence, secret shape, algorithm pin, then
43
+ * signature + audience + issuer + expiry via jose. Binding checks stay
44
+ * with the caller.
45
+ */
46
+ async function verifyTokenEnvelope(token, options) {
23
47
  if (!token) {
24
48
  return { ok: false, reason: "missing_token" };
25
49
  }
@@ -36,7 +60,6 @@ export async function verifySessionTokenDetailed(token, options) {
36
60
  if (headerAlg !== null && headerAlg !== SESSION_TOKEN_ALG) {
37
61
  return { ok: false, reason: "wrong_algorithm" };
38
62
  }
39
- let payload;
40
63
  try {
41
64
  const verified = await jwtVerify(token, new TextEncoder().encode(secret), {
42
65
  algorithms: ["HS256"],
@@ -44,21 +67,17 @@ export async function verifySessionTokenDetailed(token, options) {
44
67
  issuer,
45
68
  clockTolerance: options.clockToleranceSeconds ?? SESSION_CLOCK_TOLERANCE_SECONDS,
46
69
  });
47
- payload = verified.payload;
70
+ return { ok: true, payload: verified.payload };
48
71
  }
49
72
  catch (error) {
50
73
  return { ok: false, reason: classifyJoseError(error) };
51
74
  }
52
- const claims = readSessionClaims(payload);
53
- const { expected } = options;
54
- if (!claims ||
55
- claims.installationId !== expected.installationId ||
56
- claims.vendorId !== expected.vendorId ||
57
- claims.appSlug !== expected.appSlug ||
58
- claims.appId !== expected.appId) {
59
- return { ok: false, reason: "binding_mismatch" };
60
- }
61
- return { ok: true, claims };
75
+ }
76
+ function bindingMatches(claims, expected) {
77
+ return (claims.installationId === expected.installationId &&
78
+ claims.vendorId === expected.vendorId &&
79
+ claims.appSlug === expected.appSlug &&
80
+ claims.appId === expected.appId);
62
81
  }
63
82
  /**
64
83
  * ROUTING HINT ONLY — the `installation_id` claim read WITHOUT verifying
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
package/dist/store.d.ts CHANGED
@@ -88,6 +88,17 @@ export interface InstallationStore {
88
88
  * mints fresh.
89
89
  */
90
90
  clearCachedToken(installationId: string): Promise<void> | void;
91
+ /**
92
+ * Forget one installation's cached token ONLY when the stored token still
93
+ * equals `expectedToken` (the value the failing call presented). A late
94
+ * drop after a concurrent re-mint is a no-op instead of wiping the fresh
95
+ * token. Returns true when the token was cleared.
96
+ *
97
+ * Optional so custom stores don't break: stores without it fall back to
98
+ * `defaultClearCachedTokenIfMatches` (`getInstallation` + compare +
99
+ * `clearCachedToken`). SQLite compare-and-clear is in-process only.
100
+ */
101
+ clearCachedTokenIfMatches?(installationId: string, expectedToken: string): Promise<boolean> | boolean;
91
102
  /** Forget EVERY cached token (kill switch) while keeping the rows. */
92
103
  clearAllCachedTokens(): Promise<void> | void;
93
104
  /**
@@ -121,6 +132,15 @@ export interface InstallationStore {
121
132
  /** Release a claim (callback failed; a retry may re-run). */
122
133
  releaseWebhookId(webhookId: string): Promise<void> | void;
123
134
  }
135
+ /**
136
+ * Portable compare-and-clear for custom `InstallationStore`s that don't
137
+ * implement `clearCachedTokenIfMatches`: read the row, compare the stored
138
+ * token to the failing call's value, and clear only on a match. Best-effort
139
+ * across processes (read-then-clear is not atomic here) — exact for the
140
+ * single-process case, and a concurrent re-mint still self-heals via the
141
+ * caller's retry. Returns true when the token was cleared.
142
+ */
143
+ export declare function defaultClearCachedTokenIfMatches(store: InstallationStore, installationId: string, expectedToken: string): Promise<boolean>;
124
144
  export interface SqliteStoreOptions {
125
145
  /** Path to the sqlite file. Use `:memory:` for tests. */
126
146
  path: string;
@@ -159,6 +179,7 @@ export declare class SqliteInstallationStore implements InstallationStore {
159
179
  getInstallation(installationId: string): InstallationRecord | null;
160
180
  listInstallations(): InstallationRecord[];
161
181
  clearCachedToken(installationId: string): void;
182
+ clearCachedTokenIfMatches(installationId: string, expectedToken: string): boolean;
162
183
  clearAllCachedTokens(): void;
163
184
  deleteInstallation(installationId: string): void;
164
185
  markInstallationPending(installationId: string): void;
@@ -172,6 +193,17 @@ export declare class SqliteInstallationStore implements InstallationStore {
172
193
  private pruneSeenIds;
173
194
  close(): void;
174
195
  }
196
+ /**
197
+ * Canonical integer-string form of a Queek `p_id`: the handoff contract
198
+ * types p_ids as strings and the backend casts on the wire, but the
199
+ * tolerance stays — a JSON integer would reach here as a JS number, and
200
+ * `node:sqlite` binds that number into a TEXT column as `"1021.0"`, which
201
+ * never equals the proxy `kid` (`"1021"`). Non-numeric pids pass through
202
+ * untouched.
203
+ */
204
+ export declare function normalisePid(value: unknown): string;
205
+ /** Nullable form for the store `p_id` (null stays null). */
206
+ export declare function normaliseNullablePid(value: unknown): string | null;
175
207
  /**
176
208
  * Current schema revision, stored as exactly one row in `schema_version`
177
209
  * (Postgres) and enforced by column-presence migration (SQLite).
@@ -233,6 +265,7 @@ export declare class PostgresInstallationStore implements InstallationStore {
233
265
  getInstallation(installationId: string): Promise<InstallationRecord | null>;
234
266
  listInstallations(): Promise<InstallationRecord[]>;
235
267
  clearCachedToken(installationId: string): Promise<void>;
268
+ clearCachedTokenIfMatches(installationId: string, expectedToken: string): Promise<boolean>;
236
269
  clearAllCachedTokens(): Promise<void>;
237
270
  deleteInstallation(installationId: string): Promise<void>;
238
271
  markInstallationPending(installationId: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}