@friggframework/core 2.0.0--canary.522.cbd3d5a.0 → 2.0.0--canary.517.35ee143.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 (225) hide show
  1. package/CHANGELOG.md +67 -66
  2. package/CLAUDE.md +124 -148
  3. package/README.md +130 -165
  4. package/admin-scripts/index.js +16 -30
  5. package/admin-scripts/repositories/{admin-api-key-repository-documentdb.js → admin-process-repository-documentdb.js} +5 -5
  6. package/admin-scripts/repositories/{admin-api-key-repository-factory.js → admin-process-repository-factory.js} +15 -19
  7. package/admin-scripts/repositories/admin-process-repository-interface.js +150 -0
  8. package/admin-scripts/repositories/admin-process-repository-mongo.js +213 -0
  9. package/admin-scripts/repositories/admin-process-repository-postgres.js +251 -0
  10. package/admin-scripts/repositories/script-schedule-repository-factory.js +2 -6
  11. package/admin-scripts/repositories/script-schedule-repository-interface.js +14 -36
  12. package/admin-scripts/repositories/script-schedule-repository-mongo.js +13 -25
  13. package/admin-scripts/repositories/script-schedule-repository-postgres.js +13 -25
  14. package/application/commands/admin-script-commands.js +102 -266
  15. package/application/commands/integration-commands.js +6 -12
  16. package/application/index.js +3 -1
  17. package/assertions/get.js +4 -1
  18. package/associations/association.js +57 -59
  19. package/associations/model.js +41 -41
  20. package/core/CLAUDE.md +156 -222
  21. package/core/Worker.js +1 -5
  22. package/credential/repositories/credential-repository-documentdb.js +1 -71
  23. package/credential/repositories/credential-repository-interface.js +2 -8
  24. package/credential/repositories/credential-repository-mongo.js +4 -45
  25. package/credential/repositories/credential-repository-postgres.js +3 -44
  26. package/credential/repositories/credential-repository.js +4 -6
  27. package/credential/use-cases/get-credential-for-user.js +3 -21
  28. package/credential/use-cases/update-authentication-status.js +2 -5
  29. package/database/MONGODB_TRANSACTION_FIX.md +52 -72
  30. package/database/adapters/lambda-invoker.js +7 -8
  31. package/database/config.js +13 -15
  32. package/database/documentdb-encryption-service.js +13 -29
  33. package/database/documentdb-utils.js +12 -21
  34. package/database/encryption/README.md +36 -53
  35. package/database/encryption/encryption-schema-registry.js +9 -21
  36. package/database/encryption/field-encryption-service.js +4 -15
  37. package/database/encryption/logger.js +2 -3
  38. package/database/encryption/prisma-encryption-extension.js +8 -5
  39. package/database/index.js +2 -4
  40. package/database/models/IndividualUser.js +15 -15
  41. package/database/models/OrganizationUser.js +4 -6
  42. package/database/models/UserModel.js +2 -2
  43. package/database/models/WebsocketConnection.js +1 -4
  44. package/database/mongoose.js +2 -2
  45. package/database/prisma.js +14 -22
  46. package/database/repositories/health-check-repository-documentdb.js +7 -22
  47. package/database/repositories/health-check-repository-factory.js +3 -9
  48. package/database/repositories/health-check-repository-interface.js +5 -15
  49. package/database/repositories/health-check-repository-mongodb.js +6 -9
  50. package/database/repositories/health-check-repository-postgres.js +1 -1
  51. package/database/repositories/migration-status-repository-s3.js +5 -10
  52. package/database/use-cases/check-database-health-use-case.js +2 -3
  53. package/database/use-cases/check-database-state-use-case.js +7 -9
  54. package/database/use-cases/get-database-state-via-worker-use-case.js +12 -15
  55. package/database/use-cases/get-migration-status-use-case.js +2 -4
  56. package/database/use-cases/run-database-migration-use-case.js +9 -41
  57. package/database/use-cases/test-encryption-use-case.js +5 -4
  58. package/database/use-cases/trigger-database-migration-use-case.js +8 -9
  59. package/database/utils/mongodb-collection-utils.js +3 -11
  60. package/database/utils/mongodb-schema-init.js +4 -10
  61. package/database/utils/prisma-runner.js +74 -144
  62. package/database/utils/prisma-schema-parser.js +2 -2
  63. package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +80 -135
  64. package/encrypt/Cryptor.js +2 -8
  65. package/errors/fetch-error.js +1 -1
  66. package/generated/prisma-mongodb/edge.js +16 -59
  67. package/generated/prisma-mongodb/index-browser.js +12 -62
  68. package/generated/prisma-mongodb/index.d.ts +4850 -8136
  69. package/generated/prisma-mongodb/index.js +16 -59
  70. package/generated/prisma-mongodb/package.json +1 -1
  71. package/generated/prisma-mongodb/schema.prisma +33 -75
  72. package/generated/prisma-mongodb/wasm.js +16 -59
  73. package/generated/prisma-postgresql/edge.js +15 -59
  74. package/generated/prisma-postgresql/index-browser.js +11 -62
  75. package/generated/prisma-postgresql/index.d.ts +5963 -8930
  76. package/generated/prisma-postgresql/index.js +15 -59
  77. package/generated/prisma-postgresql/package.json +1 -1
  78. package/generated/prisma-postgresql/schema.prisma +33 -73
  79. package/generated/prisma-postgresql/wasm.js +15 -59
  80. package/handlers/WEBHOOKS.md +81 -104
  81. package/handlers/app-definition-loader.js +1 -1
  82. package/handlers/app-handler-helpers.js +2 -14
  83. package/handlers/backend-utils.js +1 -0
  84. package/handlers/database-migration-handler.js +45 -64
  85. package/handlers/middleware/admin-auth.js +53 -0
  86. package/handlers/routers/HEALTHCHECK.md +135 -170
  87. package/handlers/routers/auth.js +2 -23
  88. package/handlers/routers/db-migration.handler.js +3 -2
  89. package/handlers/routers/db-migration.js +33 -69
  90. package/handlers/routers/health.js +8 -23
  91. package/handlers/routers/integration-defined-routers.js +4 -4
  92. package/handlers/routers/integration-webhook-routers.js +7 -17
  93. package/handlers/routers/websocket.js +3 -9
  94. package/handlers/use-cases/check-integrations-health-use-case.js +6 -13
  95. package/handlers/workers/db-migration.js +26 -54
  96. package/index.js +9 -5
  97. package/integrations/WEBHOOK-QUICKSTART.md +14 -21
  98. package/integrations/index.js +0 -4
  99. package/integrations/integration-base.js +6 -9
  100. package/integrations/integration-router.js +146 -1817
  101. package/integrations/options.js +20 -47
  102. package/integrations/repositories/integration-repository-documentdb.js +24 -53
  103. package/integrations/repositories/integration-repository-factory.js +2 -6
  104. package/integrations/repositories/integration-repository-interface.js +9 -27
  105. package/integrations/repositories/integration-repository-postgres.js +3 -3
  106. package/integrations/repositories/process-repository-factory.js +1 -0
  107. package/integrations/repositories/process-repository-interface.js +5 -9
  108. package/integrations/repositories/process-repository-mongo.js +3 -7
  109. package/integrations/repositories/process-repository-postgres.js +2 -2
  110. package/integrations/tests/doubles/config-capturing-integration.js +8 -9
  111. package/integrations/tests/doubles/dummy-integration-class.js +8 -81
  112. package/integrations/tests/doubles/test-integration-repository.js +11 -51
  113. package/integrations/use-cases/create-integration.js +32 -36
  114. package/integrations/use-cases/create-process.js +9 -20
  115. package/integrations/use-cases/delete-integration-for-user.js +4 -5
  116. package/integrations/use-cases/get-integration-for-user.js +10 -25
  117. package/integrations/use-cases/get-integration-instance-by-definition.js +7 -13
  118. package/integrations/use-cases/get-integrations-for-user.js +1 -4
  119. package/integrations/use-cases/get-possible-integrations.js +1 -1
  120. package/integrations/use-cases/get-process.js +6 -5
  121. package/integrations/use-cases/index.js +1 -3
  122. package/integrations/use-cases/load-integration-context.js +5 -1
  123. package/integrations/use-cases/update-process-state.js +8 -10
  124. package/integrations/utils/map-integration-dto.js +3 -9
  125. package/jest-setup.js +1 -1
  126. package/jest-teardown.js +1 -1
  127. package/lambda/TimeoutCatcher.js +30 -32
  128. package/lambda/index.js +1 -1
  129. package/logs/index.js +3 -3
  130. package/modules/module.js +1 -3
  131. package/modules/repositories/module-repository-documentdb.js +48 -114
  132. package/modules/repositories/module-repository-interface.js +0 -13
  133. package/modules/repositories/module-repository-mongo.js +6 -46
  134. package/modules/repositories/module-repository-postgres.js +6 -48
  135. package/modules/repositories/module-repository.js +1 -34
  136. package/modules/requester/api-key.js +2 -0
  137. package/modules/requester/basic.js +1 -0
  138. package/modules/requester/oauth-2.js +2 -3
  139. package/modules/test/mock-api/definition.js +10 -15
  140. package/modules/test/mock-api/mocks/hubspot.js +36 -36
  141. package/modules/tests/doubles/test-module-factory.js +4 -10
  142. package/modules/tests/doubles/test-module-repository.js +1 -1
  143. package/modules/use-cases/get-entities-for-user.js +1 -1
  144. package/modules/use-cases/get-entity-options-by-id.js +6 -8
  145. package/modules/use-cases/get-module.js +9 -12
  146. package/modules/use-cases/process-authorization-callback.js +6 -12
  147. package/modules/use-cases/refresh-entity-options.js +6 -8
  148. package/modules/use-cases/test-module-auth.js +6 -8
  149. package/modules/utils/map-module-dto.js +2 -2
  150. package/package.json +5 -7
  151. package/prisma-mongodb/schema.prisma +33 -75
  152. package/prisma-postgresql/schema.prisma +33 -73
  153. package/queues/queuer-util.js +1 -5
  154. package/syncs/model.js +51 -51
  155. package/syncs/repositories/sync-repository-documentdb.js +19 -39
  156. package/syncs/repositories/sync-repository-interface.js +2 -6
  157. package/syncs/repositories/sync-repository-postgres.js +13 -19
  158. package/syncs/sync.js +100 -104
  159. package/token/repositories/token-repository-factory.js +3 -1
  160. package/types/assertions/index.d.ts +72 -72
  161. package/types/associations/index.d.ts +57 -57
  162. package/types/core/index.d.ts +53 -59
  163. package/types/database/index.d.ts +2 -2
  164. package/types/encrypt/index.d.ts +3 -3
  165. package/types/errors/index.d.ts +54 -61
  166. package/types/eslint-config/index.d.ts +40 -40
  167. package/types/integrations/index.d.ts +183 -185
  168. package/types/lambda/index.d.ts +26 -26
  169. package/types/logs/index.d.ts +4 -4
  170. package/types/module-plugin/index.d.ts +237 -239
  171. package/types/prettier-config/index.d.ts +5 -5
  172. package/types/syncs/index.d.ts +108 -102
  173. package/types/test-environment/index.d.ts +14 -14
  174. package/types/tsconfig.json +93 -95
  175. package/user/tests/doubles/test-user-repository.js +2 -5
  176. package/user/use-cases/authenticate-user.js +4 -2
  177. package/user/use-cases/authenticate-with-shared-secret.js +1 -1
  178. package/user/use-cases/create-individual-user.js +7 -8
  179. package/user/use-cases/create-organization-user.js +1 -1
  180. package/user/use-cases/create-token-for-user-id.js +1 -1
  181. package/user/use-cases/get-user-from-adopter-jwt.js +2 -0
  182. package/user/use-cases/get-user-from-bearer-token.js +3 -7
  183. package/user/use-cases/get-user-from-x-frigg-headers.js +11 -14
  184. package/user/use-cases/login-user.js +8 -8
  185. package/user/user.js +4 -18
  186. package/utils/backend-path.js +2 -2
  187. package/utils/index.js +1 -4
  188. package/websocket/repositories/websocket-connection-repository-documentdb.js +8 -21
  189. package/websocket/repositories/websocket-connection-repository-mongo.js +4 -8
  190. package/websocket/repositories/websocket-connection-repository-postgres.js +4 -8
  191. package/websocket/repositories/websocket-connection-repository.js +4 -8
  192. package/admin-scripts/repositories/admin-api-key-repository-interface.js +0 -121
  193. package/admin-scripts/repositories/admin-api-key-repository-mongo.js +0 -155
  194. package/admin-scripts/repositories/admin-api-key-repository-postgres.js +0 -189
  195. package/admin-scripts/repositories/script-execution-repository-documentdb.js +0 -21
  196. package/admin-scripts/repositories/script-execution-repository-factory.js +0 -55
  197. package/admin-scripts/repositories/script-execution-repository-interface.js +0 -193
  198. package/admin-scripts/repositories/script-execution-repository-mongo.js +0 -278
  199. package/admin-scripts/repositories/script-execution-repository-postgres.js +0 -320
  200. package/credential/credential-router.js +0 -262
  201. package/credential/use-cases/delete-credential-for-user.js +0 -50
  202. package/credential/use-cases/list-credentials-for-user.js +0 -31
  203. package/credential/use-cases/reauthorize-credential.js +0 -103
  204. package/handlers/routers/admin.js +0 -450
  205. package/handlers/routers/docs.js +0 -180
  206. package/handlers/routers/middleware/loadUser.js +0 -39
  207. package/handlers/routers/middleware/requireAdmin.js +0 -41
  208. package/handlers/routers/middleware/requireLoggedInUser.js +0 -19
  209. package/integrations/use-cases/execute-proxy-request.js +0 -564
  210. package/modules/domain/entities/AuthorizationSession.js +0 -131
  211. package/modules/domain/entities/index.js +0 -10
  212. package/modules/repositories/authorization-session-repository-factory.js +0 -55
  213. package/modules/repositories/authorization-session-repository-interface.js +0 -75
  214. package/modules/repositories/authorization-session-repository-mongo.js +0 -169
  215. package/modules/repositories/authorization-session-repository-postgres.js +0 -170
  216. package/modules/use-cases/delete-module-entity.js +0 -23
  217. package/modules/use-cases/get-authorization-requirements.js +0 -110
  218. package/modules/use-cases/get-module-entity-by-id.js +0 -16
  219. package/modules/use-cases/process-authorization-step.js +0 -160
  220. package/modules/use-cases/start-authorization-session.js +0 -86
  221. package/modules/use-cases/update-module-entity.js +0 -27
  222. package/openapi/openapi-spec-generator.js +0 -370
  223. package/openapi/openapi-v1.yaml +0 -1360
  224. package/openapi/openapi-v2.yaml +0 -1535
  225. package/user/use-cases/delete-user.js +0 -47
