@unchainedshop/api 3.1.10 → 3.1.12

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 (173) hide show
  1. package/lib/express/createMCPMiddleware.d.ts +4 -0
  2. package/lib/express/createMCPMiddleware.d.ts.map +1 -0
  3. package/lib/express/createMCPMiddleware.js +68 -0
  4. package/lib/express/createMCPMiddleware.js.map +1 -0
  5. package/lib/express/mcpHandler.d.ts.map +1 -0
  6. package/lib/express/mcpHandler.js +68 -0
  7. package/lib/express/mcpHandler.js.map +1 -0
  8. package/lib/fastify/createMCPMiddleware.d.ts +2 -0
  9. package/lib/fastify/createMCPMiddleware.d.ts.map +1 -0
  10. package/lib/fastify/createMCPMiddleware.js +2 -0
  11. package/lib/fastify/createMCPMiddleware.js.map +1 -0
  12. package/lib/fastify/index copy.d.ts.map +1 -0
  13. package/lib/fastify/index copy.js +157 -0
  14. package/lib/fastify/index copy.js.map +1 -0
  15. package/lib/fastify/mcpHandler.d.ts +8 -0
  16. package/lib/fastify/mcpHandler.d.ts.map +1 -0
  17. package/lib/fastify/mcpHandler.js +46 -0
  18. package/lib/fastify/mcpHandler.js.map +1 -0
  19. package/lib/loaders/assortmentLinkLoader.d.ts +12 -0
  20. package/lib/loaders/assortmentLinkLoader.d.ts.map +1 -0
  21. package/lib/loaders/assortmentLinkLoader.js +23 -0
  22. package/lib/loaders/assortmentLinkLoader.js.map +1 -0
  23. package/lib/loaders/assortmentLinksLoader.d.ts +14 -0
  24. package/lib/loaders/assortmentLinksLoader.d.ts.map +1 -0
  25. package/lib/loaders/assortmentLinksLoader.js +38 -0
  26. package/lib/loaders/assortmentLinksLoader.js.map +1 -0
  27. package/lib/loaders/assortmentLoader.d.ts +10 -0
  28. package/lib/loaders/assortmentLoader.d.ts.map +1 -0
  29. package/lib/loaders/assortmentLoader.js +15 -0
  30. package/lib/loaders/assortmentLoader.js.map +1 -0
  31. package/lib/loaders/assortmentMediaTextLoader.d.ts +12 -0
  32. package/lib/loaders/assortmentMediaTextLoader.d.ts.map +1 -0
  33. package/lib/loaders/assortmentMediaTextLoader.js +15 -0
  34. package/lib/loaders/assortmentMediaTextLoader.js.map +1 -0
  35. package/lib/loaders/assortmentMediasLoader.d.ts +10 -0
  36. package/lib/loaders/assortmentMediasLoader.d.ts.map +1 -0
  37. package/lib/loaders/assortmentMediasLoader.js +18 -0
  38. package/lib/loaders/assortmentMediasLoader.js.map +1 -0
  39. package/lib/loaders/assortmentProductLoader.d.ts +12 -0
  40. package/lib/loaders/assortmentProductLoader.d.ts.map +1 -0
  41. package/lib/loaders/assortmentProductLoader.js +14 -0
  42. package/lib/loaders/assortmentProductLoader.js.map +1 -0
  43. package/lib/loaders/assortmentProductsLoader.d.ts +10 -0
  44. package/lib/loaders/assortmentProductsLoader.d.ts.map +1 -0
  45. package/lib/loaders/assortmentProductsLoader.js +18 -0
  46. package/lib/loaders/assortmentProductsLoader.js.map +1 -0
  47. package/lib/loaders/assortmentTextLoader.d.ts +12 -0
  48. package/lib/loaders/assortmentTextLoader.d.ts.map +1 -0
  49. package/lib/loaders/assortmentTextLoader.js +15 -0
  50. package/lib/loaders/assortmentTextLoader.js.map +1 -0
  51. package/lib/loaders/buildLocaleMap.d.ts +6 -0
  52. package/lib/loaders/buildLocaleMap.d.ts.map +1 -0
  53. package/lib/loaders/buildLocaleMap.js +38 -0
  54. package/lib/loaders/buildLocaleMap.js.map +1 -0
  55. package/lib/loaders/buildTextMap.d.ts +1 -1
  56. package/lib/loaders/buildTextMap.d.ts.map +1 -1
  57. package/lib/loaders/buildTextMap.js +16 -6
  58. package/lib/loaders/buildTextMap.js.map +1 -1
  59. package/lib/loaders/countryLoader.d.ts +10 -0
  60. package/lib/loaders/countryLoader.d.ts.map +1 -0
  61. package/lib/loaders/countryLoader.js +14 -0
  62. package/lib/loaders/countryLoader.js.map +1 -0
  63. package/lib/loaders/currencyLoader.d.ts +10 -0
  64. package/lib/loaders/currencyLoader.d.ts.map +1 -0
  65. package/lib/loaders/currencyLoader.js +14 -0
  66. package/lib/loaders/currencyLoader.js.map +1 -0
  67. package/lib/loaders/deliveryProviderLoader.d.ts +10 -0
  68. package/lib/loaders/deliveryProviderLoader.d.ts.map +1 -0
  69. package/lib/loaders/deliveryProviderLoader.js +13 -0
  70. package/lib/loaders/deliveryProviderLoader.js.map +1 -0
  71. package/lib/loaders/fileLoader.d.ts +10 -0
  72. package/lib/loaders/fileLoader.d.ts.map +1 -0
  73. package/lib/loaders/fileLoader.js +13 -0
  74. package/lib/loaders/fileLoader.js.map +1 -0
  75. package/lib/loaders/filterLoader.d.ts +10 -0
  76. package/lib/loaders/filterLoader.d.ts.map +1 -0
  77. package/lib/loaders/filterLoader.js +14 -0
  78. package/lib/loaders/filterLoader.js.map +1 -0
  79. package/lib/loaders/filterTextLoader.d.ts +14 -0
  80. package/lib/loaders/filterTextLoader.d.ts.map +1 -0
  81. package/lib/loaders/filterTextLoader.js +15 -0
  82. package/lib/loaders/filterTextLoader.js.map +1 -0
  83. package/lib/loaders/index.d.ts.map +1 -1
  84. package/lib/loaders/index.js +1 -29
  85. package/lib/loaders/index.js.map +1 -1
  86. package/lib/loaders/languageLoader.d.ts +10 -0
  87. package/lib/loaders/languageLoader.d.ts.map +1 -0
  88. package/lib/loaders/languageLoader.js +14 -0
  89. package/lib/loaders/languageLoader.js.map +1 -0
  90. package/lib/loaders/orderLoader.d.ts +10 -0
  91. package/lib/loaders/orderLoader.d.ts.map +1 -0
  92. package/lib/loaders/orderLoader.js +16 -0
  93. package/lib/loaders/orderLoader.js.map +1 -0
  94. package/lib/loaders/paymentProviderLoader.d.ts +10 -0
  95. package/lib/loaders/paymentProviderLoader.d.ts.map +1 -0
  96. package/lib/loaders/paymentProviderLoader.js +13 -0
  97. package/lib/loaders/paymentProviderLoader.js.map +1 -0
  98. package/lib/loaders/productLoader.d.ts +10 -0
  99. package/lib/loaders/productLoader.d.ts.map +1 -0
  100. package/lib/loaders/productLoader.js +16 -0
  101. package/lib/loaders/productLoader.js.map +1 -0
  102. package/lib/loaders/productLoaderBySKU.d.ts +10 -0
  103. package/lib/loaders/productLoaderBySKU.d.ts.map +1 -0
  104. package/lib/loaders/productLoaderBySKU.js +16 -0
  105. package/lib/loaders/productLoaderBySKU.js.map +1 -0
  106. package/lib/loaders/productMediaTextLoader.d.ts +12 -0
  107. package/lib/loaders/productMediaTextLoader.d.ts.map +1 -0
  108. package/lib/loaders/productMediaTextLoader.js +15 -0
  109. package/lib/loaders/productMediaTextLoader.js.map +1 -0
  110. package/lib/loaders/productMediasLoader.d.ts +10 -0
  111. package/lib/loaders/productMediasLoader.d.ts.map +1 -0
  112. package/lib/loaders/productMediasLoader.js +18 -0
  113. package/lib/loaders/productMediasLoader.js.map +1 -0
  114. package/lib/loaders/productTextLoader.d.ts +12 -0
  115. package/lib/loaders/productTextLoader.d.ts.map +1 -0
  116. package/lib/loaders/productTextLoader.js +15 -0
  117. package/lib/loaders/productTextLoader.js.map +1 -0
  118. package/lib/loaders/userLoader.d.ts +10 -0
  119. package/lib/loaders/userLoader.d.ts.map +1 -0
  120. package/lib/loaders/userLoader.js +17 -0
  121. package/lib/loaders/userLoader.js.map +1 -0
  122. package/lib/loaders/utils.d.ts +7 -0
  123. package/lib/loaders/utils.d.ts.map +1 -0
  124. package/lib/loaders/utils.js +29 -0
  125. package/lib/loaders/utils.js.map +1 -0
  126. package/lib/mcp/index.d.ts +4 -0
  127. package/lib/mcp/index.d.ts.map +1 -0
  128. package/lib/mcp/index.js +12 -0
  129. package/lib/mcp/index.js.map +1 -0
  130. package/lib/mcp/server.d.ts +4 -0
  131. package/lib/mcp/server.d.ts.map +1 -0
  132. package/lib/mcp/server.js +60 -0
  133. package/lib/mcp/server.js.map +1 -0
  134. package/lib/mcp/tools/getProduct.d.ts +51 -0
  135. package/lib/mcp/tools/getProduct.d.ts.map +1 -0
  136. package/lib/mcp/tools/getProduct.js +428 -0
  137. package/lib/mcp/tools/getProduct.js.map +1 -0
  138. package/lib/mcp/tools/index.d.ts +6 -0
  139. package/lib/mcp/tools/index.d.ts.map +1 -0
  140. package/lib/mcp/tools/index.js +6 -0
  141. package/lib/mcp/tools/index.js.map +1 -0
  142. package/lib/mcp/tools/listProducts.d.ts +112 -0
  143. package/lib/mcp/tools/listProducts.d.ts.map +1 -0
  144. package/lib/mcp/tools/listProducts.js +111 -0
  145. package/lib/mcp/tools/listProducts.js.map +1 -0
  146. package/lib/mcp/types.d.ts +27 -0
  147. package/lib/mcp/types.d.ts.map +1 -0
  148. package/lib/mcp/types.js +5 -0
  149. package/lib/mcp/types.js.map +1 -0
  150. package/lib/mcp/utils/html.d.ts +16 -0
  151. package/lib/mcp/utils/html.d.ts.map +1 -0
  152. package/lib/mcp/utils/html.js +102 -0
  153. package/lib/mcp/utils/html.js.map +1 -0
  154. package/lib/middleware/accountLockout.d.ts.map +1 -0
  155. package/lib/middleware/accountLockout.js +84 -0
  156. package/lib/middleware/accountLockout.js.map +1 -0
  157. package/lib/middleware/rateLimiter.d.ts.map +1 -0
  158. package/lib/middleware/rateLimiter.js +91 -0
  159. package/lib/middleware/rateLimiter.js.map +1 -0
  160. package/lib/plugins/inputValidation.d.ts.map +1 -0
  161. package/lib/plugins/inputValidation.js +95 -0
  162. package/lib/plugins/inputValidation.js.map +1 -0
  163. package/lib/schema/mutation.js +1 -1
  164. package/lib/utils/inputValidation.d.ts.map +1 -0
  165. package/lib/utils/inputValidation.js +51 -0
  166. package/lib/utils/inputValidation.js.map +1 -0
  167. package/package.json +1 -1
  168. package/src/loaders/buildLocaleMap.test.ts +72 -0
  169. package/src/loaders/buildLocaleMap.ts +39 -0
  170. package/src/loaders/buildTextMap.test.ts +55 -0
  171. package/src/loaders/buildTextMap.ts +22 -6
  172. package/src/loaders/index.ts +1 -31
  173. package/src/schema/mutation.ts +1 -1
