@skillsmith/mcp-server 0.4.7 → 0.4.9

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 (213) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +21 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/__tests__/tool-dispatch.test.d.ts +8 -0
  5. package/dist/src/__tests__/tool-dispatch.test.d.ts.map +1 -0
  6. package/dist/src/__tests__/tool-dispatch.test.js +144 -0
  7. package/dist/src/__tests__/tool-dispatch.test.js.map +1 -0
  8. package/dist/src/index.js +31 -2
  9. package/dist/src/index.js.map +1 -1
  10. package/dist/src/middleware/license.d.ts +23 -0
  11. package/dist/src/middleware/license.d.ts.map +1 -1
  12. package/dist/src/middleware/license.js +28 -0
  13. package/dist/src/middleware/license.js.map +1 -1
  14. package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -1
  15. package/dist/src/middleware/toolFeatureMapping.js +4 -1
  16. package/dist/src/middleware/toolFeatureMapping.js.map +1 -1
  17. package/dist/src/supabase-client.d.ts +24 -0
  18. package/dist/src/supabase-client.d.ts.map +1 -0
  19. package/dist/src/supabase-client.js +63 -0
  20. package/dist/src/supabase-client.js.map +1 -0
  21. package/dist/src/tool-dispatch.d.ts.map +1 -1
  22. package/dist/src/tool-dispatch.js +71 -62
  23. package/dist/src/tool-dispatch.js.map +1 -1
  24. package/dist/src/tools/analytics.d.ts +155 -0
  25. package/dist/src/tools/analytics.d.ts.map +1 -0
  26. package/dist/src/tools/analytics.js +321 -0
  27. package/dist/src/tools/analytics.js.map +1 -0
  28. package/dist/src/tools/analytics.service.d.ts +46 -0
  29. package/dist/src/tools/analytics.service.d.ts.map +1 -0
  30. package/dist/src/tools/analytics.service.js +69 -0
  31. package/dist/src/tools/analytics.service.js.map +1 -0
  32. package/dist/src/tools/analytics.service.test.d.ts +6 -0
  33. package/dist/src/tools/analytics.service.test.d.ts.map +1 -0
  34. package/dist/src/tools/analytics.service.test.js +151 -0
  35. package/dist/src/tools/analytics.service.test.js.map +1 -0
  36. package/dist/src/tools/analytics.stub.d.ts +27 -0
  37. package/dist/src/tools/analytics.stub.d.ts.map +1 -0
  38. package/dist/src/tools/analytics.stub.js +200 -0
  39. package/dist/src/tools/analytics.stub.js.map +1 -0
  40. package/dist/src/tools/analytics.test.d.ts +6 -0
  41. package/dist/src/tools/analytics.test.d.ts.map +1 -0
  42. package/dist/src/tools/analytics.test.js +146 -0
  43. package/dist/src/tools/analytics.test.js.map +1 -0
  44. package/dist/src/tools/analyze.d.ts.map +1 -1
  45. package/dist/src/tools/analyze.js +7 -1
  46. package/dist/src/tools/analyze.js.map +1 -1
  47. package/dist/src/tools/audit-tools.d.ts +172 -0
  48. package/dist/src/tools/audit-tools.d.ts.map +1 -0
  49. package/dist/src/tools/audit-tools.js +187 -0
  50. package/dist/src/tools/audit-tools.js.map +1 -0
  51. package/dist/src/tools/audit-tools.test.d.ts +10 -0
  52. package/dist/src/tools/audit-tools.test.d.ts.map +1 -0
  53. package/dist/src/tools/audit-tools.test.js +147 -0
  54. package/dist/src/tools/audit-tools.test.js.map +1 -0
  55. package/dist/src/tools/compliance-tools.d.ts +103 -0
  56. package/dist/src/tools/compliance-tools.d.ts.map +1 -0
  57. package/dist/src/tools/compliance-tools.js +257 -0
  58. package/dist/src/tools/compliance-tools.js.map +1 -0
  59. package/dist/src/tools/compliance-tools.service.d.ts +19 -0
  60. package/dist/src/tools/compliance-tools.service.d.ts.map +1 -0
  61. package/dist/src/tools/compliance-tools.service.js +107 -0
  62. package/dist/src/tools/compliance-tools.service.js.map +1 -0
  63. package/dist/src/tools/compliance-tools.service.test.d.ts +6 -0
  64. package/dist/src/tools/compliance-tools.service.test.d.ts.map +1 -0
  65. package/dist/src/tools/compliance-tools.service.test.js +140 -0
  66. package/dist/src/tools/compliance-tools.service.test.js.map +1 -0
  67. package/dist/src/tools/compliance-tools.test.d.ts +6 -0
  68. package/dist/src/tools/compliance-tools.test.d.ts.map +1 -0
  69. package/dist/src/tools/compliance-tools.test.js +136 -0
  70. package/dist/src/tools/compliance-tools.test.js.map +1 -0
  71. package/dist/src/tools/get-skill.d.ts.map +1 -1
  72. package/dist/src/tools/get-skill.js +24 -1
  73. package/dist/src/tools/get-skill.js.map +1 -1
  74. package/dist/src/tools/index-local.d.ts.map +1 -1
  75. package/dist/src/tools/index-local.js +4 -0
  76. package/dist/src/tools/index-local.js.map +1 -1
  77. package/dist/src/tools/install.d.ts.map +1 -1
  78. package/dist/src/tools/install.js +11 -1
  79. package/dist/src/tools/install.js.map +1 -1
  80. package/dist/src/tools/install.tool.d.ts +4 -0
  81. package/dist/src/tools/install.tool.d.ts.map +1 -1
  82. package/dist/src/tools/install.tool.js +4 -0
  83. package/dist/src/tools/install.tool.js.map +1 -1
  84. package/dist/src/tools/install.types.d.ts +4 -0
  85. package/dist/src/tools/install.types.d.ts.map +1 -1
  86. package/dist/src/tools/install.types.js +5 -0
  87. package/dist/src/tools/install.types.js.map +1 -1
  88. package/dist/src/tools/integration-tools.d.ts +210 -0
  89. package/dist/src/tools/integration-tools.d.ts.map +1 -0
  90. package/dist/src/tools/integration-tools.js +264 -0
  91. package/dist/src/tools/integration-tools.js.map +1 -0
  92. package/dist/src/tools/integration-tools.service.d.ts +54 -0
  93. package/dist/src/tools/integration-tools.service.d.ts.map +1 -0
  94. package/dist/src/tools/integration-tools.service.js +299 -0
  95. package/dist/src/tools/integration-tools.service.js.map +1 -0
  96. package/dist/src/tools/integration-tools.service.test.d.ts +8 -0
  97. package/dist/src/tools/integration-tools.service.test.d.ts.map +1 -0
  98. package/dist/src/tools/integration-tools.service.test.js +401 -0
  99. package/dist/src/tools/integration-tools.service.test.js.map +1 -0
  100. package/dist/src/tools/integration-tools.stub.d.ts +13 -0
  101. package/dist/src/tools/integration-tools.stub.d.ts.map +1 -0
  102. package/dist/src/tools/integration-tools.stub.js +133 -0
  103. package/dist/src/tools/integration-tools.stub.js.map +1 -0
  104. package/dist/src/tools/integration-tools.test.d.ts +6 -0
  105. package/dist/src/tools/integration-tools.test.d.ts.map +1 -0
  106. package/dist/src/tools/integration-tools.test.js +259 -0
  107. package/dist/src/tools/integration-tools.test.js.map +1 -0
  108. package/dist/src/tools/publish-private.d.ts +60 -0
  109. package/dist/src/tools/publish-private.d.ts.map +1 -0
  110. package/dist/src/tools/publish-private.js +85 -0
  111. package/dist/src/tools/publish-private.js.map +1 -0
  112. package/dist/src/tools/publish-private.test.d.ts +6 -0
  113. package/dist/src/tools/publish-private.test.d.ts.map +1 -0
  114. package/dist/src/tools/publish-private.test.js +118 -0
  115. package/dist/src/tools/publish-private.test.js.map +1 -0
  116. package/dist/src/tools/publish.types.d.ts +2 -2
  117. package/dist/src/tools/rbac-tools.d.ts +180 -0
  118. package/dist/src/tools/rbac-tools.d.ts.map +1 -0
  119. package/dist/src/tools/rbac-tools.js +300 -0
  120. package/dist/src/tools/rbac-tools.js.map +1 -0
  121. package/dist/src/tools/rbac-tools.test.d.ts +6 -0
  122. package/dist/src/tools/rbac-tools.test.d.ts.map +1 -0
  123. package/dist/src/tools/rbac-tools.test.js +299 -0
  124. package/dist/src/tools/rbac-tools.test.js.map +1 -0
  125. package/dist/src/tools/rbac-tools.types.d.ts +70 -0
  126. package/dist/src/tools/rbac-tools.types.d.ts.map +1 -0
  127. package/dist/src/tools/rbac-tools.types.js +119 -0
  128. package/dist/src/tools/rbac-tools.types.js.map +1 -0
  129. package/dist/src/tools/recommend.helpers.d.ts.map +1 -1
  130. package/dist/src/tools/recommend.helpers.js +2 -1
  131. package/dist/src/tools/recommend.helpers.js.map +1 -1
  132. package/dist/src/tools/recommend.js +3 -3
  133. package/dist/src/tools/recommend.js.map +1 -1
  134. package/dist/src/tools/registry-tools.d.ts +133 -0
  135. package/dist/src/tools/registry-tools.d.ts.map +1 -0
  136. package/dist/src/tools/registry-tools.js +246 -0
  137. package/dist/src/tools/registry-tools.js.map +1 -0
  138. package/dist/src/tools/registry-tools.test.d.ts +6 -0
  139. package/dist/src/tools/registry-tools.test.d.ts.map +1 -0
  140. package/dist/src/tools/registry-tools.test.js +167 -0
  141. package/dist/src/tools/registry-tools.test.js.map +1 -0
  142. package/dist/src/tools/search.formatter.d.ts.map +1 -1
  143. package/dist/src/tools/search.formatter.js +11 -1
  144. package/dist/src/tools/search.formatter.js.map +1 -1
  145. package/dist/src/tools/skill-audit.d.ts +3 -3
  146. package/dist/src/tools/skill-audit.d.ts.map +1 -1
  147. package/dist/src/tools/skill-audit.js +5 -5
  148. package/dist/src/tools/skill-audit.js.map +1 -1
  149. package/dist/src/tools/skill-audit.test.js +5 -5
  150. package/dist/src/tools/skill-audit.test.js.map +1 -1
  151. package/dist/src/tools/skill-pack-audit.d.ts +22 -1
  152. package/dist/src/tools/skill-pack-audit.d.ts.map +1 -1
  153. package/dist/src/tools/skill-pack-audit.helpers.d.ts +53 -0
  154. package/dist/src/tools/skill-pack-audit.helpers.d.ts.map +1 -0
  155. package/dist/src/tools/skill-pack-audit.helpers.js +181 -0
  156. package/dist/src/tools/skill-pack-audit.helpers.js.map +1 -0
  157. package/dist/src/tools/skill-pack-audit.js +122 -5
  158. package/dist/src/tools/skill-pack-audit.js.map +1 -1
  159. package/dist/src/tools/skill-pack-audit.types.d.ts +70 -0
  160. package/dist/src/tools/skill-pack-audit.types.d.ts.map +1 -0
  161. package/dist/src/tools/skill-pack-audit.types.js +8 -0
  162. package/dist/src/tools/skill-pack-audit.types.js.map +1 -0
  163. package/dist/src/tools/skill-rescan.d.ts.map +1 -1
  164. package/dist/src/tools/skill-rescan.js +2 -3
  165. package/dist/src/tools/skill-rescan.js.map +1 -1
  166. package/dist/src/tools/skill-rescan.test.js +2 -2
  167. package/dist/src/tools/skill-rescan.test.js.map +1 -1
  168. package/dist/src/tools/sso-tools.d.ts +136 -0
  169. package/dist/src/tools/sso-tools.d.ts.map +1 -0
  170. package/dist/src/tools/sso-tools.js +214 -0
  171. package/dist/src/tools/sso-tools.js.map +1 -0
  172. package/dist/src/tools/sso-tools.test.d.ts +6 -0
  173. package/dist/src/tools/sso-tools.test.d.ts.map +1 -0
  174. package/dist/src/tools/sso-tools.test.js +167 -0
  175. package/dist/src/tools/sso-tools.test.js.map +1 -0
  176. package/dist/src/tools/suggest.d.ts.map +1 -1
  177. package/dist/src/tools/suggest.js +7 -1
  178. package/dist/src/tools/suggest.js.map +1 -1
  179. package/dist/src/tools/team-workspace.d.ts +179 -0
  180. package/dist/src/tools/team-workspace.d.ts.map +1 -0
  181. package/dist/src/tools/team-workspace.js +243 -0
  182. package/dist/src/tools/team-workspace.js.map +1 -0
  183. package/dist/src/tools/team-workspace.stub.d.ts +13 -0
  184. package/dist/src/tools/team-workspace.stub.d.ts.map +1 -0
  185. package/dist/src/tools/team-workspace.stub.js +76 -0
  186. package/dist/src/tools/team-workspace.stub.js.map +1 -0
  187. package/dist/src/tools/team-workspace.test.d.ts +7 -0
  188. package/dist/src/tools/team-workspace.test.d.ts.map +1 -0
  189. package/dist/src/tools/team-workspace.test.js +273 -0
  190. package/dist/src/tools/team-workspace.test.js.map +1 -0
  191. package/dist/src/tools/validate.helpers.d.ts.map +1 -1
  192. package/dist/src/tools/validate.helpers.js +15 -0
  193. package/dist/src/tools/validate.helpers.js.map +1 -1
  194. package/dist/src/utils/team-resolver.d.ts +20 -0
  195. package/dist/src/utils/team-resolver.d.ts.map +1 -0
  196. package/dist/src/utils/team-resolver.js +52 -0
  197. package/dist/src/utils/team-resolver.js.map +1 -0
  198. package/dist/src/utils/url-validator.d.ts +24 -0
  199. package/dist/src/utils/url-validator.d.ts.map +1 -0
  200. package/dist/src/utils/url-validator.js +59 -0
  201. package/dist/src/utils/url-validator.js.map +1 -0
  202. package/dist/tests/integration/recommend.integration.test.js +1 -1
  203. package/dist/tests/integration/recommend.integration.test.js.map +1 -1
  204. package/dist/tests/recommend.test.js +1 -1
  205. package/dist/tests/recommend.test.js.map +1 -1
  206. package/dist/tests/unit/skill-pack-audit.test.js +225 -0
  207. package/dist/tests/unit/skill-pack-audit.test.js.map +1 -1
  208. package/package.json +3 -3
  209. package/server.json +2 -2
  210. package/dist/vitest.config.d.ts +0 -6
  211. package/dist/vitest.config.d.ts.map +0 -1
  212. package/dist/vitest.config.js +0 -23
  213. package/dist/vitest.config.js.map +0 -1