@@ -1,262 +0,0 @@
1
- const express = require('express');
2
- const Boom = require('@hapi/boom');
3
- const catchAsyncError = require('express-async-handler');
4
- const {
5
- createCredentialRepository,
6
- } = require('./repositories/credential-repository-factory');
7
- const {
8
- createModuleRepository,
9
- } = require('../modules/repositories/module-repository-factory');
10
- const {
11
- ListCredentialsForUser,
12
- } = require('./use-cases/list-credentials-for-user');
13
- const { GetCredentialForUser } = require('./use-cases/get-credential-for-user');
14
- const {
15
- DeleteCredentialForUser,
16
- } = require('./use-cases/delete-credential-for-user');
17
- const { ReauthorizeCredential } = require('./use-cases/reauthorize-credential');
18
-
19
- /**
20
- * Boom Error Handler Middleware
21
- * Handles Boom errors and converts them to appropriate HTTP responses
22
- * @param {Error} err - Error object
23
- * @param {Request} req - Express request
24
- * @param {Response} res - Express response
25
- * @param {Function} next - Express next function
26
- */
27
- function boomErrorHandler(err, req, res, next) {
28
- // Handle Boom errors
29
- if (err.isBoom) {
30
- return res.status(err.output.statusCode).json({
31
- error: err.output.payload.message,
32
- statusCode: err.output.statusCode,
33
- });
34
- }
35
-
36
- // Handle generic errors (500)
37
- console.error('Unexpected error:', err);
38
- return res.status(500).json({
39
- error: 'Internal server error',
40
- statusCode: 500,
41
- });
42
- }
43
-
44
- /**
45
- * Create Credential Router
46
- * Factory function that creates an Express router with credential management endpoints
47
- *
48
- * Endpoints:
49
- * - GET /api/credentials - List all credentials for authenticated user
50
- * - GET /api/credentials/:id - Get a single credential
51
- * - DELETE /api/credentials/:id - Delete a credential
52
- * - POST /api/credentials/:id/reauthorize - Reauthorize a credential
53
- *
54
- * Security:
55
- * - All endpoints require authentication (via authenticateUser middleware)
56
- * - Credentials are filtered to only belong to the authenticated user
57
- * - Sensitive data (tokens) are filtered from responses
58
- *
59
- * @returns {express.Router} Configured Express router
60
- */
61
- function createCredentialRouter() {
62
- const router = express.Router();
63
-
64
- // Load configuration and create repositories
65
- const credentialRepository = createCredentialRepository();
66
- const moduleRepository = createModuleRepository();
67
-
68
- // Create credential use cases
69
- const listCredentialsForUser = new ListCredentialsForUser({
70
- credentialRepository,
71
- });
72
-
73
- const getCredentialForUser = new GetCredentialForUser({
74
- credentialRepository,
75
- });
76
-
77
- const deleteCredentialForUser = new DeleteCredentialForUser({
78
- credentialRepository,
79
- });
80
-
81
- const reauthorizeCredential = new ReauthorizeCredential({
82
- credentialRepository,
83
- moduleRepository,
84
- });
85
-
86
- /**
87
- * Filter sensitive data from credential objects
88
- * Removes tokens and other sensitive fields from credentials before sending to client
89
- *
90
- * @param {Object|Array} credentials - Credential(s) to filter
91
- * @returns {Object|Array} Filtered credential(s)
92
- */
93
- function filterSensitiveData(credentials) {
94
- const filter = (cred) => {
95
- if (!cred) return cred;
96
-
97
- // Create a copy without sensitive fields
98
- const {
99
- data,
100
- access_token,
101
- refresh_token,
102
- id_token,
103
- domain,
104
- ...safeCredential
105
- } = cred;
106
-
107
- // Ensure we have timestamps in ISO format
108
- if (
109
- safeCredential.createdAt &&
110
- !(safeCredential.createdAt instanceof Date)
111
- ) {
112
- safeCredential.createdAt = new Date(
113
- safeCredential.createdAt
114
- ).toISOString();
115
- }
116
- if (
117
- safeCredential.updatedAt &&
118
- !(safeCredential.updatedAt instanceof Date)
119
- ) {
120
- safeCredential.updatedAt = new Date(
121
- safeCredential.updatedAt
122
- ).toISOString();
123
- }
124
-
125
- return safeCredential;
126
- };
127
-
128
- return Array.isArray(credentials)
129
- ? credentials.map(filter)
130
- : filter(credentials);
131
- }
132
-
133
- // GET /api/credentials - List all credentials for authenticated user
134
- router.get(
135
- '/',
136
- catchAsyncError(async (req, res) => {
137
- // Expect authentication middleware to have set req.user
138
- if (!req.user) {
139
- throw Boom.unauthorized('Authentication required');
140
- }
141
- const userId =
142
- typeof req.user.getId === 'function'
143
- ? req.user.getId()
144
- : req.user.id;
145
-
146
- const credentials = await listCredentialsForUser.execute(userId);
147
-
148
- // Filter out sensitive data before responding
149
- const safeCredentials = filterSensitiveData(credentials);
150
-
151
- res.json({ credentials: safeCredentials });
152
- })
153
- );
154
-
155
- // GET /api/credentials/:id - Get a single credential
156
- router.get(
157
- '/:id',
158
- catchAsyncError(async (req, res) => {
159
- if (!req.user) {
160
- throw Boom.unauthorized('Authentication required');
161
- }
162
- const userId =
163
- typeof req.user.getId === 'function'
164
- ? req.user.getId()
165
- : req.user.id;
166
- const credentialId = req.params.id;
167
-
168
- const credential = await getCredentialForUser.execute(
169
- credentialId,
170
- userId
171
- );
172
-
173
- // Filter out sensitive data before responding
174
- const safeCredential = filterSensitiveData(credential);
175
-
176
- res.json(safeCredential);
177
- })
178
- );
179
-
180
- // DELETE /api/credentials/:id - Delete a credential
181
- router.delete(
182
- '/:id',
183
- catchAsyncError(async (req, res) => {
184
- if (!req.user) {
185
- throw Boom.unauthorized('Authentication required');
186
- }
187
- const userId =
188
- typeof req.user.getId === 'function'
189
- ? req.user.getId()
190
- : req.user.id;
191
- const credentialId = req.params.id;
192
-
193
- const result = await deleteCredentialForUser.execute(
194
- credentialId,
195
- userId
196
- );
197
-
198
- // Check if deletion was successful
199
- if (result.deletedCount === 0) {
200
- throw Boom.internal('Failed to delete credential');
201
- }
202
-
203
- res.json({
204
- success: true,
205
- message: `Credential ${credentialId} deleted successfully`,
206
- });
207
- })
208
- );
209
-
210
- // POST /api/credentials/:id/reauthorize - Reauthorize a credential
211
- router.post(
212
- '/:id/reauthorize',
213
- catchAsyncError(async (req, res) => {
214
- if (!req.user) {
215
- throw Boom.unauthorized('Authentication required');
216
- }
217
- const userId =
218
- typeof req.user.getId === 'function'
219
- ? req.user.getId()
220
- : req.user.id;
221
- const credentialId = req.params.id;
222
-
223
- // Validate request body
224
- if (!req.body.data) {
225
- throw Boom.badRequest('data is required in request body');
226
- }
227
-
228
- // Get step and sessionId from request
229
- const step = parseInt(req.body.step || '1', 10);
230
- const sessionId = req.body.sessionId;
231
-
232
- // Validate step is a positive integer
233
- if (step < 1 || !Number.isInteger(step)) {
234
- throw Boom.badRequest('step must be a positive integer');
235
- }
236
-
237
- // Validate sessionId is present for steps > 1
238
- if (step > 1 && !sessionId) {
239
- throw Boom.badRequest('sessionId is required for step > 1');
240
- }
241
-
242
- // Execute the reauthorization
243
- const result = await reauthorizeCredential.execute(
244
- credentialId,
245
- userId,
246
- req.body.data,
247
- step,
248
- sessionId
249
- );
250
-
251
- res.json(result);
252
- })
253
- );
254
-
255
- // Boom error handler middleware
256
- // Must be added after all routes to catch errors from handlers
257
- router.use(boomErrorHandler);
258
-
259
- return router;
260
- }
261
-
262
- module.exports = { createCredentialRouter, boomErrorHandler };
@@ -1,50 +0,0 @@
1
- const Boom = require('@hapi/boom');
2
-
3
- /**
4
- * Delete Credential For User Use Case
5
- * Removes a credential after verifying ownership
6
- *
7
- * Business Logic:
8
- * - Verify credential exists
9
- * - Verify credential belongs to user (authorization)
10
- * - Delete the credential
11
- * - Return success status
12
- */
13
- class DeleteCredentialForUser {
14
- constructor({ credentialRepository }) {
15
- this.credentialRepository = credentialRepository;
16
- }
17
-
18
- /**
19
- * Execute the use case
20
- * @param {string} credentialId - Credential ID
21
- * @param {string} userId - User ID (for ownership verification)
22
- * @returns {Promise<Object>} Deletion result { deletedCount: number }
23
- */
24
- async execute(credentialId, userId) {
25
- // Check if credential exists
26
- const credential = await this.credentialRepository.findCredentialById(
27
- credentialId
28
- );
29
-
30
- if (!credential) {
31
- throw Boom.notFound(`Credential ${credentialId} not found`);
32
- }
33
-
34
- // Verify ownership - compare as strings to handle both MongoDB and PostgreSQL
35
- if (credential.userId.toString() !== userId.toString()) {
36
- throw Boom.forbidden(
37
- 'You do not have permission to delete this credential'
38
- );
39
- }
40
-
41
- // Delete the credential
42
- const result = await this.credentialRepository.deleteCredentialById(
43
- credentialId
44
- );
45
-
46
- return result;
47
- }
48
- }
49
-
50
- module.exports = { DeleteCredentialForUser };
@@ -1,31 +0,0 @@
1
- /**
2
- * List Credentials For User Use Case
3
- * Retrieves all credentials belonging to a specific user
4
- *
5
- * Business Logic:
6
- * - Fetches credentials for the authenticated user
7
- * - Returns list of credentials (sensitive data filtered by handler)
8
- * - Repository returns an array when filtering by userId only
9
- */
10
- class ListCredentialsForUser {
11
- constructor({ credentialRepository }) {
12
- this.credentialRepository = credentialRepository;
13
- }
14
-
15
- /**
16
- * Execute the use case
17
- * @param {string} userId - User ID
18
- * @returns {Promise<Array>} List of credentials (empty array if none found)
19
- */
20
- async execute(userId) {
21
- const credentials = await this.credentialRepository.findCredential({
22
- userId,
23
- });
24
-
25
- // Repository returns array for userId-only queries
26
- // Ensure we always return an array (defensive programming)
27
- return Array.isArray(credentials) ? credentials : [];
28
- }
29
- }
30
-
31
- module.exports = { ListCredentialsForUser };
@@ -1,103 +0,0 @@
1
- const Boom = require('@hapi/boom');
2
-
3
- /**
4
- * Reauthorize Credential Use Case
5
- * Re-authorizes an existing credential with new authentication data
6
- * Supports both single-step and multi-step authorization flows
7
- *
8
- * Business Logic:
9
- * - Verify credential exists and belongs to user
10
- * - Load the appropriate module for the credential type
11
- * - Process authorization callback (OAuth code, API keys, etc.)
12
- * - Update credential with new tokens
13
- * - Return success or next step requirements
14
- */
15
- class ReauthorizeCredential {
16
- constructor({ credentialRepository, moduleRepository }) {
17
- this.credentialRepository = credentialRepository;
18
- this.moduleRepository = moduleRepository;
19
- }
20
-
21
- /**
22
- * Execute the use case
23
- * @param {string} credentialId - Credential ID to reauthorize
24
- * @param {string} userId - User ID (for ownership verification)
25
- * @param {Object} authData - Authorization data
26
- * @param {number} [step=1] - Current step in multi-step flow
27
- * @param {string} [sessionId] - Session ID for multi-step flows
28
- * @returns {Promise<Object>} Success response or next step requirements
29
- */
30
- async execute(credentialId, userId, authData, step = 1, sessionId = null) {
31
- // Check if credential exists
32
- const credential = await this.credentialRepository.findCredentialById(
33
- credentialId
34
- );
35
-
36
- if (!credential) {
37
- throw Boom.notFound(`Credential ${credentialId} not found`);
38
- }
39
-
40
- // Verify ownership - compare as strings to handle both MongoDB and PostgreSQL
41
- if (credential.userId.toString() !== userId.toString()) {
42
- throw Boom.forbidden(
43
- 'You do not have permission to reauthorize this credential'
44
- );
45
- }
46
-
47
- // Load the module for this credential type
48
- const module = await this.moduleRepository.findModuleById(
49
- credential.id
50
- );
51
-
52
- if (!module) {
53
- throw Boom.badRequest(
54
- `Module not found for credential type: ${
55
- credential.type || 'unknown'
56
- }`
57
- );
58
- }
59
-
60
- // Process the authorization callback
61
- const result = await module.processAuthorizationCallback({
62
- credentialId,
63
- userId,
64
- data: authData,
65
- step,
66
- sessionId,
67
- });
68
-
69
- // Multi-step flow - return next step requirements
70
- if (result.step && result.step > 1) {
71
- return {
72
- step: result.step,
73
- totalSteps: result.totalSteps,
74
- sessionId: result.sessionId,
75
- requirements: result.requirements,
76
- message: result.message,
77
- };
78
- }
79
-
80
- // Single-step or final step - update credential and return success
81
- if (result.success) {
82
- // Fetch the updated credential to get the new authIsValid status
83
- const updatedCredential =
84
- await this.credentialRepository.findCredentialById(
85
- credentialId
86
- );
87
-
88
- return {
89
- success: true,
90
- credential_id: credentialId,
91
- authIsValid: updatedCredential?.authIsValid || true,
92
- ...(result.message && { message: result.message }),
93
- };
94
- }
95
-
96
- // If we get here, something unexpected happened
97
- throw new Error(
98
- 'Authorization callback did not return expected result format'
99
- );
100
- }
101
- }
102
-
103
- module.exports = { ReauthorizeCredential };