@@ -0,0 +1,111 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Zod schema for the list_products tool (as raw object for MCP)
4
+ */
5
+ export const ListProductsSchema = {
6
+ // Search & Filter
7
+ queryString: z.string().optional().describe('Text search across product fields'),
8
+ tags: z.array(z.string()).optional().describe('Filter by product tags'),
9
+ productIds: z.array(z.string()).optional().describe('Filter by specific product IDs'),
10
+ filterQuery: z
11
+ .array(z.object({
12
+ key: z.string().describe('Filter key'),
13
+ value: z.string().optional().describe('Filter value'),
14
+ }))
15
+ .optional()
16
+ .describe('Key-value filter pairs'),
17
+ assortmentId: z.string().optional().describe('Filter by assortment'),
18
+ includeInactive: z.boolean().default(false).describe('Include inactive products'),
19
+ // Pagination
20
+ limit: z.number().min(1).max(100).default(20).describe('Results per page'),
21
+ offset: z.number().min(0).default(0).describe('Skip results for pagination'),
22
+ // Sorting
23
+ sort: z
24
+ .array(z.object({
25
+ key: z.string().describe('Sort field'),
26
+ value: z.enum(['ASC', 'DESC']).describe('Sort direction'),
27
+ }))
28
+ .optional()
29
+ .describe('Sort options'),
30
+ };
31
+ /**
32
+ * Zod object schema for type inference
33
+ */
34
+ export const ListProductsZodSchema = z.object(ListProductsSchema);
35
+ /**
36
+ * Implementation of the list_products tool
37
+ */
38
+ export async function listProductsHandler(context, params) {
39
+ const { queryString, tags, productIds, filterQuery, assortmentId, includeInactive = false, limit = 20, offset = 0, sort, } = params;
40
+ try {
41
+ let filteredProductIds = productIds;
42
+ // If assortmentId is provided, get product IDs from assortment
43
+ if (assortmentId) {
44
+ const assortmentProductIds = await context.modules.assortments.products.findProductIds({
45
+ assortmentId,
46
+ });
47
+ if (filteredProductIds) {
48
+ // Intersection of both sets
49
+ filteredProductIds = filteredProductIds.filter((id) => assortmentProductIds.includes(id));
50
+ }
51
+ else {
52
+ filteredProductIds = assortmentProductIds;
53
+ }
54
+ }
55
+ const searchResult = await context.services.filters.searchProducts({
56
+ queryString,
57
+ productIds: filteredProductIds,
58
+ includeInactive,
59
+ filterQuery: filterQuery?.filter((f) => f.key),
60
+ }, {
61
+ locale: context.locale,
62
+ });
63
+ const products = await context.modules.products.findProducts({
64
+ productIds: searchResult.aggregatedFilteredProductIds,
65
+ tags,
66
+ limit,
67
+ offset,
68
+ sort: sort?.filter((s) => s.key),
69
+ });
70
+ const productTexts = await context.loaders.productTextLoader.loadMany(searchResult.aggregatedFilteredProductIds.map((productId) => ({
71
+ productId,
72
+ locale: context.locale,
73
+ })));
74
+ // iterate all products and add texts
75
+ products.forEach((product) => {
76
+ const texts = productTexts.filter((text) => text.productId === product._id);
77
+ product.texts = texts;
78
+ });
79
+ // const htmlContent = generateProductsHTML(products, productTexts, {
80
+ // offset,
81
+ // limit,
82
+ // total,
83
+ // });
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: JSON.stringify({
89
+ products,
90
+ total: searchResult.aggregatedTotalProductIds.length,
91
+ filtered: searchResult.aggregatedFilteredProductIds.length,
92
+ }),
93
+ },
94
+ // {
95
+ // type: 'resource',
96
+ // resource: {
97
+ // text: htmlContent,
98
+ // uri: `data:text/html,charset=UTF-8,${encodeURIComponent(htmlContent)}`,
99
+ // mimeType: 'text/html',
100
+ // },
101
+ // },
102
+ ],
103
+ };
104
+ }
105
+ catch (error) {
106
+ return {
107
+ content: [{ type: 'text', text: `Error listing products: ${error.message}` }],
108
+ };
109
+ }
110
+ }
111
+ //# sourceMappingURL=listProducts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listProducts.js","sourceRoot":"","sources":["../../../src/mcp/tools/listProducts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared types for MCP tools
3
+ */
4
+ /**
5
+ * Base tool response type
6
+ */
7
+ export interface ToolResponse {
8
+ content: {
9
+ type: 'text' | 'resource';
10
+ text?: string;
11
+ resource?: {
12
+ text: string;
13
+ uri: string;
14
+ mimeType: string;
15
+ };
16
+ }[];
17
+ }
18
+ /**
19
+ * Error response type
20
+ */
21
+ export interface ErrorResponse {
22
+ content: {
23
+ type: 'text';
24
+ text: string;
25
+ }[];
26
+ }
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mcp/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE;YACT,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;YACZ,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC;KACH,EAAE,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,EAAE,CAAC;CACL"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared types for MCP tools
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mcp/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * HTML generation utilities for MCP server responses
3
+ */
4
+ /**
5
+ * Escape HTML special characters to prevent XSS
6
+ */
7
+ export declare function escapeHtml(text: string): string;
8
+ /**
9
+ * Generate HTML output for products list with Unchained styling
10
+ */
11
+ export declare function generateProductsHTML(products: any[], productTexts: any[], pagination: {
12
+ offset: number;
13
+ limit: number;
14
+ total: number;
15
+ }): string;
16
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/mcp/utils/html.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,GAAG,EAAE,EACf,YAAY,EAAE,GAAG,EAAE,EACnB,UAAU,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3D,MAAM,CAuCR"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * HTML generation utilities for MCP server responses
3
+ */
4
+ /**
5
+ * Escape HTML special characters to prevent XSS
6
+ */
7
+ export function escapeHtml(text) {
8
+ if (!text)
9
+ return '';
10
+ return text
11
+ .replace(/&/g, '&')
12
+ .replace(/</g, '&lt;')
13
+ .replace(/>/g, '&gt;')
14
+ .replace(/"/g, '&quot;')
15
+ .replace(/'/g, '&#39;');
16
+ }
17
+ /**
18
+ * Generate HTML output for products list with Unchained styling
19
+ */
20
+ export function generateProductsHTML(products, productTexts, pagination) {
21
+ const { offset, total } = pagination;
22
+ const resultsShown = products.length;
23
+ const startIndex = offset + 1;
24
+ const endIndex = offset + resultsShown;
25
+ return `
26
+ <!DOCTYPE html>
27
+ <html>
28
+ <head>
29
+ <meta charset="UTF-8" />
30
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
31
+ </head>
32
+ <body>
33
+ <div style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui; max-width: 1200px;">
34
+ <div style="margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center;">
35
+ <h3 style="color: #343a40; margin: 0;">Products</h3>
36
+ <span style="color: #6c757d; font-size: 14px;">Showing ${startIndex}-${endIndex} of ${total}</span>
37
+ </div>
38
+
39
+ <div style="background: white; border-radius: 6px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); overflow: hidden;">
40
+ <table style="width: 100%; border-collapse: collapse;">
41
+ <thead style="background: #f8f9fa; border-bottom: 1px solid #e9ecef;">
42
+ <tr>
43
+ <th style="padding: 12px; text-align: left; font-weight: 600; color: #343a40;">Image</th>
44
+ <th style="padding: 12px; text-align: left; font-weight: 600; color: #343a40;">Product</th>
45
+ <th style="padding: 12px; text-align: left; font-weight: 600; color: #343a40;">SKU</th>
46
+ <th style="padding: 12px; text-align: left; font-weight: 600; color: #343a40;">Status</th>
47
+ <th style="padding: 12px; text-align: left; font-weight: 600; color: #343a40;">ID</th>
48
+ </tr>
49
+ </thead>
50
+ <tbody>
51
+ ${products.map((product, index) => generateProductRow(product, index)).join('')}
52
+ </tbody>
53
+ </table>
54
+ </div>
55
+ </div>
56
+ </body>
57
+ </html>`;
58
+ }
59
+ /**
60
+ * Generate a single product row for the HTML table
61
+ */
62
+ function generateProductRow(product, index) {
63
+ const isEven = index % 2 === 0;
64
+ const backgroundColor = isEven ? '#ffffff' : '#f8f9fa';
65
+ // Get product title from texts
66
+ const title = product.texts?.find((t) => t.locale === 'en')?.title || product.title || 'Untitled Product';
67
+ // Get SKU from warehousing info
68
+ const sku = product.warehousing?.sku || 'N/A';
69
+ // Get status with proper formatting
70
+ const status = product.status || 'DRAFT';
71
+ const statusColor = status === 'ACTIVE' ? '#28a745' : status === 'DRAFT' ? '#ffc107' : '#6c757d';
72
+ // Product ID (shortened for display)
73
+ const productId = product._id?.toString() || 'N/A';
74
+ const shortId = productId.length > 12 ? `${productId.substring(0, 12)}...` : productId;
75
+ return `
76
+ <tr style="background: ${backgroundColor}; border-bottom: 1px solid #e9ecef;">
77
+ <td style="padding: 12px;">
78
+ <div style="width: 40px; height: 40px; background: #e9ecef; border-radius: 4px; display: flex; align-items: center; justify-content: center; color: #6c757d; font-size: 12px;">
79
+ IMG
80
+ </div>
81
+ </td>
82
+ <td style="padding: 12px;">
83
+ <div style="font-weight: 500; color: #343a40;">${escapeHtml(title)}</div>
84
+ ${product.tags?.length
85
+ ? `<div style="font-size: 12px; color: #6c757d; margin-top: 4px;">${product.tags
86
+ .slice(0, 3)
87
+ .map((tag) => `<span style="background: #e9ecef; padding: 2px 6px; border-radius: 3px; margin-right: 4px;">${escapeHtml(tag)}</span>`)
88
+ .join('')}</div>`
89
+ : ''}
90
+ </td>
91
+ <td style="padding: 12px;">
92
+ <span style="color: #343a40; font-family: monospace;">${escapeHtml(sku)}</span>
93
+ </td>
94
+ <td style="padding: 12px;">
95
+ <span style="color: ${statusColor}; font-weight: 500; font-size: 12px; text-transform: uppercase; background: ${statusColor}20; padding: 4px 8px; border-radius: 12px;">${status}</span>
96
+ </td>
97
+ <td style="padding: 12px;">
98
+ <span style="color: #6c757d; font-family: monospace; font-size: 12px;" title="${escapeHtml(productId)}">${escapeHtml(shortId)}</span>
99
+ </td>
100
+ </tr>`;
101
+ }
102
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../../src/mcp/utils/html.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accountLockout.d.ts","sourceRoot":"","sources":["../../src/middleware/accountLockout.ts"],"names":[],"mappings":"AAuCA,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3E;AAED,wBAAsB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuChF;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E"}
@@ -0,0 +1,84 @@
1
+ import { GraphQLError } from 'graphql';
2
+ // Store login attempts by user identifier (username/email)
3
+ const loginAttempts = new Map();
4
+ // Configuration
5
+ const MAX_ATTEMPTS = 5;
6
+ const LOCKOUT_DURATION = 30 * 60 * 1000; // 30 minutes
7
+ const ATTEMPT_WINDOW = 15 * 60 * 1000; // 15 minutes
8
+ // Clean up old entries periodically
9
+ setInterval(() => {
10
+ const now = Date.now();
11
+ for (const [key, attempt] of loginAttempts.entries()) {
12
+ // Remove entries older than 24 hours
13
+ if (now - attempt.lastAttempt > 24 * 60 * 60 * 1000) {
14
+ loginAttempts.delete(key);
15
+ }
16
+ }
17
+ }, 60 * 60 * 1000); // Clean every hour
18
+ async function createIdentifierHash(identifier) {
19
+ const encoder = new TextEncoder();
20
+ const dataBuffer = encoder.encode(identifier.toLowerCase());
21
+ const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
22
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
23
+ return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
24
+ }
25
+ export async function checkAccountLockout(identifier) {
26
+ const hashedIdentifier = await createIdentifierHash(identifier);
27
+ const attempt = loginAttempts.get(hashedIdentifier);
28
+ if (!attempt)
29
+ return;
30
+ const now = Date.now();
31
+ // Check if account is locked
32
+ if (attempt.lockedUntil && attempt.lockedUntil > now) {
33
+ const remainingMinutes = Math.ceil((attempt.lockedUntil - now) / 60000);
34
+ throw new GraphQLError(`Account is locked. Please try again in ${remainingMinutes} minutes.`, {
35
+ extensions: {
36
+ code: 'ACCOUNT_LOCKED',
37
+ lockedUntil: attempt.lockedUntil,
38
+ remainingMinutes,
39
+ },
40
+ });
41
+ }
42
+ // Reset attempts if outside the window
43
+ if (now - attempt.firstAttempt > ATTEMPT_WINDOW) {
44
+ loginAttempts.delete(hashedIdentifier);
45
+ }
46
+ }
47
+ export async function recordFailedLoginAttempt(identifier) {
48
+ const hashedIdentifier = await createIdentifierHash(identifier);
49
+ const now = Date.now();
50
+ let attempt = loginAttempts.get(hashedIdentifier);
51
+ if (!attempt || now - attempt.firstAttempt > ATTEMPT_WINDOW) {
52
+ // Create new attempt record or reset if outside window
53
+ attempt = {
54
+ count: 1,
55
+ firstAttempt: now,
56
+ lastAttempt: now,
57
+ };
58
+ }
59
+ else {
60
+ // Increment existing attempt
61
+ attempt.count++;
62
+ attempt.lastAttempt = now;
63
+ // Lock account if max attempts exceeded
64
+ if (attempt.count >= MAX_ATTEMPTS) {
65
+ attempt.lockedUntil = now + LOCKOUT_DURATION;
66
+ }
67
+ }
68
+ loginAttempts.set(hashedIdentifier, attempt);
69
+ // Provide warning about remaining attempts
70
+ if (attempt.count >= 3 && attempt.count < MAX_ATTEMPTS) {
71
+ const remainingAttempts = MAX_ATTEMPTS - attempt.count;
72
+ throw new GraphQLError(`Invalid credentials. ${remainingAttempts} attempts remaining before account lockout.`, {
73
+ extensions: {
74
+ code: 'INVALID_CREDENTIALS',
75
+ remainingAttempts,
76
+ },
77
+ });
78
+ }
79
+ }
80
+ export async function clearLoginAttempts(identifier) {
81
+ const hashedIdentifier = await createIdentifierHash(identifier);
82
+ loginAttempts.delete(hashedIdentifier);
83
+ }
84
+ //# sourceMappingURL=accountLockout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accountLockout.js","sourceRoot":"","sources":["../../src/middleware/accountLockout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../src/middleware/rateLimiter.ts"],"names":[],"mappings":"AAEA,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD;AAkCD,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,EAAE,UAAS,gBAAqB,MAmBnE,SAAS,GAAG,qBA8B3B,CAAC;AAGF,eAAO,MAAM,eAAe,YAjCH,GAAG,qBAqC1B,CAAC;AAEH,eAAO,MAAM,wBAAwB,YAvCZ,GAAG,qBAiD1B,CAAC;AAEH,eAAO,MAAM,uBAAuB,YAnDX,GAAG,qBA4D1B,CAAC"}
@@ -0,0 +1,91 @@
1
+ import { GraphQLError } from 'graphql';
2
+ const stores = {};
3
+ // Clean up expired entries periodically
4
+ setInterval(() => {
5
+ const now = Date.now();
6
+ Object.keys(stores).forEach((storeName) => {
7
+ const store = stores[storeName];
8
+ Object.keys(store).forEach((key) => {
9
+ if (store[key].resetTime < now) {
10
+ delete store[key];
11
+ }
12
+ });
13
+ });
14
+ }, 60000); // Clean every minute
15
+ // Helper to create hash using WebCrypto
16
+ async function createHash(data) {
17
+ const encoder = new TextEncoder();
18
+ const dataBuffer = encoder.encode(data);
19
+ const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
20
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
21
+ return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
22
+ }
23
+ export const createRateLimiter = (storeName, options = {}) => {
24
+ const { windowMs = 15 * 60 * 1000, // 15 minutes default
25
+ max = 5, // 5 requests per window default
26
+ message = 'Too many requests, please try again later.', keyGenerator = async (context) => {
27
+ // Default key generator uses IP + userId
28
+ const ip = context.req?.ip || context.req?.connection?.remoteAddress || 'unknown';
29
+ const userId = context.userId || 'anonymous';
30
+ return createHash(`${ip}-${userId}`);
31
+ }, } = options;
32
+ // Initialize store for this limiter
33
+ if (!stores[storeName]) {
34
+ stores[storeName] = {};
35
+ }
36
+ const store = stores[storeName];
37
+ return async (context) => {
38
+ const key = await keyGenerator(context);
39
+ const now = Date.now();
40
+ // Get or create rate limit entry
41
+ let entry = store[key];
42
+ if (!entry || entry.resetTime < now) {
43
+ entry = {
44
+ count: 0,
45
+ resetTime: now + windowMs,
46
+ };
47
+ store[key] = entry;
48
+ }
49
+ // Increment counter
50
+ entry.count++;
51
+ // Check if limit exceeded
52
+ if (entry.count > max) {
53
+ const retryAfter = Math.ceil((entry.resetTime - now) / 1000);
54
+ throw new GraphQLError(message, {
55
+ extensions: {
56
+ code: 'RATE_LIMIT_EXCEEDED',
57
+ retryAfter,
58
+ },
59
+ });
60
+ }
61
+ return true;
62
+ };
63
+ };
64
+ // Pre-configured rate limiters for common use cases
65
+ export const authRateLimiter = createRateLimiter('auth', {
66
+ windowMs: 15 * 60 * 1000, // 15 minutes
67
+ max: 5, // 5 attempts per 15 minutes
68
+ message: 'Too many authentication attempts. Please try again later.',
69
+ });
70
+ export const passwordResetRateLimiter = createRateLimiter('passwordReset', {
71
+ windowMs: 60 * 60 * 1000, // 1 hour
72
+ max: 3, // 3 attempts per hour
73
+ message: 'Too many password reset requests. Please try again later.',
74
+ keyGenerator: async (context) => {
75
+ // Rate limit by email/username instead of IP for password reset
76
+ const { email, username } = context.args || {};
77
+ const identifier = email || username || 'unknown';
78
+ return createHash(identifier.toLowerCase());
79
+ },
80
+ });
81
+ export const registrationRateLimiter = createRateLimiter('registration', {
82
+ windowMs: 60 * 60 * 1000, // 1 hour
83
+ max: 10, // 10 registrations per hour per IP
84
+ message: 'Too many registration attempts. Please try again later.',
85
+ keyGenerator: async (context) => {
86
+ // Rate limit by IP only for registrations
87
+ const ip = context.req?.ip || context.req?.connection?.remoteAddress || 'unknown';
88
+ return createHash(ip);
89
+ },
90
+ });
91
+ //# sourceMappingURL=rateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../src/middleware/rateLimiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputValidation.d.ts","sourceRoot":"","sources":["../../src/plugins/inputValidation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AA6DtC,MAAM,WAAW,sBAAsB;IAErC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IAEtB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAErD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,CA6C/E"}
@@ -0,0 +1,95 @@
1
+ import { GraphQLError } from 'graphql';
2
+ // Dangerous patterns to check for
3
+ const DANGEROUS_PATTERNS = [
4
+ /<script/i, // Script tags
5
+ /<iframe/i, // Iframes
6
+ /<object/i, // Object embeds
7
+ /<embed/i, // Embed tags
8
+ /<link/i, // Link tags (can load CSS)
9
+ /javascript:/i, // JavaScript protocol
10
+ /vbscript:/i, // VBScript protocol
11
+ /on\w+\s*=/i, // Event handlers (onclick, onload, etc)
12
+ /<meta/i, // Meta tags
13
+ /data:text\/html/i, // Data URLs with HTML
14
+ /<svg.*onload/i, // SVG with event handlers
15
+ /&#x?[0-9a-f]+;/i, // HTML entities (could be obfuscation)
16
+ /\\u[0-9a-f]{4}/i, // Unicode escapes
17
+ /expression\s*\(/i, // CSS expressions
18
+ /@import/i, // CSS imports
19
+ /<!--|-->/, // HTML comments
20
+ ];
21
+ function checkForDangerousContent(value, path) {
22
+ for (const dangerous of DANGEROUS_PATTERNS) {
23
+ if (dangerous.test(value)) {
24
+ throw new GraphQLError(`Potentially dangerous content detected in ${path}`, {
25
+ extensions: {
26
+ code: 'DANGEROUS_INPUT',
27
+ path,
28
+ },
29
+ });
30
+ }
31
+ }
32
+ }
33
+ function validateValue(value, path = '') {
34
+ if (value === null || value === undefined) {
35
+ return value;
36
+ }
37
+ if (typeof value === 'string') {
38
+ checkForDangerousContent(value, path);
39
+ return value;
40
+ }
41
+ if (Array.isArray(value)) {
42
+ return value.map((item, index) => validateValue(item, `${path}[${index}]`));
43
+ }
44
+ if (typeof value === 'object') {
45
+ const validated = {};
46
+ for (const [key, val] of Object.entries(value)) {
47
+ validated[key] = validateValue(val, path ? `${path}.${key}` : key);
48
+ }
49
+ return validated;
50
+ }
51
+ return value;
52
+ }
53
+ export function useInputValidation(options = {}) {
54
+ const { skipOperations = [], skipFields = [], customValidator, logErrors = false } = options;
55
+ return {
56
+ onParams({ params, setParams }) {
57
+ // Get operation name from the request
58
+ const operationName = params.operationName || '';
59
+ // Skip if operation is in skip list
60
+ if (operationName && skipOperations.includes(operationName)) {
61
+ return;
62
+ }
63
+ try {
64
+ // Validate variables
65
+ if (params.variables) {
66
+ const validatedVariables = {};
67
+ for (const [key, value] of Object.entries(params.variables)) {
68
+ if (!skipFields.includes(key)) {
69
+ validatedVariables[key] = validateValue(value, `variables.${key}`);
70
+ // Run custom validator if provided
71
+ if (customValidator) {
72
+ customValidator(value, `variables.${key}`);
73
+ }
74
+ }
75
+ else {
76
+ validatedVariables[key] = value;
77
+ }
78
+ }
79
+ // Update params with validated variables
80
+ setParams({
81
+ ...params,
82
+ variables: validatedVariables,
83
+ });
84
+ }
85
+ }
86
+ catch (error) {
87
+ if (logErrors) {
88
+ console.error('Input validation error:', error);
89
+ }
90
+ throw error;
91
+ }
92
+ },
93
+ };
94
+ }
95
+ //# sourceMappingURL=inputValidation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputValidation.js","sourceRoot":"","sources":["../../src/plugins/inputValidation.ts"],"names":[],"mappings":"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"}
@@ -339,7 +339,7 @@ export default [
339
339
  """
340
340
  Set a new password for a specific user
341
341
  """
342
- setPassword(newPassword!: String, userId: ID!): User!
342
+ setPassword(newPassword: String!, userId: ID!): User!
343
343
 
344
344
  """
345
345
  Set roles of a user
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputValidation.d.ts","sourceRoot":"","sources":["../../src/utils/inputValidation.ts"],"names":[],"mappings":"AAuBA,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAU5D;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,SAAK,GAAG,GAAG,CAmBvD"}