@mj-biz-apps/orders-server 0.0.1 → 5.2.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.
Files changed (71) hide show
  1. package/LICENSE +183 -0
  2. package/README.md +47 -2
  3. package/dist/CheckoutServerExtension.d.ts +96 -0
  4. package/dist/CheckoutServerExtension.d.ts.map +1 -0
  5. package/dist/CheckoutServerExtension.js +554 -0
  6. package/dist/CheckoutServerExtension.js.map +1 -0
  7. package/dist/PaymentWebhookExtension.d.ts +17 -0
  8. package/dist/PaymentWebhookExtension.d.ts.map +1 -0
  9. package/dist/PaymentWebhookExtension.js +151 -0
  10. package/dist/PaymentWebhookExtension.js.map +1 -0
  11. package/dist/__tests__/CheckoutServerExtension.test.d.ts +2 -0
  12. package/dist/__tests__/CheckoutServerExtension.test.d.ts.map +1 -0
  13. package/dist/__tests__/CheckoutServerExtension.test.js +257 -0
  14. package/dist/__tests__/CheckoutServerExtension.test.js.map +1 -0
  15. package/dist/__tests__/checkout-edge-policy.test.d.ts +2 -0
  16. package/dist/__tests__/checkout-edge-policy.test.d.ts.map +1 -0
  17. package/dist/__tests__/checkout-edge-policy.test.js +70 -0
  18. package/dist/__tests__/checkout-edge-policy.test.js.map +1 -0
  19. package/dist/__tests__/checkout-host-page.test.d.ts +2 -0
  20. package/dist/__tests__/checkout-host-page.test.d.ts.map +1 -0
  21. package/dist/__tests__/checkout-host-page.test.js +86 -0
  22. package/dist/__tests__/checkout-host-page.test.js.map +1 -0
  23. package/dist/__tests__/server-extensions-manifest.test.d.ts +2 -0
  24. package/dist/__tests__/server-extensions-manifest.test.d.ts.map +1 -0
  25. package/dist/__tests__/server-extensions-manifest.test.js +29 -0
  26. package/dist/__tests__/server-extensions-manifest.test.js.map +1 -0
  27. package/dist/checkout-edge-policy.d.ts +44 -0
  28. package/dist/checkout-edge-policy.d.ts.map +1 -0
  29. package/dist/checkout-edge-policy.js +84 -0
  30. package/dist/checkout-edge-policy.js.map +1 -0
  31. package/dist/checkout-host-page.d.ts +43 -0
  32. package/dist/checkout-host-page.d.ts.map +1 -0
  33. package/dist/checkout-host-page.js +445 -0
  34. package/dist/checkout-host-page.js.map +1 -0
  35. package/dist/config.d.ts +6 -0
  36. package/dist/config.d.ts.map +1 -0
  37. package/dist/config.js +6 -0
  38. package/dist/config.js.map +1 -0
  39. package/dist/custom/generate-invoice.action.d.ts +59 -0
  40. package/dist/custom/generate-invoice.action.d.ts.map +1 -0
  41. package/dist/custom/generate-invoice.action.js +208 -0
  42. package/dist/custom/generate-invoice.action.js.map +1 -0
  43. package/dist/custom/open-payment-intent.action.d.ts +39 -0
  44. package/dist/custom/open-payment-intent.action.d.ts.map +1 -0
  45. package/dist/custom/open-payment-intent.action.js +169 -0
  46. package/dist/custom/open-payment-intent.action.js.map +1 -0
  47. package/dist/custom/send-document.action.d.ts +78 -0
  48. package/dist/custom/send-document.action.d.ts.map +1 -0
  49. package/dist/custom/send-document.action.js +277 -0
  50. package/dist/custom/send-document.action.js.map +1 -0
  51. package/dist/generated/class-registrations-manifest.d.ts +7 -0
  52. package/dist/generated/class-registrations-manifest.d.ts.map +1 -0
  53. package/dist/generated/class-registrations-manifest.js +7 -0
  54. package/dist/generated/class-registrations-manifest.js.map +1 -0
  55. package/dist/generated/generated.d.ts +3536 -0
  56. package/dist/generated/generated.d.ts.map +1 -0
  57. package/dist/generated/generated.js +18371 -0
  58. package/dist/generated/generated.js.map +1 -0
  59. package/dist/index.d.ts +28 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +105 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/server-extensions-manifest.d.ts +14 -0
  64. package/dist/server-extensions-manifest.d.ts.map +1 -0
  65. package/dist/server-extensions-manifest.js +15 -0
  66. package/dist/server-extensions-manifest.js.map +1 -0
  67. package/dist/services/invoice-renderer.d.ts +80 -0
  68. package/dist/services/invoice-renderer.d.ts.map +1 -0
  69. package/dist/services/invoice-renderer.js +103 -0
  70. package/dist/services/invoice-renderer.js.map +1 -0
  71. package/package.json +65 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-host-page.test.js","sourceRoot":"","sources":["../../src/__tests__/checkout-host-page.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server-extensions-manifest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-extensions-manifest.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/server-extensions-manifest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { MJ_SERVER_EXTENSIONS } from '../server-extensions-manifest.js';
