@memberjunction/server 5.38.0 → 5.40.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 (180) hide show
  1. package/README.md +67 -0
  2. package/dist/apolloServer/index.d.ts +0 -8
  3. package/dist/apolloServer/index.d.ts.map +1 -1
  4. package/dist/apolloServer/index.js +61 -0
  5. package/dist/apolloServer/index.js.map +1 -1
  6. package/dist/auth/index.js +1 -1
  7. package/dist/auth/index.js.map +1 -1
  8. package/dist/auth/magicLink/MagicLinkKeys.d.ts +58 -0
  9. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -0
  10. package/dist/auth/magicLink/MagicLinkKeys.js +99 -0
  11. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -0
  12. package/dist/auth/magicLink/MagicLinkRouter.d.ts +33 -0
  13. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -0
  14. package/dist/auth/magicLink/MagicLinkRouter.js +184 -0
  15. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -0
  16. package/dist/auth/magicLink/MagicLinkService.d.ts +123 -0
  17. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -0
  18. package/dist/auth/magicLink/MagicLinkService.js +605 -0
  19. package/dist/auth/magicLink/MagicLinkService.js.map +1 -0
  20. package/dist/auth/magicLink/index.d.ts +6 -0
  21. package/dist/auth/magicLink/index.d.ts.map +1 -0
  22. package/dist/auth/magicLink/index.js +6 -0
  23. package/dist/auth/magicLink/index.js.map +1 -0
  24. package/dist/auth/magicLink/magicLinkCore.d.ts +82 -0
  25. package/dist/auth/magicLink/magicLinkCore.d.ts.map +1 -0
  26. package/dist/auth/magicLink/magicLinkCore.js +164 -0
  27. package/dist/auth/magicLink/magicLinkCore.js.map +1 -0
  28. package/dist/auth/magicLink/redeemLanding.d.ts +22 -0
  29. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -0
  30. package/dist/auth/magicLink/redeemLanding.js +61 -0
  31. package/dist/auth/magicLink/redeemLanding.js.map +1 -0
  32. package/dist/auth/magicLink/types.d.ts +131 -0
  33. package/dist/auth/magicLink/types.d.ts.map +1 -0
  34. package/dist/auth/magicLink/types.js +6 -0
  35. package/dist/auth/magicLink/types.js.map +1 -0
  36. package/dist/config.d.ts +479 -0
  37. package/dist/config.d.ts.map +1 -1
  38. package/dist/config.js +84 -0
  39. package/dist/config.js.map +1 -1
  40. package/dist/context.d.ts.map +1 -1
  41. package/dist/context.js +223 -19
  42. package/dist/context.js.map +1 -1
  43. package/dist/generated/generated.d.ts +952 -4
  44. package/dist/generated/generated.d.ts.map +1 -1
  45. package/dist/generated/generated.js +25663 -20321
  46. package/dist/generated/generated.js.map +1 -1
  47. package/dist/generic/FireAndForgetHeartbeat.d.ts +51 -0
  48. package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -0
  49. package/dist/generic/FireAndForgetHeartbeat.js +44 -0
  50. package/dist/generic/FireAndForgetHeartbeat.js.map +1 -0
  51. package/dist/generic/ResolverBase.d.ts.map +1 -1
  52. package/dist/generic/ResolverBase.js +35 -7
  53. package/dist/generic/ResolverBase.js.map +1 -1
  54. package/dist/index.d.ts +5 -0
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +145 -2
  57. package/dist/index.js.map +1 -1
  58. package/dist/logging/NoLog.d.ts +50 -0
  59. package/dist/logging/NoLog.d.ts.map +1 -0
  60. package/dist/logging/NoLog.js +80 -0
  61. package/dist/logging/NoLog.js.map +1 -0
  62. package/dist/logging/bootAudit.d.ts +43 -0
  63. package/dist/logging/bootAudit.d.ts.map +1 -0
  64. package/dist/logging/bootAudit.js +83 -0
  65. package/dist/logging/bootAudit.js.map +1 -0
  66. package/dist/logging/boundaryLogPayload.d.ts +18 -0
  67. package/dist/logging/boundaryLogPayload.d.ts.map +1 -0
  68. package/dist/logging/boundaryLogPayload.js +18 -0
  69. package/dist/logging/boundaryLogPayload.js.map +1 -0
  70. package/dist/logging/secretRedactor.d.ts +23 -0
  71. package/dist/logging/secretRedactor.d.ts.map +1 -0
  72. package/dist/logging/secretRedactor.js +53 -0
  73. package/dist/logging/secretRedactor.js.map +1 -0
  74. package/dist/logging/shortenForLog.d.ts +8 -0
  75. package/dist/logging/shortenForLog.d.ts.map +1 -0
  76. package/dist/logging/shortenForLog.js +21 -0
  77. package/dist/logging/shortenForLog.js.map +1 -0
  78. package/dist/logging/variablesLoggingMiddleware.d.ts +22 -0
  79. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -0
  80. package/dist/logging/variablesLoggingMiddleware.js +127 -0
  81. package/dist/logging/variablesLoggingMiddleware.js.map +1 -0
  82. package/dist/resolvers/CurrentUserContextResolver.d.ts +9 -3
  83. package/dist/resolvers/CurrentUserContextResolver.d.ts.map +1 -1
  84. package/dist/resolvers/CurrentUserContextResolver.js +19 -5
  85. package/dist/resolvers/CurrentUserContextResolver.js.map +1 -1
  86. package/dist/resolvers/EntityResolver.d.ts.map +1 -1
  87. package/dist/resolvers/EntityResolver.js +13 -2
  88. package/dist/resolvers/EntityResolver.js.map +1 -1
  89. package/dist/resolvers/GenerateSeedTaxonomyResolver.d.ts +28 -0
  90. package/dist/resolvers/GenerateSeedTaxonomyResolver.d.ts.map +1 -0
  91. package/dist/resolvers/GenerateSeedTaxonomyResolver.js +100 -0
  92. package/dist/resolvers/GenerateSeedTaxonomyResolver.js.map +1 -0
  93. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  94. package/dist/resolvers/GetDataResolver.js +8 -4
  95. package/dist/resolvers/GetDataResolver.js.map +1 -1
  96. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +259 -2
  97. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  98. package/dist/resolvers/IntegrationDiscoveryResolver.js +1276 -117
  99. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  100. package/dist/resolvers/IntegrationProgressResolver.d.ts +90 -0
  101. package/dist/resolvers/IntegrationProgressResolver.d.ts.map +1 -0
  102. package/dist/resolvers/IntegrationProgressResolver.js +196 -0
  103. package/dist/resolvers/IntegrationProgressResolver.js.map +1 -0
  104. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  105. package/dist/resolvers/MCPResolver.js +19 -14
  106. package/dist/resolvers/MCPResolver.js.map +1 -1
  107. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  108. package/dist/resolvers/RunAIAgentResolver.js +26 -5
  109. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  110. package/dist/resolvers/RunClusterAnalysisResolver.d.ts +74 -0
  111. package/dist/resolvers/RunClusterAnalysisResolver.d.ts.map +1 -0
  112. package/dist/resolvers/RunClusterAnalysisResolver.js +243 -0
  113. package/dist/resolvers/RunClusterAnalysisResolver.js.map +1 -0
  114. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  115. package/dist/resolvers/RunTestResolver.js +12 -2
  116. package/dist/resolvers/RunTestResolver.js.map +1 -1
  117. package/dist/resolvers/SearchEntitiesResolver.d.ts +46 -0
  118. package/dist/resolvers/SearchEntitiesResolver.d.ts.map +1 -0
  119. package/dist/resolvers/SearchEntitiesResolver.js +216 -0
  120. package/dist/resolvers/SearchEntitiesResolver.js.map +1 -0
  121. package/dist/resolvers/UserResolver.d.ts +16 -2
  122. package/dist/resolvers/UserResolver.d.ts.map +1 -1
  123. package/dist/resolvers/UserResolver.js +45 -2
  124. package/dist/resolvers/UserResolver.js.map +1 -1
  125. package/dist/resolvers/VectorizeEntityResolver.d.ts.map +1 -1
  126. package/dist/resolvers/VectorizeEntityResolver.js +14 -1
  127. package/dist/resolvers/VectorizeEntityResolver.js.map +1 -1
  128. package/dist/rest/SignatureWebhookHandler.d.ts +19 -0
  129. package/dist/rest/SignatureWebhookHandler.d.ts.map +1 -0
  130. package/dist/rest/SignatureWebhookHandler.js +86 -0
  131. package/dist/rest/SignatureWebhookHandler.js.map +1 -0
  132. package/dist/services/ScheduledJobsService.d.ts.map +1 -1
  133. package/dist/services/ScheduledJobsService.js +14 -2
  134. package/dist/services/ScheduledJobsService.js.map +1 -1
  135. package/package.json +79 -74
  136. package/src/__tests__/NoLog.test.ts +76 -0
  137. package/src/__tests__/bootAudit.test.ts +188 -0
  138. package/src/__tests__/boundaryLogPayload.test.ts +31 -0
  139. package/src/__tests__/getDataTokenRedaction.test.ts +84 -0
  140. package/src/__tests__/magicLink.test.ts +387 -0
  141. package/src/__tests__/secretRedactor.test.ts +163 -0
  142. package/src/__tests__/subscriptionRedaction.test.ts +217 -0
  143. package/src/apolloServer/index.ts +58 -0
  144. package/src/auth/index.ts +2 -2
  145. package/src/auth/magicLink/MagicLinkKeys.ts +122 -0
  146. package/src/auth/magicLink/MagicLinkRouter.ts +209 -0
  147. package/src/auth/magicLink/MagicLinkService.ts +724 -0
  148. package/src/auth/magicLink/index.ts +17 -0
  149. package/src/auth/magicLink/magicLinkCore.ts +216 -0
  150. package/src/auth/magicLink/redeemLanding.ts +62 -0
  151. package/src/auth/magicLink/types.ts +137 -0
  152. package/src/config.ts +89 -0
  153. package/src/context.ts +249 -17
  154. package/src/generated/generated.ts +12528 -8866
  155. package/src/generic/FireAndForgetHeartbeat.ts +85 -0
  156. package/src/generic/ResolverBase.ts +35 -7
  157. package/src/generic/__tests__/FireAndForgetHeartbeat.test.ts +99 -0
  158. package/src/index.ts +165 -2
  159. package/src/logging/NoLog.ts +88 -0
  160. package/src/logging/bootAudit.ts +117 -0
  161. package/src/logging/boundaryLogPayload.ts +19 -0
  162. package/src/logging/secretRedactor.ts +82 -0
  163. package/src/logging/shortenForLog.ts +17 -0
  164. package/src/logging/variablesLoggingMiddleware.ts +191 -0
  165. package/src/resolvers/CurrentUserContextResolver.ts +21 -5
  166. package/src/resolvers/EntityResolver.ts +17 -5
  167. package/src/resolvers/GenerateSeedTaxonomyResolver.ts +90 -0
  168. package/src/resolvers/GetDataResolver.ts +9 -5
  169. package/src/resolvers/IntegrationDiscoveryResolver.ts +1111 -120
  170. package/src/resolvers/IntegrationProgressResolver.ts +220 -0
  171. package/src/resolvers/MCPResolver.ts +18 -14
  172. package/src/resolvers/RunAIAgentResolver.ts +28 -5
  173. package/src/resolvers/RunClusterAnalysisResolver.ts +249 -0
  174. package/src/resolvers/RunTestResolver.ts +14 -2
  175. package/src/resolvers/SearchEntitiesResolver.ts +173 -0
  176. package/src/resolvers/UserResolver.ts +38 -2
  177. package/src/resolvers/VectorizeEntityResolver.ts +14 -1
  178. package/src/resolvers/__tests__/IntegrationProgressResolver.test.ts +170 -0
  179. package/src/rest/SignatureWebhookHandler.ts +103 -0
  180. package/src/services/ScheduledJobsService.ts +15 -2
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @fileoverview Inbound eSignature webhook handler (DocuSign Connect, Adobe events, …).
3
+ *
4
+ * Unauthenticated by design — external signature providers call this endpoint without an MJ bearer
5
+ * token. Payload authenticity is verified by the provider DRIVER's `ParseWebhookEvent` (HMAC /
6
+ * signature), not by MJ auth. Must be registered BEFORE the unified auth middleware.
7
+ *
8
+ * Endpoint:
9
+ * - POST /esignature/webhook/:driverKey
10
+ *
11
+ * @module @memberjunction/server/rest/SignatureWebhookHandler
12
+ */
13
+ import express from 'express';
14
+ import BodyParser from 'body-parser';
15
+ import { LogError, LogStatus } from '@memberjunction/core';
16
+ import { UserCache } from '@memberjunction/sqlserver-dataprovider';
17
+ import { SignatureEngine } from '@memberjunction/esignature/server';
18
+ /**
19
+ * Build an Express router exposing the eSignature webhook. Mount it unauthenticated:
20
+ * `app.use('/esignature', createSignatureWebhookHandler())`.
21
+ */
22
+ export function createSignatureWebhookHandler() {
23
+ const router = express.Router();
24
+ // Capture the raw body so drivers that HMAC-verify over the exact bytes can do so.
25
+ router.post('/webhook/:driverKey', BodyParser.json({ limit: '25mb', verify: captureRawBody }), async (req, res) => {
26
+ await handleWebhook(req, res);
27
+ });
28
+ return router;
29
+ }
30
+ /** Stash the raw request bytes on the request for signature verification by the driver. */
31
+ function captureRawBody(req, _res, buf) {
32
+ req.rawBody = buf;
33
+ }
34
+ async function handleWebhook(req, res) {
35
+ const driverKey = req.params.driverKey;
36
+ if (!driverKey) {
37
+ res.status(400).json({ error: 'Missing driver key in path.' });
38
+ return;
39
+ }
40
+ const contextUser = getSystemUser();
41
+ if (!contextUser) {
42
+ LogError('[eSignature webhook] No system user available; cannot process webhook.');
43
+ res.status(503).json({ error: 'Server not ready to process webhooks.' });
44
+ return;
45
+ }
46
+ try {
47
+ await SignatureEngine.Instance.Config(false, contextUser);
48
+ const headers = normalizeHeaders(req.headers);
49
+ const rawBody = req.rawBody;
50
+ const result = await SignatureEngine.Instance.RecordWebhookEvent(driverKey, req.body, headers, contextUser, rawBody);
51
+ if (!result.Success) {
52
+ // 202: we received it but couldn't act (e.g. unrecognized payload / no matching envelope).
53
+ // Returning 2xx prevents most providers from aggressively retrying a payload we'll never match.
54
+ LogStatus(`[eSignature webhook] ${driverKey}: not actioned — ${result.ErrorMessage}`);
55
+ res.status(202).json({ received: true, actioned: false, message: result.ErrorMessage });
56
+ return;
57
+ }
58
+ res.status(200).json({ received: true, actioned: true, status: result.event?.status });
59
+ }
60
+ catch (e) {
61
+ LogError(`[eSignature webhook] ${driverKey}: ${e instanceof Error ? e.message : String(e)}`);
62
+ res.status(500).json({ error: 'Failed to process webhook.' });
63
+ }
64
+ }
65
+ /** Flatten Express header values to a simple string map for the driver. */
66
+ function normalizeHeaders(headers) {
67
+ const out = {};
68
+ for (const [key, value] of Object.entries(headers)) {
69
+ if (typeof value === 'string') {
70
+ out[key] = value;
71
+ }
72
+ else if (Array.isArray(value)) {
73
+ out[key] = value.join(', ');
74
+ }
75
+ }
76
+ return out;
77
+ }
78
+ function getSystemUser() {
79
+ try {
80
+ return UserCache.Instance.GetSystemUser() ?? null;
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ //# sourceMappingURL=SignatureWebhookHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureWebhookHandler.js","sourceRoot":"","sources":["../../src/rest/SignatureWebhookHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAY,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEpE;;;GAGG;AACH,MAAM,UAAU,6BAA6B;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,mFAAmF;IACnF,MAAM,CAAC,IAAI,CACP,qBAAqB,EACrB,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,EAC1D,KAAK,EAAE,GAAoB,EAAE,GAAqB,EAAE,EAAE;QAClD,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC,CACJ,CAAC;IAEF,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,2FAA2F;AAC3F,SAAS,cAAc,CAAC,GAAoB,EAAE,IAAsB,EAAE,GAAW;IAC5E,GAAsB,CAAC,OAAO,GAAG,GAAG,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAoB,EAAE,GAAqB;IACpE,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;IACvC,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;QAC/D,OAAO;IACX,CAAC;IAED,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC;IACpC,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,QAAQ,CAAC,wEAAwE,CAAC,CAAC;QACnF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uCAAuC,EAAE,CAAC,CAAC;QACzE,OAAO;IACX,CAAC;IAED,IAAI,CAAC;QACD,MAAM,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAI,GAAsB,CAAC,OAAO,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QAErH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,2FAA2F;YAC3F,gGAAgG;YAChG,SAAS,CAAC,wBAAwB,SAAS,oBAAoB,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YACtF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YACxF,OAAO;QACX,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3F,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,QAAQ,CAAC,wBAAwB,SAAS,KAAK,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7F,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;IAClE,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,SAAS,gBAAgB,CAAC,OAAmC;IACzD,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,SAAS,aAAa;IAClB,IAAI,CAAC;QACD,OAAO,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,IAAI,IAAI,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ScheduledJobsService.d.ts","sourceRoot":"","sources":["../../src/services/ScheduledJobsService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD;;;GAGG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAKvC;;;OAGG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBxC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwCnC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBlC;;;OAGG;YACW,aAAa;IAgB3B;;OAEG;IACI,SAAS,IAAI;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;KAC3B;IASD;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;CACJ"}
1
+ {"version":3,"file":"ScheduledJobsService.d.ts","sourceRoot":"","sources":["../../src/services/ScheduledJobsService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD;;;GAGG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,EAAE,mBAAmB;IAKvC;;;OAGG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBxC;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmDnC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBlC;;;OAGG;YACW,aAAa;IAgB3B;;OAEG;IACI,SAAS,IAAI;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;KAC3B;IASD;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;CACJ"}
@@ -54,7 +54,17 @@ export class ScheduledJobsService {
54
54
  throw new Error('Service not initialized - call Initialize() first');
55
55
  }
56
56
  try {
57
- this.engine.StartPolling(this.systemUser);
57
+ // Wire engine tunables from MJServer's scheduledJobs config block.
58
+ // Both fields have schema defaults (maxConcurrentJobs=5, defaultLockTimeout=600000ms),
59
+ // but apply explicitly so the values are visible in startup logs and
60
+ // a future config change is picked up without an engine code change.
61
+ if (this.config.maxConcurrentJobs != null) {
62
+ this.engine.MaxConcurrentJobs = this.config.maxConcurrentJobs;
63
+ }
64
+ if (this.config.defaultLockTimeout != null) {
65
+ this.engine.LeaseTimeoutMs = this.config.defaultLockTimeout;
66
+ }
67
+ await this.engine.StartPolling(this.systemUser);
58
68
  this.isRunning = true;
59
69
  // Single consolidated console message
60
70
  const jobCount = this.engine.ScheduledJobs.length;
@@ -89,7 +99,9 @@ export class ScheduledJobsService {
89
99
  }
90
100
  try {
91
101
  LogStatus('[ScheduledJobsService] Stopping scheduled job polling');
92
- this.engine.StopPolling();
102
+ // Graceful shutdown: wait for in-flight dispatched jobs to settle,
103
+ // bounded by 30s so a zombie can't hang the shutdown indefinitely.
104
+ await this.engine.StopPolling({ waitForInflight: true, maxWaitMs: 30_000 });
93
105
  this.isRunning = false;
94
106
  LogStatus('[ScheduledJobsService] Polling stopped successfully');
95
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ScheduledJobsService.js","sourceRoot":"","sources":["../../src/services/ScheduledJobsService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScheduledJobsService.js","sourceRoot":"","sources":["../../src/services/ScheduledJobsService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/server",
3
- "version": "5.38.0",
3
+ "version": "5.40.0",
4
4
  "description": "MemberJunction: This project provides API access via GraphQL to the common data store.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./src/index.ts",
@@ -27,75 +27,81 @@
27
27
  "@as-integrations/express5": "^1.0.0",
28
28
  "@graphql-tools/schema": "latest",
29
29
  "@graphql-tools/utils": "^11.0.0",
30
- "@memberjunction/actions": "5.38.0",
31
- "@memberjunction/actions-apollo": "5.38.0",
32
- "@memberjunction/actions-base": "5.38.0",
33
- "@memberjunction/actions-bizapps-accounting": "5.38.0",
34
- "@memberjunction/actions-bizapps-crm": "5.38.0",
35
- "@memberjunction/actions-bizapps-formbuilders": "5.38.0",
36
- "@memberjunction/actions-bizapps-lms": "5.38.0",
37
- "@memberjunction/actions-bizapps-social": "5.38.0",
38
- "@memberjunction/ai": "5.38.0",
39
- "@memberjunction/ai-agent-manager": "5.38.0",
40
- "@memberjunction/ai-agent-manager-actions": "5.38.0",
41
- "@memberjunction/ai-agents": "5.38.0",
42
- "@memberjunction/ai-core-plus": "5.38.0",
43
- "@memberjunction/ai-mcp-client": "5.38.0",
44
- "@memberjunction/ai-prompts": "5.38.0",
45
- "@memberjunction/ai-provider-bundle": "5.38.0",
46
- "@memberjunction/ai-vector-sync": "5.38.0",
47
- "@memberjunction/ai-vectordb": "5.38.0",
48
- "@memberjunction/ai-vectors-pinecone": "5.38.0",
49
- "@memberjunction/aiengine": "5.38.0",
50
- "@memberjunction/api-keys": "5.38.0",
51
- "@memberjunction/auth-providers": "5.38.0",
52
- "@memberjunction/codegen-lib": "5.38.0",
53
- "@memberjunction/communication-ms-graph": "5.38.0",
54
- "@memberjunction/communication-sendgrid": "5.38.0",
55
- "@memberjunction/communication-types": "5.38.0",
56
- "@memberjunction/component-registry-client-sdk": "5.38.0",
57
- "@memberjunction/computer-use-engine": "5.38.0",
58
- "@memberjunction/config": "5.38.0",
59
- "@memberjunction/core": "5.38.0",
60
- "@memberjunction/core-actions": "5.38.0",
61
- "@memberjunction/core-entities": "5.38.0",
62
- "@memberjunction/core-entities-server": "5.38.0",
63
- "@memberjunction/data-context": "5.38.0",
64
- "@memberjunction/data-context-server": "5.38.0",
65
- "@memberjunction/doc-utils": "5.38.0",
66
- "@memberjunction/encryption": "5.38.0",
67
- "@memberjunction/entity-communications-base": "5.38.0",
68
- "@memberjunction/entity-communications-server": "5.38.0",
69
- "@memberjunction/external-change-detection": "5.38.0",
70
- "@memberjunction/generic-database-provider": "5.38.0",
71
- "@memberjunction/global": "5.38.0",
72
- "@memberjunction/graphql-dataprovider": "5.38.0",
73
- "@memberjunction/integration-engine": "5.38.0",
74
- "@memberjunction/integration-schema-builder": "5.38.0",
75
- "@memberjunction/interactive-component-types": "5.38.0",
76
- "@memberjunction/lists": "5.38.0",
77
- "@memberjunction/lists-base": "5.38.0",
78
- "@memberjunction/notifications": "5.38.0",
79
- "@memberjunction/postgresql-dataprovider": "5.38.0",
80
- "@memberjunction/queue": "5.38.0",
81
- "@memberjunction/redis-provider": "5.38.0",
82
- "@memberjunction/scheduling-actions": "5.38.0",
83
- "@memberjunction/scheduling-base-types": "5.38.0",
84
- "@memberjunction/scheduling-engine": "5.38.0",
85
- "@memberjunction/scheduling-engine-base": "5.38.0",
86
- "@memberjunction/schema-engine": "5.38.0",
87
- "@memberjunction/search-engine": "5.38.0",
88
- "@memberjunction/server-extensions-core": "5.38.0",
89
- "@memberjunction/skip-types": "5.38.0",
90
- "@memberjunction/sql-dialect": "5.38.0",
91
- "@memberjunction/sqlserver-dataprovider": "5.38.0",
92
- "@memberjunction/storage": "5.38.0",
93
- "@memberjunction/tag-engine": "5.38.0",
94
- "@memberjunction/tag-engine-base": "5.38.0",
95
- "@memberjunction/templates": "5.38.0",
96
- "@memberjunction/testing-engine": "5.38.0",
97
- "@memberjunction/testing-engine-base": "5.38.0",
98
- "@memberjunction/version-history": "5.38.0",
30
+ "@memberjunction/actions": "5.40.0",
31
+ "@memberjunction/actions-apollo": "5.40.0",
32
+ "@memberjunction/actions-base": "5.40.0",
33
+ "@memberjunction/actions-bizapps-accounting": "5.40.0",
34
+ "@memberjunction/actions-bizapps-crm": "5.40.0",
35
+ "@memberjunction/actions-bizapps-formbuilders": "5.40.0",
36
+ "@memberjunction/actions-bizapps-lms": "5.40.0",
37
+ "@memberjunction/actions-bizapps-social": "5.40.0",
38
+ "@memberjunction/ai": "5.40.0",
39
+ "@memberjunction/ai-agent-manager": "5.40.0",
40
+ "@memberjunction/ai-agent-manager-actions": "5.40.0",
41
+ "@memberjunction/ai-agents": "5.40.0",
42
+ "@memberjunction/ai-core-plus": "5.40.0",
43
+ "@memberjunction/ai-mcp-client": "5.40.0",
44
+ "@memberjunction/ai-prompts": "5.40.0",
45
+ "@memberjunction/ai-provider-bundle": "5.40.0",
46
+ "@memberjunction/ai-vector-sync": "5.40.0",
47
+ "@memberjunction/ai-vectordb": "5.40.0",
48
+ "@memberjunction/ai-vectors-pinecone": "5.40.0",
49
+ "@memberjunction/aiengine": "5.40.0",
50
+ "@memberjunction/clustering-engine": "5.40.0",
51
+ "@memberjunction/api-keys": "5.40.0",
52
+ "@memberjunction/auth-providers": "5.40.0",
53
+ "@memberjunction/codegen-lib": "5.40.0",
54
+ "@memberjunction/communication-engine": "5.40.0",
55
+ "@memberjunction/communication-ms-graph": "5.40.0",
56
+ "@memberjunction/communication-sendgrid": "5.40.0",
57
+ "@memberjunction/communication-types": "5.40.0",
58
+ "@memberjunction/component-registry-client-sdk": "5.40.0",
59
+ "@memberjunction/computer-use-engine": "5.40.0",
60
+ "@memberjunction/config": "5.40.0",
61
+ "@memberjunction/core": "5.40.0",
62
+ "@memberjunction/core-actions": "5.40.0",
63
+ "@memberjunction/core-entities": "5.40.0",
64
+ "@memberjunction/core-entities-server": "5.40.0",
65
+ "@memberjunction/data-context": "5.40.0",
66
+ "@memberjunction/esignature": "5.40.0",
67
+ "@memberjunction/data-context-server": "5.40.0",
68
+ "@memberjunction/doc-utils": "5.40.0",
69
+ "@memberjunction/encryption": "5.40.0",
70
+ "@memberjunction/entity-communications-base": "5.40.0",
71
+ "@memberjunction/entity-communications-server": "5.40.0",
72
+ "@memberjunction/external-change-detection": "5.40.0",
73
+ "@memberjunction/generic-database-provider": "5.40.0",
74
+ "@memberjunction/global": "5.40.0",
75
+ "@memberjunction/graphql-dataprovider": "5.40.0",
76
+ "@memberjunction/integration-engine": "5.40.0",
77
+ "@memberjunction/integration-progress-artifacts": "5.40.0",
78
+ "@memberjunction/integration-schema-builder": "5.40.0",
79
+ "@memberjunction/interactive-component-types": "5.40.0",
80
+ "@memberjunction/lists": "5.40.0",
81
+ "@memberjunction/lists-base": "5.40.0",
82
+ "@memberjunction/notifications": "5.40.0",
83
+ "@memberjunction/postgresql-dataprovider": "5.40.0",
84
+ "@memberjunction/queue": "5.40.0",
85
+ "@memberjunction/redis-provider": "5.40.0",
86
+ "@memberjunction/scheduling-actions": "5.40.0",
87
+ "@memberjunction/scheduling-base-types": "5.40.0",
88
+ "@memberjunction/scheduling-engine": "5.40.0",
89
+ "@memberjunction/scheduling-engine-base": "5.40.0",
90
+ "@memberjunction/schema-engine": "5.40.0",
91
+ "@memberjunction/search-engine": "5.40.0",
92
+ "@memberjunction/server-extensions-core": "5.40.0",
93
+ "@memberjunction/skip-types": "5.40.0",
94
+ "@memberjunction/sql-dialect": "5.40.0",
95
+ "@memberjunction/sqlserver-dataprovider": "5.40.0",
96
+ "@memberjunction/storage": "5.40.0",
97
+ "@memberjunction/tag-engine": "5.40.0",
98
+ "@memberjunction/tag-engine-base": "5.40.0",
99
+ "@memberjunction/templates": "5.40.0",
100
+ "@memberjunction/testing-engine": "5.40.0",
101
+ "@memberjunction/testing-engine-base": "5.40.0",
102
+ "@memberjunction/version-history": "5.40.0",
103
+ "@octokit/auth-app": "^7.1.5",
104
+ "@octokit/rest": "^21.1.1",
99
105
  "@types/compression": "^1.8.1",
100
106
  "@types/cors": "^2.8.19",
101
107
  "@types/jsonwebtoken": "9.0.10",
@@ -111,6 +117,7 @@
111
117
  "cosmiconfig": "9.0.0",
112
118
  "dotenv": "^17.2.4",
113
119
  "express": "^5.2.1",
120
+ "express-rate-limit": "^8.2.1",
114
121
  "fast-glob": "^3.3.3",
115
122
  "graphql": "^16.12.0",
116
123
  "graphql-scalars": "^1.25.0",
@@ -128,14 +135,12 @@
128
135
  "typedi": "^0.10.0",
129
136
  "uuid": "^13.0.0",
130
137
  "ws": "^8.19.0",
131
- "@octokit/auth-app": "^7.1.5",
132
- "@octokit/rest": "^21.1.1",
133
138
  "zod": "~3.24.4"
134
139
  },
135
140
  "devDependencies": {
136
141
  "pkgroll": "2.23.0",
137
- "vitest": "^3.1.1",
138
- "typescript": "^5.9.3"
142
+ "typescript": "^5.9.3",
143
+ "vitest": "^3.1.1"
139
144
  },
140
145
  "repository": {
141
146
  "type": "git",
@@ -0,0 +1,76 @@
1
+ import 'reflect-metadata';
2
+ import { describe, it, expect } from 'vitest';
3
+ import { NoLog, hasNoLogParameter, getNoLogFields } from '../logging/NoLog.js';
4
+
5
+ describe('NoLog decorator', () => {
6
+ it('marks a resolver method parameter (3-arg call) and is readable via hasNoLogParameter', () => {
7
+ class MyResolver {
8
+ doThing(_safeArg: string, _secret: string): void {
9
+ // method body irrelevant; decorators applied below
10
+ }
11
+ }
12
+ NoLog(MyResolver.prototype, 'doThing', 1);
13
+
14
+ expect(hasNoLogParameter(MyResolver, 'doThing', 1)).toBe(true);
15
+ expect(hasNoLogParameter(MyResolver, 'doThing', 0)).toBe(false);
16
+ expect(hasNoLogParameter(MyResolver, 'unknownMethod', 0)).toBe(false);
17
+ });
18
+
19
+ it('marks a field on an input class (2-arg call) and is readable via getNoLogFields', () => {
20
+ class MyInput {
21
+ // eslint-disable-next-line @typescript-eslint/no-inferrable-types
22
+ Token: string = '';
23
+ Queries: string[] = [];
24
+ }
25
+ NoLog(MyInput.prototype, 'Token');
26
+
27
+ const fields = getNoLogFields(MyInput);
28
+ expect(fields.has('Token')).toBe(true);
29
+ expect(fields.has('Queries')).toBe(false);
30
+ expect(fields.size).toBe(1);
31
+ });
32
+
33
+ it('returns empty results when no @NoLog has been applied', () => {
34
+ class UndecoratedResolver {
35
+ doNothing(): void {
36
+ // nothing
37
+ }
38
+ }
39
+ class UndecoratedInput {
40
+ A: string = '';
41
+ B: string = '';
42
+ }
43
+
44
+ expect(hasNoLogParameter(UndecoratedResolver, 'doNothing', 0)).toBe(false);
45
+ expect(getNoLogFields(UndecoratedInput).size).toBe(0);
46
+ });
47
+
48
+ it('supports multiple parameter marks on the same method', () => {
49
+ class TwoSecrets {
50
+ handle(_a: string, _b: string, _c: string): void {
51
+ // marks below
52
+ }
53
+ }
54
+ NoLog(TwoSecrets.prototype, 'handle', 0);
55
+ NoLog(TwoSecrets.prototype, 'handle', 2);
56
+
57
+ expect(hasNoLogParameter(TwoSecrets, 'handle', 0)).toBe(true);
58
+ expect(hasNoLogParameter(TwoSecrets, 'handle', 1)).toBe(false);
59
+ expect(hasNoLogParameter(TwoSecrets, 'handle', 2)).toBe(true);
60
+ });
61
+
62
+ it('supports multiple field marks on the same input class', () => {
63
+ class TwoFieldSecrets {
64
+ A: string = '';
65
+ B: string = '';
66
+ C: string = '';
67
+ }
68
+ NoLog(TwoFieldSecrets.prototype, 'A');
69
+ NoLog(TwoFieldSecrets.prototype, 'C');
70
+
71
+ const fields = getNoLogFields(TwoFieldSecrets);
72
+ expect(fields.has('A')).toBe(true);
73
+ expect(fields.has('B')).toBe(false);
74
+ expect(fields.has('C')).toBe(true);
75
+ });
76
+ });
@@ -0,0 +1,188 @@
1
+ import 'reflect-metadata';
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
3
+
4
+ // Short-circuits config.ts's loadConfig() so this file loads in any environment, not just one
5
+ // with DB env vars set. bootAudit.ts imports `configInfo` at module-init; without this mock,
6
+ // `loadConfig()` runs and throws "Configuration validation failed" on a clean machine or in
7
+ // sandboxed CI. The audit tests below call `auditResolverList` directly and don't read
8
+ // `logVariables`, but the import chain still pulls in `configInfo`. Mirrors the same shim in
9
+ // subscriptionRedaction.test.ts.
10
+ vi.mock('../config', () => ({
11
+ configInfo: {
12
+ loggingSettings: { graphql: { logVariables: true } },
13
+ },
14
+ }));
15
+ vi.mock('../config.js', () => ({
16
+ configInfo: {
17
+ loggingSettings: { graphql: { logVariables: true } },
18
+ },
19
+ }));
20
+
21
+ import { auditResolverList } from '../logging/bootAudit.js';
22
+ import type { AuditArgParam, AuditResolver } from '../logging/bootAudit.js';
23
+ import { NoLog } from '../logging/NoLog.js';
24
+
25
+ // --------------------------------------------------------------------------
26
+ // Synthetic fixture types & helpers
27
+ // --------------------------------------------------------------------------
28
+
29
+ class CreateMJCredentialInput {}
30
+ class CustomSecretInput {}
31
+
32
+ function makeArgParam(opts: {
33
+ target: Function;
34
+ methodName: string;
35
+ index: number;
36
+ name: string;
37
+ type: Function;
38
+ }): AuditArgParam {
39
+ return {
40
+ target: opts.target,
41
+ methodName: opts.methodName,
42
+ index: opts.index,
43
+ kind: 'arg',
44
+ name: opts.name,
45
+ getType: () => opts.type,
46
+ };
47
+ }
48
+
49
+ function makeResolver(opts: {
50
+ target: Function;
51
+ methodName: string;
52
+ params: AuditArgParam[];
53
+ }): AuditResolver {
54
+ return {
55
+ target: opts.target,
56
+ methodName: opts.methodName,
57
+ params: opts.params,
58
+ };
59
+ }
60
+
61
+ // --------------------------------------------------------------------------
62
+ // Tests
63
+ // --------------------------------------------------------------------------
64
+
65
+ describe('auditResolverList', () => {
66
+ let warnSpy: ReturnType<typeof vi.spyOn>;
67
+
68
+ beforeEach(() => {
69
+ warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
70
+ });
71
+
72
+ afterEach(() => {
73
+ warnSpy.mockRestore();
74
+ });
75
+
76
+ it('does NOT warn for an @Arg whose type matches Create<X>Input', () => {
77
+ class SafeCrudResolver {
78
+ doCreate(_input: CreateMJCredentialInput): void {
79
+ // body
80
+ }
81
+ }
82
+ const resolver = makeResolver({
83
+ target: SafeCrudResolver,
84
+ methodName: 'doCreate',
85
+ params: [
86
+ makeArgParam({
87
+ target: SafeCrudResolver,
88
+ methodName: 'doCreate',
89
+ index: 0,
90
+ name: 'input',
91
+ type: CreateMJCredentialInput,
92
+ }),
93
+ ],
94
+ });
95
+
96
+ auditResolverList([resolver]);
97
+ expect(warnSpy).not.toHaveBeenCalled();
98
+ });
99
+
100
+ it('WARNS for an @Arg of a custom type without @NoLog', () => {
101
+ class CustomNoMarkResolver {
102
+ doCustom(_input: CustomSecretInput): void {
103
+ // body
104
+ }
105
+ }
106
+ const resolver = makeResolver({
107
+ target: CustomNoMarkResolver,
108
+ methodName: 'doCustom',
109
+ params: [
110
+ makeArgParam({
111
+ target: CustomNoMarkResolver,
112
+ methodName: 'doCustom',
113
+ index: 0,
114
+ name: 'input',
115
+ type: CustomSecretInput,
116
+ }),
117
+ ],
118
+ });
119
+
120
+ auditResolverList([resolver]);
121
+ expect(warnSpy).toHaveBeenCalledTimes(1);
122
+ const message = warnSpy.mock.calls[0][0];
123
+ expect(typeof message).toBe('string');
124
+ expect(message).toContain('CustomNoMarkResolver.doCustom');
125
+ expect(message).toContain("'input'");
126
+ expect(message).toContain('CustomSecretInput');
127
+ });
128
+
129
+ it('does NOT warn for an @Arg of a custom type marked @NoLog at parameter level', () => {
130
+ class CustomMarkedResolver {
131
+ doCustom(_input: CustomSecretInput): void {
132
+ // body
133
+ }
134
+ }
135
+ NoLog(CustomMarkedResolver.prototype, 'doCustom', 0);
136
+
137
+ const resolver = makeResolver({
138
+ target: CustomMarkedResolver,
139
+ methodName: 'doCustom',
140
+ params: [
141
+ makeArgParam({
142
+ target: CustomMarkedResolver,
143
+ methodName: 'doCustom',
144
+ index: 0,
145
+ name: 'input',
146
+ type: CustomSecretInput,
147
+ }),
148
+ ],
149
+ });
150
+
151
+ auditResolverList([resolver]);
152
+ expect(warnSpy).not.toHaveBeenCalled();
153
+ });
154
+
155
+ it('mixed resolver: warns for the un-decorated custom arg but not the metadata-bound one', () => {
156
+ class MixedResolver {
157
+ doMixed(_safe: CreateMJCredentialInput, _custom: CustomSecretInput): void {
158
+ // body
159
+ }
160
+ }
161
+ const resolver = makeResolver({
162
+ target: MixedResolver,
163
+ methodName: 'doMixed',
164
+ params: [
165
+ makeArgParam({
166
+ target: MixedResolver,
167
+ methodName: 'doMixed',
168
+ index: 0,
169
+ name: 'safe',
170
+ type: CreateMJCredentialInput,
171
+ }),
172
+ makeArgParam({
173
+ target: MixedResolver,
174
+ methodName: 'doMixed',
175
+ index: 1,
176
+ name: 'custom',
177
+ type: CustomSecretInput,
178
+ }),
179
+ ],
180
+ });
181
+
182
+ auditResolverList([resolver]);
183
+ expect(warnSpy).toHaveBeenCalledTimes(1);
184
+ const message = warnSpy.mock.calls[0][0];
185
+ expect(message).toContain("'custom'");
186
+ expect(message).not.toContain("'safe'");
187
+ });
188
+ });
@@ -0,0 +1,31 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { buildBoundaryLogPayload } from '../logging/boundaryLogPayload.js';
3
+
4
+ /**
5
+ * Guards the load-bearing #2638 fix: the always-on GraphQL boundary log line emits the
6
+ * operation name ONLY and never a `variables` key, in any configuration. A future refactor
7
+ * that re-adds variables to this line (the original leak) must fail here.
8
+ *
9
+ * See docs/adr/0001-graphql-variables-logging-tiered-by-verbose.md.
10
+ */
11
+ describe('buildBoundaryLogPayload', () => {
12
+ it('returns operation name only', () => {
13
+ expect(buildBoundaryLogPayload('CreateMJCredential')).toEqual({ operationName: 'CreateMJCredential' });
14
+ });
15
+
16
+ it('never includes a `variables` key', () => {
17
+ const payload = buildBoundaryLogPayload('RunViewsWithCacheCheck');
18
+ expect('variables' in payload).toBe(false);
19
+ });
20
+
21
+ it('serialized form contains no value content — only the operation name', () => {
22
+ // Even if someone passes a secret-shaped operation name, nothing but the name is emitted.
23
+ const serialized = JSON.stringify(buildBoundaryLogPayload('SomeOp'));
24
+ expect(serialized).toBe('{"operationName":"SomeOp"}');
25
+ });
26
+
27
+ it('handles undefined operation name (non-named operations)', () => {
28
+ expect(buildBoundaryLogPayload(undefined)).toEqual({ operationName: undefined });
29
+ expect('variables' in buildBoundaryLogPayload(undefined)).toBe(false);
30
+ });
31
+ });