@friggframework/core 2.0.0--canary.490.dfd8df5.0 → 2.0.0--canary.490.1d4d68c.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 (30) hide show
  1. package/credential/repositories/credential-repository-factory.js +11 -13
  2. package/credential/repositories/{credential-repository-documentdb.js → credential-repository-mongodb-native.js} +4 -4
  3. package/database/repositories/health-check-repository-factory.js +10 -33
  4. package/database/repositories/{health-check-repository-documentdb.js → health-check-repository-mongodb-native.js} +4 -4
  5. package/integrations/repositories/integration-mapping-repository-factory.js +5 -30
  6. package/integrations/repositories/{integration-mapping-repository-documentdb.js → integration-mapping-repository-mongodb-native.js} +4 -4
  7. package/integrations/repositories/integration-repository-factory.js +11 -12
  8. package/integrations/repositories/{integration-repository-documentdb.js → integration-repository-mongodb-native.js} +12 -4
  9. package/integrations/repositories/process-repository-factory.js +5 -30
  10. package/integrations/repositories/{process-repository-documentdb.js → process-repository-mongodb-native.js} +4 -4
  11. package/modules/repositories/module-repository-factory.js +5 -11
  12. package/modules/repositories/{module-repository-documentdb.js → module-repository-mongodb-native.js} +4 -4
  13. package/package.json +5 -5
  14. package/syncs/repositories/sync-repository-factory.js +5 -11
  15. package/syncs/repositories/{sync-repository-documentdb.js → sync-repository-mongodb-native.js} +4 -4
  16. package/token/repositories/token-repository-factory.js +5 -11
  17. package/token/repositories/{token-repository-documentdb.js → token-repository-mongodb-native.js} +4 -4
  18. package/user/repositories/user-repository-factory.js +7 -32
  19. package/user/repositories/{user-repository-documentdb.js → user-repository-mongodb-native.js} +4 -4
  20. package/websocket/repositories/websocket-connection-repository-factory.js +5 -11
  21. package/websocket/repositories/{websocket-connection-repository-documentdb.js → websocket-connection-repository-mongodb-native.js} +4 -4
  22. package/credential/repositories/credential-repository-mongo.js +0 -311
  23. package/integrations/repositories/integration-mapping-repository-mongo.js +0 -165
  24. package/integrations/repositories/integration-repository-mongo.js +0 -307
  25. package/integrations/repositories/process-repository-mongo.js +0 -194
  26. package/modules/repositories/module-repository-mongo.js +0 -381
  27. package/syncs/repositories/sync-repository-mongo.js +0 -243
  28. package/token/repositories/token-repository-mongo.js +0 -216
  29. package/user/repositories/user-repository-mongo.js +0 -295
  30. package/websocket/repositories/websocket-connection-repository-mongo.js +0 -160