6
+ const pkgJsonPath = join(dirname(fileURLToPath(import.meta.url)), '../../package.json');
7
+ describe('MJ_SERVER_EXTENSIONS', () => {
8
+ it('declares the webhook and checkout edge with the same DriverClass/RootPath as mj.config.cjs', () => {
9
+ expect(MJ_SERVER_EXTENSIONS).toEqual([
10
+ {
11
+ Enabled: true,
12
+ DriverClass: 'OrdersPaymentWebhook',
13
+ RootPath: '/webhooks/payments',
14
+ Settings: {},
15
+ },
16
+ {
17
+ Enabled: true,
18
+ DriverClass: 'OrdersCheckoutEdge',
19
+ RootPath: '/checkout',
20
+ Settings: {},
21
+ },
22
+ ]);
23
+ });
24
+ it('mirrors package.json memberjunction.serverExtensions so static introspection matches the export', () => {
25
+ const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
26
+ expect(pkg.memberjunction?.serverExtensions).toEqual(MJ_SERVER_EXTENSIONS);
27
+ });
28
+ });
29
+ //# sourceMappingURL=server-extensions-manifest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-extensions-manifest.test.js","sourceRoot":"","sources":["../../src/__tests__/server-extensions-manifest.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAExF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,4FAA4F,EAAE,GAAG,EAAE;QAClG,MAAM,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC;YACjC;gBACI,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,sBAAsB;gBACnC,QAAQ,EAAE,oBAAoB;gBAC9B,QAAQ,EAAE,EAAE;aACf;YACD;gBACI,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,oBAAoB;gBACjC,QAAQ,EAAE,WAAW;gBACrB,QAAQ,EAAE,EAAE;aACf;SACJ,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iGAAiG,EAAE,GAAG,EAAE;QACvG,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAEvD,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Pure helpers for the anonymous checkout edge: slug validation and origin allowlist.
3
+ * Extracted so unit tests do not have to boot Express or the ClassFactory.
4
+ */
5
+ /** POST route suffixes that must never be treated as a distribution slug. */
6
+ export declare const CHECKOUT_RESERVED_SLUGS: ReadonlySet<string>;
7
+ /**
8
+ * Public distribution slugs: short, URL-safe, not colliding with the POST verbs
9
+ * mounted on the same root.
10
+ */
11
+ export declare function isValidCheckoutSlug(slug: string): boolean;
12
+ /**
13
+ * True when the browser Origin is the same host:port as this request (the
14
+ * first-party `GET /checkout/:slug` page posting back to MJAPI).
15
+ */
16
+ export declare function isSameOrigin(origin: string, hostHeader: string | undefined): boolean;
17
+ export interface CheckoutOriginPolicy {
18
+ allowedOrigins?: string[];
19
+ }
20
+ /**
21
+ * Widget `allowedOrigins` is a **cross-origin embed** allowlist. Same-origin
22
+ * posts from the MJAPI-hosted public page always pass. When the allowlist is
23
+ * absent or empty, any origin is allowed (the distribution slug remains the
24
+ * access control).
25
+ */
26
+ /**
27
+ * Client IP for rate limiting and Turnstile.
28
+ *
29
+ * `TrustedProxyHops` is the number of reverse proxies that append to
30
+ * `X-Forwarded-For`. 0 (the default) ignores XFF entirely and uses the socket
31
+ * address — the leftmost XFF hop is client-supplied and must never key a
32
+ * security decision. When hops is N, the Nth-from-the-right entry is used
33
+ * (the address the outermost trusted proxy observed).
34
+ */
35
+ export declare function resolveClientIp(req: {
36
+ headers: {
37
+ [key: string]: unknown;
38
+ };
39
+ socket?: {
40
+ remoteAddress?: string;
41
+ };
42
+ }, trustedProxyHops?: number): string;
43
+ export declare function originAllowed(origin: string, policy: CheckoutOriginPolicy, hostHeader?: string): boolean;
44
+ //# sourceMappingURL=checkout-edge-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-edge-policy.d.ts","sourceRoot":"","sources":["../src/checkout-edge-policy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAKtD,CAAC;AAIH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAUpF;AAED,MAAM,WAAW,oBAAoB;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;GAKG;AACH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC3B,GAAG,EAAE;IAAE,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACjF,gBAAgB,SAAI,GACrB,MAAM,CAgBR;AAED,wBAAgB,aAAa,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,oBAAoB,EAC5B,UAAU,CAAC,EAAE,MAAM,GACpB,OAAO,CAWT"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Pure helpers for the anonymous checkout edge: slug validation and origin allowlist.
3
+ * Extracted so unit tests do not have to boot Express or the ClassFactory.
4
+ */
5
+ /** POST route suffixes that must never be treated as a distribution slug. */
6
+ export const CHECKOUT_RESERVED_SLUGS = new Set([
7
+ 'initialize',
8
+ 'draft',
9
+ 'payment-intent',
10
+ 'complete',
11
+ ]);
12
+ const SLUG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
13
+ /**
14
+ * Public distribution slugs: short, URL-safe, not colliding with the POST verbs
15
+ * mounted on the same root.
16
+ */
17
+ export function isValidCheckoutSlug(slug) {
18
+ if (!slug || slug.length > 128) {
19
+ return false;
20
+ }
21
+ if (CHECKOUT_RESERVED_SLUGS.has(slug.toLowerCase())) {
22
+ return false;
23
+ }
24
+ return SLUG_PATTERN.test(slug);
25
+ }
26
+ /**
27
+ * True when the browser Origin is the same host:port as this request (the
28
+ * first-party `GET /checkout/:slug` page posting back to MJAPI).
29
+ */
30
+ export function isSameOrigin(origin, hostHeader) {
31
+ if (!origin || !hostHeader) {
32
+ return false;
33
+ }
34
+ try {
35
+ const url = new URL(origin);
36
+ return url.host.toLowerCase() === hostHeader.toLowerCase();
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ /**
43
+ * Widget `allowedOrigins` is a **cross-origin embed** allowlist. Same-origin
44
+ * posts from the MJAPI-hosted public page always pass. When the allowlist is
45
+ * absent or empty, any origin is allowed (the distribution slug remains the
46
+ * access control).
47
+ */
48
+ /**
49
+ * Client IP for rate limiting and Turnstile.
50
+ *
51
+ * `TrustedProxyHops` is the number of reverse proxies that append to
52
+ * `X-Forwarded-For`. 0 (the default) ignores XFF entirely and uses the socket
53
+ * address — the leftmost XFF hop is client-supplied and must never key a
54
+ * security decision. When hops is N, the Nth-from-the-right entry is used
55
+ * (the address the outermost trusted proxy observed).
56
+ */
57
+ export function resolveClientIp(req, trustedProxyHops = 0) {
58
+ const socket = req.socket?.remoteAddress ?? 'unknown';
59
+ if (!Number.isInteger(trustedProxyHops) || trustedProxyHops < 1) {
60
+ return socket;
61
+ }
62
+ const fwd = req.headers['x-forwarded-for'];
63
+ const raw = Array.isArray(fwd) ? fwd.join(',') : typeof fwd === 'string' ? fwd : undefined;
64
+ if (!raw) {
65
+ return socket;
66
+ }
67
+ const hops = raw.split(',').map((h) => h.trim()).filter((h) => h.length > 0);
68
+ const idx = hops.length - trustedProxyHops;
69
+ if (idx < 0 || idx >= hops.length) {
70
+ return socket;
71
+ }
72
+ return hops[idx];
73
+ }
74
+ export function originAllowed(origin, policy, hostHeader) {
75
+ if (isSameOrigin(origin, hostHeader)) {
76
+ return true;
77
+ }
78
+ if (!policy.allowedOrigins || policy.allowedOrigins.length === 0) {
79
+ return true;
80
+ }
81
+ const normalized = origin.replace(/\/+$/, '').toLowerCase();
82
+ return policy.allowedOrigins.some((allowed) => allowed.replace(/\/+$/, '').toLowerCase() === normalized);
83
+ }
84
+ //# sourceMappingURL=checkout-edge-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-edge-policy.js","sourceRoot":"","sources":["../src/checkout-edge-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Public checkout host page — a self-contained HTML document that drives
3
+ * `OrdersCheckoutEdge` POSTs from a browser with no Explorer shell and no
4
+ * custom-element bundle.
5
+ *
6
+ * All per-request values reach the boot script via HTML-escaped `data-*`
7
+ * attributes (Forms host-page XSS rule): nothing attacker-controlled is
8
+ * interpolated into the inline `<script>`.
9
+ */
10
+ export interface CheckoutHostPageOptions {
11
+ /** Distribution slug from `GET /checkout/:slug`. */
12
+ slug: string;
13
+ /**
14
+ * URL prefix the boot script POSTs to (the extension RootPath, e.g. `/checkout`).
15
+ * Relative so the page works behind whatever public origin MJAPI is served on.
16
+ */
17
+ apiRoot: string;
18
+ /** Browser tab title before initialize returns the widget name. */
19
+ pageTitle?: string;
20
+ /** Per-response CSP nonce. Required so a caller cannot emit a nonce-less page. */
21
+ cspNonce: string;
22
+ /**
23
+ * Relative URL of the `<mj-orders-checkout>` Angular Element bundle.
24
+ * When set, the page hosts the reusable Angular widget (customUI, introspected
25
+ * extension fields). When omitted, a vanilla fallback form is used.
26
+ */
27
+ elementSrc?: string;
28
+ }
29
+ export interface CheckoutHostErrorOptions {
30
+ message: string;
31
+ pageTitle?: string;
32
+ /** Per-response CSP nonce. Required so a caller cannot emit a nonce-less page. */
33
+ cspNonce: string;
34
+ }
35
+ /** Headers for the public checkout host / error pages (CSP is nonce-based). */
36
+ export declare function checkoutHostSecurityHeaders(nonce: string): Record<string, string>;
37
+ /** Escape a string for safe insertion into HTML text content. */
38
+ export declare function escapeHtml(value: string): string;
39
+ /** Escape a string for safe insertion into a double-quoted HTML attribute. */
40
+ export declare function escapeAttr(value: string): string;
41
+ export declare function renderCheckoutHostPage(options: CheckoutHostPageOptions): string;
42
+ export declare function renderCheckoutHostErrorPage(options: CheckoutHostErrorOptions): string;
43
+ //# sourceMappingURL=checkout-host-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-host-page.d.ts","sourceRoot":"","sources":["../src/checkout-host-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,uBAAuB;IACpC,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoBjF;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,MAAM,CAwC/E;AAED,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAmBrF"}