@monok/server 1.4.0 → 1.5.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.
package/AGENTS.md CHANGED
@@ -5,9 +5,23 @@ and developers integrating Monok with an Express application or CMS. Follow the
5
5
  requirements below rather than inventing alternate endpoint paths or response
6
6
  shapes.
7
7
 
8
- ## Objective
8
+ ## Choose the integration mode
9
9
 
10
- By default, expose a public HTTPS Monok integration at these routes:
10
+ Before changing the host application, establish which mode the developer wants:
11
+
12
+ 1. **Content only** — implement `createMonokRouter` and publication linkbacks.
13
+ 2. **Affiliate only** — implement `monokAffiliateAttribution` and
14
+ `createMonokReferral`; do not expose content endpoints.
15
+ 3. **Content and affiliate** — implement both independent contracts.
16
+
17
+ Do not assume affiliate functionality merely because the package supports it.
18
+ Updating an existing content-only installation requires no affiliate code or
19
+ configuration. Do not assume content delivery for an affiliate-only merchant.
20
+
21
+ ## Content integration
22
+
23
+ Follow this section only for **content only** or **content and affiliate** mode.
24
+ Expose a public HTTPS Monok content integration at these routes:
11
25
 
12
26
  - `POST /api/monok/push`
13
27
  - `GET /api/monok/info`
@@ -19,7 +33,7 @@ default API base, or at an intentional custom base such as
19
33
  site origin to select the default or the complete custom base URL. Monok appends
20
34
  `/info`, `/push`, and `/postfilter` to that base.
21
35
 
22
- ## Required implementation
36
+ ## Content implementation
23
37
 
24
38
  Install the package and Express:
25
39
 