@@ -1,216 +0,0 @@
1
- const { prisma } = require('../../database/prisma');
2
- const bcrypt = require('bcryptjs');
3
- const { TokenRepositoryInterface } = require('./token-repository-interface');
4
- const { BaseRepositoryMongoDB } = require('../../database/repositories/base-repository-mongodb');
5
-
6
- const BCRYPT_ROUNDS = 10;
7
-
8
- /**
9
- * MongoDB Token Repository Adapter
10
- * Handles persistence of authentication tokens with bcrypt hashing
11
- *
12
- * MongoDB-specific characteristics:
13
- * - Uses String IDs (ObjectId)
14
- * - No ID conversion needed (IDs are already strings)
15
- * - Bcrypt hashing handled in repository layer
16
- */
17
- class TokenRepositoryMongo extends TokenRepositoryInterface {
18
- constructor() {
19
- super();
20
-
21
- // Use MongoDB base repository for DocumentDB compatibility
22
- const mongoBase = new BaseRepositoryMongoDB({ prismaClient: prisma });
23
- this.prisma = mongoBase.prisma;
24
- }
25
-
26
- /**
27
- * Create a token with expiration
28
- * Replaces: Token.createTokenWithExpire(userId, rawToken, minutes)
29
- *
30
- * @param {string} userId - The user ID
31
- * @param {string} rawToken - The raw (unhashed) token string
32
- * @param {number} minutes - Minutes until expiration
33
- * @returns {Promise<Object>} The created token record with string IDs
34
- */
35
- async createTokenWithExpire(userId, rawToken, minutes) {
36
- // Hash the token with bcrypt
37
- const tokenHash = await bcrypt.hash(rawToken, BCRYPT_ROUNDS);
38
-
39
- // Calculate expiration time
40
- const expires = new Date(Date.now() + minutes * 60000);
41
-
42
- return await this.prisma.token.create({
43
- data: {
44
- token: tokenHash,
45
- expires,
46
- userId,
47
- },
48
- });
49
- }
50
-
51
- /**
52
- * Validate and retrieve token from JSON token object
53
- * Replaces: Token.validateAndGetTokenFromJSONToken(tokenObj)
54
- *
55
- * @param {Object} tokenObj - Object with id and token properties
56
- * @returns {Promise<Object>} The validated token record with string IDs
57
- * @throws {Error} If token is invalid, expired, or doesn't exist
58
- */
59
- async validateAndGetToken(tokenObj) {
60
- const sessionToken = await this.prisma.token.findUnique({
61
- where: { id: tokenObj.id },
62
- });
63
-
64
- if (!sessionToken) {
65
- throw new Error('Invalid Token: Token does not exist');
66
- }
67
-
68
- // Verify token hash matches
69
- const isValid = await bcrypt.compare(
70
- tokenObj.token,
71
- sessionToken.token
72
- );
73
- if (!isValid) {
74
- throw new Error('Invalid Token: Token does not match');
75
- }
76
-
77
- // Check if token is expired
78
- if (
79
- sessionToken.expires &&
80
- new Date(sessionToken.expires) < new Date()
81
- ) {
82
- throw new Error('Invalid Token: Token is expired');
83
- }
84
-
85
- return sessionToken;
86
- }
87
-
88
- /**
89
- * Find a token by ID
90
- * Replaces: Token.findById(tokenId)
91
- *
92
- * @param {string} tokenId - The token ID
93
- * @returns {Promise<Object|null>} The token record with string IDs or null
94
- */
95
- async findTokenById(tokenId) {
96
- return await this.prisma.token.findUnique({
97
- where: { id: tokenId },
98
- });
99
- }
100
-
101
- /**
102
- * Find tokens by user ID
103
- * Replaces: Token.find({ user: userId })
104
- *
105
- * @param {string} userId - The user ID
106
- * @returns {Promise<Array>} Array of token records with string IDs
107
- */
108
- async findTokensByUserId(userId) {
109
- return await this.prisma.token.findMany({
110
- where: { userId },
111
- });
112
- }
113
-
114
- /**
115
- * Delete a token by ID
116
- * Replaces: Token.deleteOne({ _id: tokenId })
117
- *
118
- * @param {string} tokenId - The token ID
119
- * @returns {Promise<Object>} The deletion result
120
- */
121
- async deleteToken(tokenId) {
122
- try {
123
- await this.prisma.token.delete({
124
- where: { id: tokenId },
125
- });
126
- return { acknowledged: true, deletedCount: 1 };
127
- } catch (error) {
128
- if (error.code === 'P2025') {
129
- // Record not found
130
- return { acknowledged: true, deletedCount: 0 };
131
- }
132
- throw error;
133
- }
134
- }
135
-
136
- /**
137
- * Delete expired tokens
138
- * Replaces: Token.deleteMany({ expires: { $lt: new Date() } })
139
- *
140
- * @returns {Promise<Object>} The deletion result with count
141
- */
142
- async deleteExpiredTokens() {
143
- const result = await this.prisma.token.deleteMany({
144
- where: {
145
- expires: {
146
- lt: new Date(),
147
- },
148
- },
149
- });
150
-
151
- return {
152
- acknowledged: true,
153
- deletedCount: result.count,
154
- };
155
- }
156
-
157
- /**
158
- * Delete all tokens for a user
159
- * Replaces: Token.deleteMany({ user: userId })
160
- *
161
- * @param {string} userId - The user ID
162
- * @returns {Promise<Object>} The deletion result
163
- */
164
- async deleteTokensByUserId(userId) {
165
- const result = await this.prisma.token.deleteMany({
166
- where: { userId },
167
- });
168
-
169
- return {
170
- acknowledged: true,
171
- deletedCount: result.count,
172
- };
173
- }
174
-
175
- /**
176
- * Create JSON token string from token object and raw token
177
- * Replaces: Token.createJSONToken(token, rawToken)
178
- *
179
- * @param {Object} token - The token record
180
- * @param {string} rawToken - The raw token string
181
- * @returns {string} JSON string with id and token
182
- */
183
- createJSONToken(token, rawToken) {
184
- return JSON.stringify({
185
- id: token.id,
186
- token: rawToken,
187
- });
188
- }
189
-
190
- /**
191
- * Create base64 encoded buffer token
192
- * Replaces: Token.createBase64BufferToken(token, rawToken)
193
- *
194
- * @param {Object} token - The token record
195
- * @param {string} rawToken - The raw token string
196
- * @returns {string} Base64 encoded token
197
- */
198
- createBase64BufferToken(token, rawToken) {
199
- const jsonVal = this.createJSONToken(token, rawToken);
200
- return Buffer.from(jsonVal).toString('base64');
201
- }
202
-
203
- /**
204
- * Parse JSON token from base64 buffer
205
- * Replaces: Token.getJSONTokenFromBase64BufferToken(buffer)
206
- *
207
- * @param {string} buffer - Base64 encoded token string
208
- * @returns {Object} Parsed token object with id and token
209
- */
210
- getJSONTokenFromBase64BufferToken(buffer) {
211
- const tokenStr = Buffer.from(buffer.trim(), 'base64').toString('ascii');
212
- return JSON.parse(tokenStr);
213
- }
214
- }
215
-
216
- module.exports = { TokenRepositoryMongo };
@@ -1,295 +0,0 @@
1
- const bcrypt = require('bcryptjs');
2
- const { prisma } = require('../../database/prisma');
3
- const {
4
- createTokenRepository,
5
- } = require('../../token/repositories/token-repository-factory');
6
- const { UserRepositoryInterface } = require('./user-repository-interface');
7
- const { BaseRepositoryMongoDB } = require('../../database/repositories/base-repository-mongodb');
8
-
9
- /**
10
- * MongoDB User Repository Adapter
11
- * Handles user operations with discriminator pattern support
12
- *
13
- * MongoDB-specific characteristics:
14
- * - Uses String IDs (ObjectId)
15
- * - No ID conversion needed (IDs are already strings)
16
- * - IndividualUser/OrganizationUser discriminators → User model with type field
17
- */
18
- class UserRepositoryMongo extends UserRepositoryInterface {
19
- constructor() {
20
- super();
21
-
22
- // Use MongoDB base repository for DocumentDB compatibility
23
- const mongoBase = new BaseRepositoryMongoDB({ prismaClient: prisma });
24
- this.prisma = mongoBase.prisma;
25
- this.tokenRepository = createTokenRepository();
26
- }
27
-
28
- /**
29
- * Get session token from base64 buffer token
30
- * Delegates to TokenRepository
31
- *
32
- * @param {string} token - Base64 buffer token
33
- * @returns {Promise<Object>} Session token object with string IDs
34
- */
35
- async getSessionToken(token) {
36
- const jsonToken =
37
- this.tokenRepository.getJSONTokenFromBase64BufferToken(token);
38
- const sessionToken = await this.tokenRepository.validateAndGetToken(
39
- jsonToken
40
- );
41
- return sessionToken;
42
- }
43
-
44
- /**
45
- * Find organization user by ID
46
- * Replaces: OrganizationUser.findById(userId)
47
- *
48
- * @param {string} userId - User ID
49
- * @returns {Promise<Object|null>} User object with string IDs or null
50
- */
51
- async findOrganizationUserById(userId) {
52
- return await this.prisma.user.findFirst({
53
- where: {
54
- id: userId,
55
- type: 'ORGANIZATION',
56
- },
57
- });
58
- }
59
-
60
- /**
61
- * Find individual user by ID
62
- * Replaces: IndividualUser.findById(userId)
63
- *
64
- * @param {string} userId - User ID
65
- * @returns {Promise<Object|null>} User object with string IDs or null
66
- */
67
- async findIndividualUserById(userId) {
68
- return await this.prisma.user.findFirst({
69
- where: {
70
- id: userId,
71
- type: 'INDIVIDUAL',
72
- },
73
- });
74
- }
75
-
76
- /**
77
- * Create token with expiration
78
- * Delegates to TokenRepository
79
- *
80
- * @param {string} userId - User ID
81
- * @param {string} rawToken - Raw unhashed token
82
- * @param {number} minutes - Minutes until expiration (default 120)
83
- * @returns {Promise<string>} Base64 buffer token
84
- */
85
- async createToken(userId, rawToken, minutes = 120) {
86
- const createdToken = await this.tokenRepository.createTokenWithExpire(
87
- userId,
88
- rawToken,
89
- minutes
90
- );
91
- return this.tokenRepository.createBase64BufferToken(
92
- createdToken,
93
- rawToken
94
- );
95
- }
96
-
97
- /**
98
- * Create individual user
99
- * Replaces: IndividualUser.create(params)
100
- *
101
- * @param {Object} params - User creation parameters
102
- * @param {string} [params.hashword] - Plain text password (will be bcrypt hashed automatically)
103
- * @returns {Promise<Object>} Created user object with string IDs
104
- */
105
- async createIndividualUser(params) {
106
- const data = {
107
- type: 'INDIVIDUAL',
108
- email: params.email,
109
- username: params.username,
110
- appUserId: params.appUserId,
111
- organizationId: params.organization || params.organizationId,
112
- };
113
-
114
- if (
115
- params.hashword !== undefined &&
116
- params.hashword !== null &&
117
- params.hashword !== ''
118
- ) {
119
- if (typeof params.hashword !== 'string') {
120
- throw new Error('Password must be a string');
121
- }
122
-
123
- // Prevent double-hashing: bcrypt hashes start with $2a$ or $2b$
124
- if (params.hashword.startsWith('$2')) {
125
- throw new Error(
126
- 'Password appears to be already hashed. Pass plain text password only.'
127
- );
128
- }
129
-
130
- data.hashword = await bcrypt.hash(params.hashword, 10);
131
- }
132
-
133
- return await this.prisma.user.create({ data });
134
- }
135
-
136
- /**
137
- * Create organization user
138
- * Replaces: OrganizationUser.create(params)
139
- *
140
- * @param {Object} params - Organization creation parameters
141
- * @returns {Promise<Object>} Created organization object with string IDs
142
- */
143
- async createOrganizationUser(params) {
144
- return await this.prisma.user.create({
145
- data: {
146
- type: 'ORGANIZATION',
147
- appOrgId: params.appOrgId,
148
- name: params.name,
149
- },
150
- });
151
- }
152
-
153
- /**
154
- * Find individual user by username
155
- * Replaces: IndividualUser.findOne({ username })
156
- *
157
- * @param {string} username - Username to search for
158
- * @returns {Promise<Object|null>} User object with string IDs or null
159
- */
160
- async findIndividualUserByUsername(username) {
161
- return await this.prisma.user.findFirst({
162
- where: {
163
- type: 'INDIVIDUAL',
164
- username,
165
- },
166
- });
167
- }
168
-
169
- /**
170
- * Find individual user by app user ID
171
- * Replaces: IndividualUser.getUserByAppUserId(appUserId)
172
- *
173
- * @param {string} appUserId - App user ID to search for
174
- * @returns {Promise<Object|null>} User object with string IDs or null
175
- */
176
- async findIndividualUserByAppUserId(appUserId) {
177
- return await this.prisma.user.findFirst({
178
- where: {
179
- type: 'INDIVIDUAL',
180
- appUserId,
181
- },
182
- });
183
- }
184
-
185
- /**
186
- * Find organization user by app org ID
187
- * Replaces: OrganizationUser.getUserByAppOrgId(appOrgId)
188
- *
189
- * @param {string} appOrgId - App organization ID to search for
190
- * @returns {Promise<Object|null>} User object with string IDs or null
191
- */
192
- async findOrganizationUserByAppOrgId(appOrgId) {
193
- return await this.prisma.user.findFirst({
194
- where: {
195
- type: 'ORGANIZATION',
196
- appOrgId,
197
- },
198
- });
199
- }
200
-
201
- /**
202
- * Find user by ID (any type)
203
- * @param {string} userId - User ID
204
- * @returns {Promise<Object|null>} User object with string IDs or null
205
- */
206
- async findUserById(userId) {
207
- return await this.prisma.user.findUnique({
208
- where: { id: userId },
209
- });
210
- }
211
-
212
- /**
213
- * Find individual user by email
214
- * @param {string} email - Email to search for
215
- * @returns {Promise<Object|null>} User object with string IDs or null
216
- */
217
- async findIndividualUserByEmail(email) {
218
- return await this.prisma.user.findFirst({
219
- where: {
220
- type: 'INDIVIDUAL',
221
- email,
222
- },
223
- });
224
- }
225
-
226
- /**
227
- * Update individual user
228
- * @param {string} userId - User ID
229
- * @param {Object} updates - Fields to update
230
- * @param {string} [updates.hashword] - Plain text password (will be bcrypt hashed automatically)
231
- * @returns {Promise<Object>} Updated user object with string IDs
232
- */
233
- async updateIndividualUser(userId, updates) {
234
- const data = { ...updates };
235
-
236
- if (
237
- data.hashword !== undefined &&
238
- data.hashword !== null &&
239
- data.hashword !== ''
240
- ) {
241
- if (typeof data.hashword !== 'string') {
242
- throw new Error('Password must be a string');
243
- }
244
-
245
- // Prevent double-hashing: bcrypt hashes start with $2a$ or $2b$
246
- if (data.hashword.startsWith('$2')) {
247
- throw new Error(
248
- 'Password appears to be already hashed. Pass plain text password only.'
249
- );
250
- }
251
-
252
- data.hashword = await bcrypt.hash(data.hashword, 10);
253
- }
254
-
255
- return await this.prisma.user.update({
256
- where: { id: userId },
257
- data,
258
- });
259
- }
260
-
261
- /**
262
- * Update organization user
263
- * @param {string} userId - User ID
264
- * @param {Object} updates - Fields to update
265
- * @returns {Promise<Object>} Updated user object with string IDs
266
- */
267
- async updateOrganizationUser(userId, updates) {
268
- return await this.prisma.user.update({
269
- where: { id: userId },
270
- data: updates,
271
- });
272
- }
273
-
274
- /**
275
- * Delete user by ID
276
- * @param {string} userId - User ID to delete
277
- * @returns {Promise<boolean>} True if deleted successfully
278
- */
279
- async deleteUser(userId) {
280
- try {
281
- await this.prisma.user.delete({
282
- where: { id: userId },
283
- });
284
- return true;
285
- } catch (error) {
286
- if (error.code === 'P2025') {
287
- // Record not found
288
- return false;
289
- }
290
- throw error;
291
- }
292
- }
293
- }
294
-
295
- module.exports = { UserRepositoryMongo };
@@ -1,160 +0,0 @@
1
- const { prisma } = require('../../database/prisma');
2
- const {
3
- ApiGatewayManagementApiClient,
4
- PostToConnectionCommand,
5
- } = require('@aws-sdk/client-apigatewaymanagementapi');
6
- const {
7
- WebsocketConnectionRepositoryInterface,
8
- } = require('./websocket-connection-repository-interface');
9
- const { BaseRepositoryMongoDB } = require('../../database/repositories/base-repository-mongodb');
10
-
11
- /**
12
- * MongoDB WebSocket Connection Repository Adapter
13
- * Handles persistence of active WebSocket connections
14
- *
15
- * MongoDB-specific characteristics:
16
- * - Uses String IDs (ObjectId)
17
- * - No ID conversion needed (IDs are already strings)
18
- * - AWS API Gateway Management API integration preserved
19
- */
20
- class WebsocketConnectionRepositoryMongo extends WebsocketConnectionRepositoryInterface {
21
- constructor() {
22
- super();
23
-
24
- // Use MongoDB base repository for DocumentDB compatibility
25
- const mongoBase = new BaseRepositoryMongoDB({ prismaClient: prisma });
26
- this.prisma = mongoBase.prisma;
27
- }
28
-
29
- /**
30
- * Create a new WebSocket connection record
31
- * Replaces: WebsocketConnection.create({ connectionId })
32
- *
33
- * @param {string} connectionId - The WebSocket connection ID
34
- * @returns {Promise<Object>} The created connection record with string IDs
35
- */
36
- async createConnection(connectionId) {
37
- return await this.prisma.websocketConnection.create({
38
- data: { connectionId },
39
- });
40
- }
41
-
42
- /**
43
- * Delete a WebSocket connection record
44
- * Replaces: WebsocketConnection.deleteOne({ connectionId })
45
- *
46
- * @param {string} connectionId - The WebSocket connection ID to delete
47
- * @returns {Promise<Object>} The deletion result
48
- */
49
- async deleteConnection(connectionId) {
50
- try {
51
- await this.prisma.websocketConnection.delete({
52
- where: { connectionId },
53
- });
54
- return { acknowledged: true, deletedCount: 1 };
55
- } catch (error) {
56
- if (error.code === 'P2025') {
57
- // Record not found
58
- return { acknowledged: true, deletedCount: 0 };
59
- }
60
- throw error;
61
- }
62
- }
63
-
64
- /**
65
- * Get all active WebSocket connections with send capability
66
- * Replaces: WebsocketConnection.getActiveConnections()
67
- *
68
- * @returns {Promise<Array>} Array of active connection objects with send capability
69
- */
70
- async getActiveConnections() {
71
- try {
72
- // Return empty array if websockets are not configured
73
- if (!process.env.WEBSOCKET_API_ENDPOINT) {
74
- return [];
75
- }
76
-
77
- const connections = await this.prisma.websocketConnection.findMany({
78
- select: { connectionId: true },
79
- });
80
-
81
- return connections.map((conn) => ({
82
- connectionId: conn.connectionId,
83
- send: async (data) => {
84
- const apigwManagementApi = new ApiGatewayManagementApiClient({
85
- endpoint: process.env.WEBSOCKET_API_ENDPOINT,
86
- });
87
-
88
- try {
89
- const command = new PostToConnectionCommand({
90
- ConnectionId: conn.connectionId,
91
- Data: JSON.stringify(data),
92
- });
93
- await apigwManagementApi.send(command);
94
- } catch (error) {
95
- if (error.statusCode === 410 || error.$metadata?.httpStatusCode === 410) {
96
- console.log(
97
- `Stale connection ${conn.connectionId}`
98
- );
99
- // Delete stale connection
100
- await this.prisma.websocketConnection.deleteMany({
101
- where: { connectionId: conn.connectionId },
102
- });
103
- } else {
104
- throw error;
105
- }
106
- }
107
- },
108
- }));
109
- } catch (error) {
110
- console.error('Error getting active connections:', error);
111
- throw error;
112
- }
113
- }
114
-
115
- /**
116
- * Find a connection by connection ID
117
- * Replaces: WebsocketConnection.findOne({ connectionId })
118
- *
119
- * @param {string} connectionId - The WebSocket connection ID
120
- * @returns {Promise<Object|null>} The connection record with string IDs or null
121
- */
122
- async findConnection(connectionId) {
123
- return await this.prisma.websocketConnection.findFirst({
124
- where: { connectionId },
125
- });
126
- }
127
-
128
- /**
129
- * Find connection by internal ID
130
- * @param {string} id - The internal connection ID
131
- * @returns {Promise<Object|null>} The connection record with string IDs or null
132
- */
133
- async findConnectionById(id) {
134
- return await this.prisma.websocketConnection.findUnique({
135
- where: { id },
136
- });
137
- }
138
-
139
- /**
140
- * Get all connections
141
- * @returns {Promise<Array>} Array of all connection records with string IDs
142
- */
143
- async getAllConnections() {
144
- return await this.prisma.websocketConnection.findMany();
145
- }
146
-
147
- /**
148
- * Delete all connections
149
- * @returns {Promise<Object>} The deletion result
150
- */
151
- async deleteAllConnections() {
152
- const result = await this.prisma.websocketConnection.deleteMany();
153
- return {
154
- acknowledged: true,
155
- deletedCount: result.count,
156
- };
157
- }
158
- }
159
-
160
- module.exports = { WebsocketConnectionRepositoryMongo };