@@ -0,0 +1,299 @@
1
+ /**
2
+ * @fileoverview Real IntegrationService backed by Supabase
3
+ * @module @skillsmith/mcp-server/tools/integration-tools.service
4
+ * @see SMI-3915: Wave 1 — Webhooks + API Keys (Real Implementation)
5
+ *
6
+ * Uses HMAC-SHA256 for webhook signing. API keys are hashed with SHA-256
7
+ * before storage — raw key is returned once on creation and never persisted.
8
+ *
9
+ * SSRF protection via validateExternalUrl() on all outbound URLs.
10
+ */
11
+ import { createHmac, randomBytes } from 'node:crypto';
12
+ import { validateExternalUrl } from '../utils/url-validator.js';
13
+ // ============================================================================
14
+ // Constants
15
+ // ============================================================================
16
+ const KEY_HMAC_SECRET = 'skillsmith-api-key';
17
+ const TEST_RATE_LIMIT_MS = 60_000;
18
+ const TEST_DELIVERY_TIMEOUT_MS = 10_000;
19
+ const API_KEY_PREFIX_LENGTH = 15; // "sk_int_" (7) + 8 chars
20
+ // ============================================================================
21
+ // Crypto helpers
22
+ // ============================================================================
23
+ function generateSigningSecret() {
24
+ return 'whsec_' + randomBytes(32).toString('hex');
25
+ }
26
+ function generateApiKey() {
27
+ return 'sk_int_' + randomBytes(32).toString('base64url');
28
+ }
29
+ /** Hash an API key for storage (one-way) */
30
+ export function hashApiKey(key) {
31
+ return createHmac('sha256', KEY_HMAC_SECRET).update(key).digest('hex');
32
+ }
33
+ /** Compute HMAC-SHA256 signature for webhook delivery */
34
+ export function computeHmacSignature(secret, payload) {
35
+ return createHmac('sha256', secret).update(payload).digest('hex');
36
+ }
37
+ // ============================================================================
38
+ // Expiration helper
39
+ // ============================================================================
40
+ function computeExpiresAt(expiresIn) {
41
+ if (!expiresIn || expiresIn === 'never')
42
+ return null;
43
+ const days = parseInt(expiresIn, 10);
44
+ if (isNaN(days))
45
+ return null;
46
+ return new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString();
47
+ }
48
+ // ============================================================================
49
+ // Row mappers
50
+ // ============================================================================
51
+ function rowToWebhookMasked(row) {
52
+ const secret = String(row.signing_secret ?? '');
53
+ return {
54
+ id: String(row.id),
55
+ url: String(row.url),
56
+ events: row.events,
57
+ description: row.description ? String(row.description) : null,
58
+ signingSecretLast4: secret.slice(-4),
59
+ status: row.status,
60
+ createdAt: String(row.created_at),
61
+ lastDeliveryAt: row.last_delivery_at ? String(row.last_delivery_at) : null,
62
+ };
63
+ }
64
+ function rowToApiKeyMasked(row) {
65
+ const prefix = String(row.key_prefix ?? '');
66
+ return {
67
+ id: String(row.id),
68
+ name: String(row.name),
69
+ keyLast4: prefix.slice(-4),
70
+ keyPrefix: prefix,
71
+ permissions: row.permissions,
72
+ expiresAt: row.expires_at ? String(row.expires_at) : null,
73
+ createdAt: String(row.created_at),
74
+ status: row.revoked_at ? 'revoked' : 'active',
75
+ };
76
+ }
77
+ // ============================================================================
78
+ // Factory
79
+ // ============================================================================
80
+ /**
81
+ * Create a real IntegrationService backed by Supabase.
82
+ *
83
+ * @param supabase - Supabase client (anon or service-role)
84
+ * @param teamId - Team ID for row-level scoping
85
+ */
86
+ export function createRealIntegrationService(supabase, teamId) {
87
+ // Rate limiting for test delivery (per webhook, in-memory)
88
+ const testDeliveryTimestamps = new Map();
89
+ return {
90
+ // ========================================================================
91
+ // Webhooks
92
+ // ========================================================================
93
+ async createWebhook(url, events, description) {
94
+ const urlCheck = validateExternalUrl(url);
95
+ if (!urlCheck.valid) {
96
+ throw new Error(`Invalid webhook URL: ${urlCheck.error}`);
97
+ }
98
+ const signingSecret = generateSigningSecret();
99
+ const { data, error } = await supabase
100
+ .from('webhook_endpoints')
101
+ .insert({
102
+ team_id: teamId,
103
+ url,
104
+ events,
105
+ description: description ?? null,
106
+ signing_secret: signingSecret,
107
+ status: 'active',
108
+ })
109
+ .select()
110
+ .single();
111
+ if (error || !data) {
112
+ throw new Error(`Failed to create webhook: ${error?.message ?? 'no data returned'}`);
113
+ }
114
+ return {
115
+ id: String(data.id),
116
+ url: String(data.url),
117
+ events: data.events,
118
+ description: data.description ? String(data.description) : null,
119
+ signingSecret,
120
+ status: data.status,
121
+ createdAt: String(data.created_at),
122
+ lastDeliveryAt: data.last_delivery_at ? String(data.last_delivery_at) : null,
123
+ };
124
+ },
125
+ async listWebhooks() {
126
+ const result = (await supabase
127
+ .from('webhook_endpoints')
128
+ .select('*')
129
+ .eq('team_id', teamId)
130
+ .order('created_at', { ascending: false }));
131
+ if (result.error) {
132
+ throw new Error(`Failed to list webhooks: ${result.error.message}`);
133
+ }
134
+ const rows = result.data ?? [];
135
+ return rows.map(rowToWebhookMasked);
136
+ },
137
+ async getWebhook(webhookId) {
138
+ const { data, error } = await supabase
139
+ .from('webhook_endpoints')
140
+ .select('*')
141
+ .eq('id', webhookId)
142
+ .eq('team_id', teamId)
143
+ .single();
144
+ if (error || !data)
145
+ return null;
146
+ return rowToWebhookMasked(data);
147
+ },
148
+ async deleteWebhook(webhookId) {
149
+ const result = (await supabase
150
+ .from('webhook_endpoints')
151
+ .delete()
152
+ .eq('id', webhookId)
153
+ .eq('team_id', teamId));
154
+ return !result.error;
155
+ },
156
+ async testWebhook(webhookId) {
157
+ // Rate limit: max 1 test delivery per webhook per minute
158
+ const lastTest = testDeliveryTimestamps.get(webhookId);
159
+ if (lastTest && Date.now() - lastTest < TEST_RATE_LIMIT_MS) {
160
+ return {
161
+ success: false,
162
+ statusCode: 0,
163
+ message: 'Rate limited: max 1 test delivery per webhook per minute.',
164
+ };
165
+ }
166
+ const { data: wh, error } = await supabase
167
+ .from('webhook_endpoints')
168
+ .select('*')
169
+ .eq('id', webhookId)
170
+ .eq('team_id', teamId)
171
+ .single();
172
+ if (error || !wh) {
173
+ return { success: false, statusCode: 0, message: 'Webhook not found.' };
174
+ }
175
+ const whData = wh;
176
+ // SSRF validation on stored URL (may have been updated externally)
177
+ const urlCheck = validateExternalUrl(String(whData.url));
178
+ if (!urlCheck.valid) {
179
+ return {
180
+ success: false,
181
+ statusCode: 0,
182
+ message: `Webhook URL blocked: ${urlCheck.error}`,
183
+ };
184
+ }
185
+ const timestamp = new Date().toISOString();
186
+ const payload = JSON.stringify({ event: 'test', timestamp, webhookId });
187
+ const signature = computeHmacSignature(String(whData.signing_secret), payload);
188
+ try {
189
+ const response = await fetch(String(whData.url), {
190
+ method: 'POST',
191
+ headers: {
192
+ 'Content-Type': 'application/json',
193
+ 'X-Skillsmith-Signature': `sha256=${signature}`,
194
+ 'X-Skillsmith-Timestamp': timestamp,
195
+ },
196
+ body: payload,
197
+ signal: AbortSignal.timeout(TEST_DELIVERY_TIMEOUT_MS),
198
+ });
199
+ testDeliveryTimestamps.set(webhookId, Date.now());
200
+ // Update last_delivery_at (fire-and-forget)
201
+ void supabase
202
+ .from('webhook_endpoints')
203
+ .update({ last_delivery_at: new Date().toISOString() })
204
+ .eq('id', webhookId);
205
+ return {
206
+ success: response.ok,
207
+ statusCode: response.status,
208
+ message: `Test delivery to ${whData.url}: HTTP ${response.status}`,
209
+ };
210
+ }
211
+ catch (err) {
212
+ return {
213
+ success: false,
214
+ statusCode: 0,
215
+ message: `Test delivery failed: ${err instanceof Error ? err.message : 'unknown error'}`,
216
+ };
217
+ }
218
+ },
219
+ async rotateSecret(webhookId) {
220
+ const newSecret = generateSigningSecret();
221
+ const result = (await supabase
222
+ .from('webhook_endpoints')
223
+ .update({ signing_secret: newSecret })
224
+ .eq('id', webhookId)
225
+ .eq('team_id', teamId));
226
+ if (result.error) {
227
+ throw new Error(`Webhook "${webhookId}" not found.`);
228
+ }
229
+ return { webhookId, newSigningSecret: newSecret };
230
+ },
231
+ // ========================================================================
232
+ // API Keys
233
+ // ========================================================================
234
+ async createApiKey(name, permissions, expiresIn) {
235
+ const keyValue = generateApiKey();
236
+ const keyPrefix = keyValue.slice(0, API_KEY_PREFIX_LENGTH);
237
+ const keyHash = hashApiKey(keyValue);
238
+ const expiresAt = computeExpiresAt(expiresIn);
239
+ const { data, error } = await supabase
240
+ .from('api_keys')
241
+ .insert({
242
+ team_id: teamId,
243
+ name,
244
+ key_hash: keyHash,
245
+ key_prefix: keyPrefix,
246
+ permissions: permissions ?? ['read'],
247
+ expires_at: expiresAt,
248
+ })
249
+ .select()
250
+ .single();
251
+ if (error || !data) {
252
+ throw new Error(`Failed to create API key: ${error?.message ?? 'no data returned'}`);
253
+ }
254
+ return {
255
+ id: String(data.id),
256
+ name: String(data.name),
257
+ keyValue,
258
+ keyPrefix,
259
+ permissions: data.permissions,
260
+ expiresAt: data.expires_at ? String(data.expires_at) : null,
261
+ createdAt: String(data.created_at),
262
+ };
263
+ },
264
+ async listApiKeys() {
265
+ const result = (await supabase
266
+ .from('api_keys')
267
+ .select('*')
268
+ .eq('team_id', teamId)
269
+ .is('revoked_at', null)
270
+ .order('created_at', { ascending: false }));
271
+ if (result.error) {
272
+ throw new Error(`Failed to list API keys: ${result.error.message}`);
273
+ }
274
+ const rows = result.data ?? [];
275
+ return rows.map(rowToApiKeyMasked);
276
+ },
277
+ async getApiKey(keyId) {
278
+ const { data, error } = await supabase
279
+ .from('api_keys')
280
+ .select('*')
281
+ .eq('id', keyId)
282
+ .eq('team_id', teamId)
283
+ .single();
284
+ if (error || !data)
285
+ return null;
286
+ return rowToApiKeyMasked(data);
287
+ },
288
+ async revokeApiKey(keyId) {
289
+ const result = (await supabase
290
+ .from('api_keys')
291
+ .update({ revoked_at: new Date().toISOString() })
292
+ .eq('id', keyId)
293
+ .eq('team_id', teamId)
294
+ .is('revoked_at', null));
295
+ return !result.error;
296
+ },
297
+ };
298
+ }
299
+ //# sourceMappingURL=integration-tools.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-tools.service.js","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Tests for real IntegrationService (Supabase-backed)
3
+ * @see SMI-3915: Wave 1 — Webhooks + API Keys (Real Implementation)
4
+ *
5
+ * All tests mock the Supabase client — no real database needed.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=integration-tools.service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-tools.service.test.d.ts","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}