@@ -208,7 +222,7 @@ If `getSiteInfo` is omitted, `/info` returns this authenticated fallback:
208
222
  ```json
209
223
  {
210
224
  "js_scripts": "Disabled",
211
- "version": "1.4.0",
225
+ "version": "1.5.1",
212
226
  "name": "Custom CMS",
213
227
  "logo": "",
214
228
  "categories": [],
@@ -270,6 +284,9 @@ When an article is actually published, notify Monok only after the public
270
284
  canonical URL exists. This applies both to a draft published later and to an
271
285
  asynchronous `action: "publish"` job:
272
286
 
287
+ The default destination is `https://app.monok.com/api/v1/linkback`.
288
+ `monokBaseUrl` is only an override for another Monok environment.
289
+
273
290
  ```ts
274
291
  await sendMonokLinkback({
275
292
  monokId: storedMonokId,
@@ -289,7 +306,7 @@ When useful, `externalId` is the stable article ID assigned by the host CMS; it
289
306
  is optional because the canonical URL also identifies the publication. When
290
307
  supplied, `thumbnailUrl` is the public thumbnail URL.
291
308
 
292
- ## Verification checklist
309
+ ## Content verification checklist
293
310
 
294
311
  Before declaring the integration complete, verify all applicable items:
295
312
 
@@ -316,3 +333,110 @@ routes and confirm one durable draft or draft job, one publication or publicatio
316
333
  job, one repeated delivery, and one discovery query against the host
317
334
  application's persistence layer. For asynchronous publishing, also complete one
318
335
  job and verify its eventual linkback.
336
+
337
+ ## Affiliate integration
338
+
339
+ Follow this section only for **affiliate only** or **content and affiliate**
340
+ mode. A content-only installation must not be changed based on this section.
341
+
342
+ For Express, mount attribution before landing, signup, authentication, and
343
+ account-creation routes:
344
+
345
+ ```ts
346
+ import express from "express";
347
+ import {
348
+ createMonokReferral,
349
+ monokAffiliateAttribution
350
+ } from "@monok/server";
351
+
352
+ const app = express();
353
+
354
+ app.use(monokAffiliateAttribution());
355
+ app.use(express.json());
356
+ ```
357
+
358
+ The middleware reads the signed `monok_ref` query parameter, stores it in an
359
+ HttpOnly, Secure, SameSite=Lax cookie, and redirects to the same URL without the
360
+ token. The offer controls attribution duration; cookie expiry comes from the
361
+ token. Do not add a merchant-configured attribution duration. Only set
362
+ `secure: false` for local HTTP development.
363
+
364
+ For an apex landing site and an account application on a subdomain, explicitly
365
+ share the cookie across the parent domain:
366
+
367
+ ```ts
368
+ app.use(monokAffiliateAttribution({ cookieDomain: ".example.com" }));
369
+ ```
370
+
371
+ A cookie created on `example.com` with `Domain=.example.com` is sent to
372
+ `app.example.com`. Omit `cookieDomain` when landing and signup use the same
373
+ hostname. Avoid simultaneous host-only and parent-domain cookies with the same
374
+ name because they produce ambiguous duplicate cookies.
375
+
376
+ After durably creating a new customer, call Monok from that same successful
377
+ account-creation path:
378
+
379
+ ```ts
380
+ if (req.monokAttribution) {
381
+ await createMonokReferral(
382
+ {
383
+ attributionToken: req.monokAttribution,
384
+ customerReference: customer.id
385
+ },
386
+ { apiKey: process.env.MONOK_API_KEY! }
387
+ );
388
+ }
389
+ ```
390
+
391
+ Use a durable internal customer ID for `customerReference`, never an email or
392
+ other personal data. Do not register referrals during ordinary login,
393
+ invitation acceptance, or flows that do not create a new merchant customer.
394
+ Registration is idempotent for an offer/customer. A temporary Monok failure
395
+ must not roll back an already-created customer; retain the token and customer ID
396
+ in durable retry work. Keep `MONOK_API_KEY` server-side.
397
+
398
+ Monok's own sites use this same public package and API flow. Do not replace it
399
+ with direct database writes, an internal-only attribution service, or
400
+ `referredWorkspaceId` handling.
401
+
402
+ `monokAffiliateAttribution` is Express middleware;
403
+ `createMonokReferral` is framework-independent server code. In another server
404
+ framework, reproduce the capture contract server-side: read `monok_ref`, derive
405
+ expiry from the token, set the secure HttpOnly cookie, and redirect to the clean
406
+ URL. Then read the cookie during customer creation and pass it to
407
+ `createMonokReferral`. A static frontend cannot create an HttpOnly cookie; it
408
+ requires a server or CDN/edge capture handler. Client-side JavaScript cookies
409
+ are not an equivalent secure integration.
410
+
411
+ ### Configure the offer on app.monok.com
412
+
413
+ Briefly tell the developer to:
414
+
415
+ 1. Sign in to `app.monok.com` and select the merchant workspace.
416
+ 2. Open the relevant Brand and choose **Affiliate Program**.
417
+ 3. Create the offer with its exact HTTPS landing URL, commission terms,
418
+ duration, and attribution window.
419
+ 4. Deploy the integration, click **Test setup**, and confirm **Capture
420
+ verified**.
421
+ 5. Activate the offer when it is ready to receive attributed traffic.
422
+
423
+ The Affiliate Program page is currently development-only. If it is absent,
424
+ explain that it is not enabled in that environment. Do not invent another route
425
+ or substitute the content `/info` endpoint.
426
+
427
+ Affiliate integration does not require `createMonokRouter`, `/push`, `/info`,
428
+ or `/postfilter`.
429
+
430
+ ### Affiliate verification checklist
431
+
432
+ - Test the exact production landing URL through **Test setup**; do not fabricate
433
+ an attribution token locally.
434
+ - Confirm the offer becomes **Capture verified** before activation.
435
+ - For cross-subdomain flows, confirm the parent-domain cookie reaches the
436
+ account-creation hostname.
437
+ - Exercise each qualifying customer-creation path, including credentials and
438
+ OAuth where applicable, and confirm it calls `createMonokReferral`.
439
+ - Confirm login and invitation-only flows do not create referrals.
440
+ - Do not claim end-to-end verification yet. The dashboard currently validates
441
+ capture only; one-time test-customer callback validation is reserved for a
442
+ later implementation.
package/README.md CHANGED
@@ -3,14 +3,27 @@
3
3
  # `@monok/server`
4
4
 
5
5
  Monok server integration helpers for Node.js/Express.
6
- Easily connect your backend to Monok to receive articles, expose site info, and send linkbacks.
6
+ Connect a backend to Monok for content delivery, affiliate attribution, or both.
7
7
 
8
8
  Using an AI coding assistant? Give it [`AGENTS.md`](./AGENTS.md). The guide contains
9
9
  the complete host-implementation contract, response shapes, and verification checklist.
10
10
 
11
11
  ---
12
12
 
13
- ## ⚡ Quick Start
13
+ ## Choose the integration mode
14
+
15
+ Use `@monok/server` in one of three modes:
16
+
17
+ 1. **Content only** — receive and publish Monok content.
18
+ 2. **Affiliate only** — capture affiliate attribution and register referred customers.
19
+ 3. **Content and affiliate** — implement both independent integrations.
20
+
21
+ Only implement the mode your project needs. Existing content-only integrations
22
+ do not need affiliate middleware or configuration when updating this package.
23
+
24
+ ---
25
+
26
+ ## ⚡ Content quick start
14
27
 
15
28
  ```ts
16
29
  import express from "express";
@@ -47,7 +60,7 @@ npm install @monok/server express
47
60
 
48
61
  ---
49
62
 
50
- ## 📚 Usage
63
+ ## 📚 Content integration
51
64
 
52
65
  ### Express setup (TypeScript)
53
66
 
@@ -196,6 +209,8 @@ private no-cache headers. `POST /push` also accepts Monok's `token` header.
196
209
 
197
210
  The push acknowledgement confirms delivery only. If publication is asynchronous,
198
211
  send the linkback later, after the public canonical URL actually exists.
212
+ Linkbacks default to `https://app.monok.com/api/v1/linkback`; use
213
+ `monokBaseUrl` only when targeting another Monok environment.
199
214
 
200
215
  ```ts
201
216
  import { sendMonokLinkback } from "@monok/server";
@@ -225,6 +240,57 @@ await sendMonokLinkback({
225
240
 
226
241
  ---
227
242
 
243
+ ## Affiliate integration
244
+
245
+ Follow this section for **affiliate only** or **content and affiliate** mode.
246
+ Content-only integrations can ignore it completely.
247
+
248
+ The affiliate middleware preserves the signed `monok_ref` value from a Monok
249
+ redirect in an HttpOnly, SameSite=Lax cookie, then redirects to the same URL
250
+ without the token. The offer controls the attribution window and the middleware
251
+ derives the cookie expiry from the token, so merchants do not configure it.
252
+ Mount it before the merchant's landing and signup routes. After the customer has
253
+ been durably created, register the referral using the merchant's own stable
254
+ customer ID.
255
+
256
+ ```ts
257
+ import express from "express";
258
+ import {
259
+ createMonokReferral,
260
+ monokAffiliateAttribution
261
+ } from "@monok/server";
262
+
263
+ const app = express();
264
+ app.use(monokAffiliateAttribution());
265
+ app.use(express.json());
266
+
267
+ app.post("/signup", async (req, res) => {
268
+ const customer = await createCustomer(req.body);
269
+
270
+ if (req.monokAttribution) {
271
+ await createMonokReferral(
272
+ {
273
+ attributionToken: req.monokAttribution,
274
+ customerReference: customer.id
275
+ },
276
+ { apiKey: process.env.MONOK_API_KEY! }
277
+ );
278
+ }
279
+
280
+ res.status(201).json({ id: customer.id });
281
+ });
282
+ ```
283
+
284
+ The middleware defaults to secure cookies. For local HTTP development only, use
285
+ `monokAffiliateAttribution({ secure: false })`. `customerReference` should be a
286
+ durable internal ID, not an email address or other personal data. Repeating the
287
+ same offer/customer registration is idempotent and retains the first referral.
288
+
289
+ Affiliate-only merchants do **not** need to mount `createMonokRouter` or expose
290
+ `/push`, `/info`, or `/postfilter`.
291
+
292
+ ---
293
+
228
294
  ## 🛠 Development
229
295
 
230
296
  Build the package:
@@ -0,0 +1,15 @@
1
+ import type { RequestHandler } from "express";
2
+ import type { MonokAffiliateAttributionOptions } from "./types.js";
3
+ declare global {
4
+ namespace Express {
5
+ interface Request {
6
+ monokAttribution?: string;
7
+ }
8
+ }
9
+ }
10
+ /**
11
+ * Preserve Monok's signed redirect token in an HttpOnly cookie and expose it as
12
+ * `req.monokAttribution`. This does not expose any content-receiving endpoint.
13
+ */
14
+ export declare function monokAffiliateAttribution(options?: MonokAffiliateAttributionOptions): RequestHandler;
15
+ //# sourceMappingURL=affiliate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affiliate.d.ts","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAC;AAcnE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;SAC3B;KACF;CACF;AAgED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gCAAqC,GAC7C,cAAc,CAuChB"}
@@ -0,0 +1,96 @@
1
+ const DEFAULT_QUERY_PARAMETER = "monok_ref";
2
+ const DEFAULT_COOKIE_NAME = "monok_ref";
3
+ const MAX_TOKEN_LENGTH = 4096;
4
+ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
5
+ const MAX_ATTRIBUTION_WINDOW_DAYS = 365;
6
+ const TOKEN_PATTERN = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
7
+ function validToken(value) {
8
+ return typeof value === "string" &&
9
+ value.length > 0 &&
10
+ value.length <= MAX_TOKEN_LENGTH &&
11
+ TOKEN_PATTERN.test(value);
12
+ }
13
+ function readAttribution(value, nowMs = Date.now()) {
14
+ if (!validToken(value))
15
+ return undefined;
16
+ try {
17
+ const [encodedPayload] = value.split(".");
18
+ const payload = JSON.parse(Buffer.from(encodedPayload, "base64url").toString("utf8"));
19
+ if (payload.version !== 1 ||
20
+ typeof payload.issuedAt !== "number" || !Number.isInteger(payload.issuedAt) ||
21
+ typeof payload.expiresAt !== "number" || !Number.isInteger(payload.expiresAt)) {
22
+ return undefined;
23
+ }
24
+ const lifetimeMs = (payload.expiresAt - payload.issuedAt) * 1000;
25
+ const maxAgeMs = payload.expiresAt * 1000 - nowMs;
26
+ if (lifetimeMs < MILLISECONDS_PER_DAY ||
27
+ lifetimeMs > MAX_ATTRIBUTION_WINDOW_DAYS * MILLISECONDS_PER_DAY ||
28
+ lifetimeMs % MILLISECONDS_PER_DAY !== 0 ||
29
+ payload.issuedAt * 1000 > nowMs + 60000 ||
30
+ maxAgeMs <= 0) {
31
+ return undefined;
32
+ }
33
+ return { token: value, maxAgeMs };
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ }
39
+ function readCookie(req, cookieName) {
40
+ const header = req.headers.cookie;
41
+ if (!header)
42
+ return undefined;
43
+ for (const part of header.split(";")) {
44
+ const separator = part.indexOf("=");
45
+ if (separator < 0 || part.slice(0, separator).trim() !== cookieName)
46
+ continue;
47
+ try {
48
+ const value = decodeURIComponent(part.slice(separator + 1).trim());
49
+ return readAttribution(value);
50
+ }
51
+ catch {
52
+ return undefined;
53
+ }
54
+ }
55
+ return undefined;
56
+ }
57
+ /**
58
+ * Preserve Monok's signed redirect token in an HttpOnly cookie and expose it as
59
+ * `req.monokAttribution`. This does not expose any content-receiving endpoint.
60
+ */
61
+ export function monokAffiliateAttribution(options = {}) {
62
+ const queryParameter = options.queryParameter ?? DEFAULT_QUERY_PARAMETER;
63
+ const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
64
+ if (!queryParameter || !cookieName) {
65
+ throw new Error("Affiliate query parameter and cookie name cannot be empty");
66
+ }
67
+ return (req, res, next) => {
68
+ const queryToken = req.query[queryParameter];
69
+ const queryAttribution = readAttribution(queryToken);
70
+ const attribution = queryAttribution
71
+ ? queryAttribution
72
+ : readCookie(req, cookieName);
73
+ if (attribution)
74
+ req.monokAttribution = attribution.token;
75
+ if (queryAttribution) {
76
+ res.cookie(cookieName, queryAttribution.token, {
77
+ httpOnly: true,
78
+ secure: options.secure ?? true,
79
+ sameSite: "lax",
80
+ path: "/",
81
+ maxAge: queryAttribution.maxAgeMs,
82
+ ...(options.cookieDomain ? { domain: options.cookieDomain } : {})
83
+ });
84
+ }
85
+ if (validToken(queryToken)) {
86
+ if (options.cleanUrl ?? true) {
87
+ const cleanUrl = new URL(req.originalUrl, "http://monok.local");
88
+ cleanUrl.searchParams.delete(queryParameter);
89
+ res.redirect(302, cleanUrl.pathname + cleanUrl.search);
90
+ return;
91
+ }
92
+ }
93
+ next();
94
+ };
95
+ }
96
+ //# sourceMappingURL=affiliate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { LinkbackPayload } from "./types.js";
1
+ import type { CreateMonokReferralPayload, LinkbackPayload, MonokAffiliateClientOptions, MonokReferralResult } from "./types.js";
2
+ export declare const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
2
3
  /**
3
4
  * Send a linkback to Monok after you publish the article.
4
5
  */
@@ -6,4 +7,9 @@ export declare function sendMonokLinkback({ monokId, externalId, url, title, thu
6
7
  monokBaseUrl?: string;
7
8
  apiKey?: string;
8
9
  }): Promise<void>;
10
+ /**
11
+ * Register a newly created merchant customer against a signed attribution token.
12
+ * Repeating the same offer/customer pair is safe and returns the existing referral.
13
+ */
14
+ export declare function createMonokReferral({ attributionToken, customerReference }: CreateMonokReferralPayload, { apiKey, monokBaseUrl }: MonokAffiliateClientOptions): Promise<MonokReferralResult>;
9
15
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,eAAe,EAClE,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0BAA0B,EAC1B,eAAe,EACf,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,sBAAsB,0BAA0B,CAAC;AAE9D;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,eAAe,EAClE,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,EAAE,0BAA0B,EACnE,EAAE,MAAM,EAAE,YAAqC,EAAE,EAAE,2BAA2B,GAC7E,OAAO,CAAC,mBAAmB,CAAC,CAwB9B"}
package/dist/client.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import fetch from "node-fetch";
2
+ export const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
2
3
  /**
3
4
  * Send a linkback to Monok after you publish the article.
4
5
  */
5
6
  export async function sendMonokLinkback({ monokId, externalId, url, title, thumbnailUrl }, opts) {
6
- const endpoint = (opts?.monokBaseUrl ?? "https://www.monok.com") + "/api/v1/linkback";
7
+ const endpoint = (opts?.monokBaseUrl ?? DEFAULT_MONOK_BASE_URL) + "/api/v1/linkback";
7
8
  const payload = {
8
9
  puff: { title },
9
10
  id: monokId,
@@ -27,4 +28,33 @@ export async function sendMonokLinkback({ monokId, externalId, url, title, thumb
27
28
  throw new Error(`Monok linkback failed: ${resp.status} ${text}`);
28
29
  }
29
30
  }
31
+ /**
32
+ * Register a newly created merchant customer against a signed attribution token.
33
+ * Repeating the same offer/customer pair is safe and returns the existing referral.
34
+ */
35
+ export async function createMonokReferral({ attributionToken, customerReference }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
36
+ if (!apiKey.trim())
37
+ throw new Error("A Monok API key is required");
38
+ if (!attributionToken.trim())
39
+ throw new Error("An attribution token is required");
40
+ if (!customerReference.trim())
41
+ throw new Error("A customer reference is required");
42
+ const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/referrals";
43
+ const resp = await fetch(endpoint, {
44
+ method: "POST",
45
+ headers: {
46
+ "Content-Type": "application/json",
47
+ "X-API-Key": apiKey
48
+ },
49
+ body: JSON.stringify({
50
+ attributionToken,
51
+ customerReference
52
+ })
53
+ });
54
+ if (!resp.ok) {
55
+ const text = await resp.text().catch(() => "");
56
+ throw new Error(`Monok referral registration failed: ${resp.status} ${text}`);
57
+ }
58
+ return await resp.json();
59
+ }
30
60
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAmB,EAClE,IAAiD;IAEjD,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,IAAI,uBAAuB,CAAC,GAAG,kBAAkB,CAAC;IACtF,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,EAAE,KAAK,EAAE;QACf,EAAE,EAAE,OAAO;QACX,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI;YACjD,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE;YACpC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG;QACH,MAAM,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ;QAC7B,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./types.js";
2
2
  export * from "./client.js";
3
3
  export * from "./express.js";
4
+ export * from "./affiliate.js";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./types.js";
2
2
  export * from "./client.js";
3
3
  export * from "./express.js";
4
+ export * from "./affiliate.js";
4
5
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -89,6 +89,34 @@ export interface LinkbackPayload {
89
89
  title: string;
90
90
  thumbnailUrl?: string;
91
91
  }
92
+ export interface MonokAffiliateAttributionOptions {
93
+ /** Query parameter carrying the signed Monok attribution token. */
94
+ queryParameter?: string;
95
+ /** HttpOnly cookie used to preserve attribution until signup. */
96
+ cookieName?: string;
97
+ /** Optional cookie domain, for example `.example.com`. */
98
+ cookieDomain?: string;
99
+ /** Defaults to true. Set false only for local HTTP development. */
100
+ secure?: boolean;
101
+ /** Remove the token from the address bar with a safe same-site redirect. Defaults to true. */
102
+ cleanUrl?: boolean;
103
+ }
104
+ export interface CreateMonokReferralPayload {
105
+ attributionToken: string;
106
+ /** The merchant's durable, non-sensitive customer ID. */
107
+ customerReference: string;
108
+ }
109
+ export interface MonokAffiliateClientOptions {
110
+ apiKey: string;
111
+ monokBaseUrl?: string;
112
+ }
113
+ export interface MonokReferralResult {
114
+ id: string;
115
+ status: "created" | "existing";
116
+ offerId: string;
117
+ publisherWorkspaceId: string;
118
+ customerReference: string;
119
+ }
92
120
  export interface CreateRouterOptions {
93
121
  /**
94
122
  * Token Monok will send in the `token` header.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ const DEFAULT_QUERY_PARAMETER = "monok_ref";
2
+ const DEFAULT_COOKIE_NAME = "monok_ref";
3
+ const MAX_TOKEN_LENGTH = 4096;
4
+ const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
5
+ const MAX_ATTRIBUTION_WINDOW_DAYS = 365;
6
+ const TOKEN_PATTERN = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
7
+ function validToken(value) {
8
+ return typeof value === "string" &&
9
+ value.length > 0 &&
10
+ value.length <= MAX_TOKEN_LENGTH &&
11
+ TOKEN_PATTERN.test(value);
12
+ }
13
+ function readAttribution(value, nowMs = Date.now()) {
14
+ if (!validToken(value))
15
+ return undefined;
16
+ try {
17
+ const [encodedPayload] = value.split(".");
18
+ const payload = JSON.parse(Buffer.from(encodedPayload, "base64url").toString("utf8"));
19
+ if (payload.version !== 1 ||
20
+ typeof payload.issuedAt !== "number" || !Number.isInteger(payload.issuedAt) ||
21
+ typeof payload.expiresAt !== "number" || !Number.isInteger(payload.expiresAt)) {
22
+ return undefined;
23
+ }
24
+ const lifetimeMs = (payload.expiresAt - payload.issuedAt) * 1000;
25
+ const maxAgeMs = payload.expiresAt * 1000 - nowMs;
26
+ if (lifetimeMs < MILLISECONDS_PER_DAY ||
27
+ lifetimeMs > MAX_ATTRIBUTION_WINDOW_DAYS * MILLISECONDS_PER_DAY ||
28
+ lifetimeMs % MILLISECONDS_PER_DAY !== 0 ||
29
+ payload.issuedAt * 1000 > nowMs + 60000 ||
30
+ maxAgeMs <= 0) {
31
+ return undefined;
32
+ }
33
+ return { token: value, maxAgeMs };
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ }
39
+ function readCookie(req, cookieName) {
40
+ const header = req.headers.cookie;
41
+ if (!header)
42
+ return undefined;
43
+ for (const part of header.split(";")) {
44
+ const separator = part.indexOf("=");
45
+ if (separator < 0 || part.slice(0, separator).trim() !== cookieName)
46
+ continue;
47
+ try {
48
+ const value = decodeURIComponent(part.slice(separator + 1).trim());
49
+ return readAttribution(value);
50
+ }
51
+ catch {
52
+ return undefined;
53
+ }
54
+ }
55
+ return undefined;
56
+ }
57
+ /**
58
+ * Preserve Monok's signed redirect token in an HttpOnly cookie and expose it as
59
+ * `req.monokAttribution`. This does not expose any content-receiving endpoint.
60
+ */
61
+ export function monokAffiliateAttribution(options = {}) {
62
+ const queryParameter = options.queryParameter ?? DEFAULT_QUERY_PARAMETER;
63
+ const cookieName = options.cookieName ?? DEFAULT_COOKIE_NAME;
64
+ if (!queryParameter || !cookieName) {
65
+ throw new Error("Affiliate query parameter and cookie name cannot be empty");
66
+ }
67
+ return (req, res, next) => {
68
+ const queryToken = req.query[queryParameter];
69
+ const queryAttribution = readAttribution(queryToken);
70
+ const attribution = queryAttribution
71
+ ? queryAttribution
72
+ : readCookie(req, cookieName);
73
+ if (attribution)
74
+ req.monokAttribution = attribution.token;
75
+ if (queryAttribution) {
76
+ res.cookie(cookieName, queryAttribution.token, {
77
+ httpOnly: true,
78
+ secure: options.secure ?? true,
79
+ sameSite: "lax",
80
+ path: "/",
81
+ maxAge: queryAttribution.maxAgeMs,
82
+ ...(options.cookieDomain ? { domain: options.cookieDomain } : {})
83
+ });
84
+ }
85
+ if (validToken(queryToken)) {
86
+ if (options.cleanUrl ?? true) {
87
+ const cleanUrl = new URL(req.originalUrl, "http://monok.local");
88
+ cleanUrl.searchParams.delete(queryParameter);
89
+ res.redirect(302, cleanUrl.pathname + cleanUrl.search);
90
+ return;
91
+ }
92
+ }
93
+ next();
94
+ };
95
+ }
96
+ //# sourceMappingURL=affiliate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"affiliate.js","sourceRoot":"","sources":["../src/affiliate.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
1
  import fetch from "node-fetch";
2
+ export const DEFAULT_MONOK_BASE_URL = "https://app.monok.com";
2
3
  /**
3
4
  * Send a linkback to Monok after you publish the article.
4
5
  */
5
6
  export async function sendMonokLinkback({ monokId, externalId, url, title, thumbnailUrl }, opts) {
6
- const endpoint = (opts?.monokBaseUrl ?? "https://www.monok.com") + "/api/v1/linkback";
7
+ const endpoint = (opts?.monokBaseUrl ?? DEFAULT_MONOK_BASE_URL) + "/api/v1/linkback";
7
8
  const payload = {
8
9
  puff: { title },
9
10
  id: monokId,
@@ -27,4 +28,33 @@ export async function sendMonokLinkback({ monokId, externalId, url, title, thumb
27
28
  throw new Error(`Monok linkback failed: ${resp.status} ${text}`);
28
29
  }
29
30
  }
31
+ /**
32
+ * Register a newly created merchant customer against a signed attribution token.
33
+ * Repeating the same offer/customer pair is safe and returns the existing referral.
34
+ */
35
+ export async function createMonokReferral({ attributionToken, customerReference }, { apiKey, monokBaseUrl = DEFAULT_MONOK_BASE_URL }) {
36
+ if (!apiKey.trim())
37
+ throw new Error("A Monok API key is required");
38
+ if (!attributionToken.trim())
39
+ throw new Error("An attribution token is required");
40
+ if (!customerReference.trim())
41
+ throw new Error("A customer reference is required");
42
+ const endpoint = monokBaseUrl.replace(/\/$/, "") + "/api/v1/affiliate/referrals";
43
+ const resp = await fetch(endpoint, {
44
+ method: "POST",
45
+ headers: {
46
+ "Content-Type": "application/json",
47
+ "X-API-Key": apiKey
48
+ },
49
+ body: JSON.stringify({
50
+ attributionToken,
51
+ customerReference
52
+ })
53
+ });
54
+ if (!resp.ok) {
55
+ const text = await resp.text().catch(() => "");
56
+ throw new Error(`Monok referral registration failed: ${resp.status} ${text}`);
57
+ }
58
+ return await resp.json();
59
+ }
30
60
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAmB,EAClE,IAAiD;IAEjD,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,IAAI,uBAAuB,CAAC,GAAG,kBAAkB,CAAC;IACtF,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,EAAE,KAAK,EAAE;QACf,EAAE,EAAE,OAAO;QACX,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI;YACjD,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE;YACpC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG;QACH,MAAM,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ;QAC7B,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrD,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist-cjs/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./types.js";
2
2
  export * from "./client.js";
3
3
  export * from "./express.js";
4
+ export * from "./affiliate.js";
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@monok/server",
3
- "version": "1.4.0",
4
- "description": "Monok server integration helpers (Express router + linkback client)",
3
+ "version": "1.5.1",
4
+ "description": "Monok server integration helpers for content and affiliate attribution",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "main": "dist-cjs/index.js",
@@ -36,6 +36,7 @@
36
36
  "monok",
37
37
  "cms",
38
38
  "express",
39
+ "affiliate",
39
40
  "webhook"
40
41
  ],
41
42
  "dependencies": {