@friggframework/core 2.0.0-next.54 → 2.0.0-next.55

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.
@@ -56,7 +56,7 @@ function createCredentialCommands() {
56
56
  }
57
57
 
58
58
  const credentialData = {
59
- identifiers: { user: userId, externalId },
59
+ identifiers: { userId, externalId },
60
60
  details: {
61
61
  access_token,
62
62
  authIsValid,
@@ -39,6 +39,18 @@ const createHandler = (optionByName = {}) => {
39
39
 
40
40
  // Don't leak implementation details to end users.
41
41
  if (isUserFacingResponse) {
42
+ // Allow client-safe errors to pass through with their actual message
43
+ if (error.isClientSafe === true) {
44
+ const statusCode = error.statusCode || 400;
45
+ return {
46
+ statusCode,
47
+ body: JSON.stringify({
48
+ error: error.message,
49
+ }),
50
+ };
51
+ }
52
+
53
+ // Hide other errors with generic message
42
54
  return {
43
55
  statusCode: 500,
44
56
  body: JSON.stringify({
@@ -10,7 +10,9 @@ const {
10
10
  const {
11
11
  CredentialRepositoryInterface,
12
12
  } = require('./credential-repository-interface');
13
- const { DocumentDBEncryptionService } = require('../../database/documentdb-encryption-service');
13
+ const {
14
+ DocumentDBEncryptionService,
15
+ } = require('../../database/documentdb-encryption-service');
14
16
 
15
17
  /**
16
18
  * Credential repository for DocumentDB.
@@ -20,7 +22,6 @@ const { DocumentDBEncryptionService } = require('../../database/documentdb-encry
20
22
  * - Credential.data.access_token
21
23
  * - Credential.data.refresh_token
22
24
  * - Credential.data.id_token
23
- * - Credential.data.domain
24
25
  *
25
26
  * SECURITY CRITICAL: All OAuth credentials must be encrypted at rest.
26
27
  *
@@ -40,8 +41,10 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
40
41
  const doc = await findOne(this.prisma, 'Credential', { _id: objectId });
41
42
  if (!doc) return null;
42
43
 
43
- // Decrypt sensitive fields using service
44
- const decryptedCredential = await this.encryptionService.decryptFields('Credential', doc);
44
+ const decryptedCredential = await this.encryptionService.decryptFields(
45
+ 'Credential',
46
+ doc
47
+ );
45
48
  return this._mapCredentialById(decryptedCredential);
46
49
  }
47
50
 
@@ -63,16 +66,19 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
63
66
  async deleteCredentialById(credentialId) {
64
67
  const objectId = toObjectId(credentialId);
65
68
  if (!objectId) return { acknowledged: true, deletedCount: 0 };
66
- const result = await deleteOne(this.prisma, 'Credential', { _id: objectId });
69
+ const result = await deleteOne(this.prisma, 'Credential', {
70
+ _id: objectId,
71
+ });
67
72
  const deleted = result?.n ?? 0;
68
73
  return { acknowledged: true, deletedCount: deleted };
69
74
  }
70
75
 
71
76
  async upsertCredential(credentialDetails) {
72
77
  const { identifiers, details } = credentialDetails;
73
- if (!identifiers) throw new Error('identifiers required to upsert credential');
74
- if (!identifiers.user && !identifiers.userId) {
75
- throw new Error('user or userId required in identifiers');
78
+ if (!identifiers)
79
+ throw new Error('identifiers required to upsert credential');
80
+ if (!identifiers.userId) {
81
+ throw new Error('userId required in identifiers');
76
82
  }
77
83
  if (!identifiers.externalId) {
78
84
  throw new Error(
@@ -82,32 +88,29 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
82
88
 
83
89
  const filter = this._buildIdentifierFilter(identifiers);
84
90
  const existing = await findOne(this.prisma, 'Credential', filter);
85
-
86
- const {
87
- user,
88
- userId,
89
- authIsValid,
90
- externalId,
91
- ...oauthData
92
- } = details || {};
93
-
94
91
  const now = new Date();
95
92
 
93
+ const { authIsValid, ...oauthData } = details || {};
94
+
96
95
  if (existing) {
97
- // Decrypt existing credential data first
98
- const decryptedExisting = await this.encryptionService.decryptFields('Credential', existing);
99
- const mergedData = { ...(decryptedExisting.data || {}), ...oauthData };
96
+ const decryptedExisting =
97
+ await this.encryptionService.decryptFields(
98
+ 'Credential',
99
+ existing
100
+ );
101
+ const mergedData = {
102
+ ...(decryptedExisting.data || {}),
103
+ ...oauthData,
104
+ };
100
105
 
101
- // Build update document
102
106
  const updateDocument = {
103
- userId: toObjectId(userId || user) || existing.userId || null,
104
- externalId: externalId !== undefined ? externalId : existing.externalId,
105
- authIsValid: authIsValid !== undefined ? authIsValid : existing.authIsValid,
107
+ userId: existing.userId,
108
+ externalId: existing.externalId,
109
+ authIsValid: authIsValid,
106
110
  data: mergedData,
107
111
  updatedAt: now,
108
112
  };
109
113
 
110
- // Encrypt before storing
111
114
  const encryptedUpdate = await this.encryptionService.encryptFields(
112
115
  'Credential',
113
116
  { data: updateDocument.data }
@@ -128,33 +131,44 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
128
131
  }
129
132
  );
130
133
 
131
- // Read back and decrypt
132
- const updated = await findOne(this.prisma, 'Credential', { _id: existing._id });
133
- const decryptedCredential = await this.encryptionService.decryptFields('Credential', updated);
134
+ const updated = await findOne(this.prisma, 'Credential', {
135
+ _id: existing._id,
136
+ });
137
+ const decryptedCredential =
138
+ await this.encryptionService.decryptFields(
139
+ 'Credential',
140
+ updated
141
+ );
134
142
  return this._mapCredential(decryptedCredential);
135
143
  }
136
144
 
137
- // Build plain text document
138
145
  const plainDocument = {
139
- userId: toObjectId(userId || user || identifiers.user),
140
- externalId: externalId !== undefined ? externalId : identifiers.externalId,
141
- authIsValid: authIsValid ?? null,
142
- data: oauthData,
146
+ userId: identifiers.userId,
147
+ externalId: identifiers.externalId,
148
+ authIsValid: details.authIsValid,
149
+ data: { ...oauthData },
143
150
  createdAt: now,
144
151
  updatedAt: now,
145
152
  };
146
153
 
147
- // Encrypt before storing
148
154
  const encryptedDocument = await this.encryptionService.encryptFields(
149
155
  'Credential',
150
156
  plainDocument
151
157
  );
152
158
 
153
- const insertedId = await insertOne(this.prisma, 'Credential', encryptedDocument);
159
+ const insertedId = await insertOne(
160
+ this.prisma,
161
+ 'Credential',
162
+ encryptedDocument
163
+ );
154
164
 
155
- // Read back and decrypt
156
- const created = await findOne(this.prisma, 'Credential', { _id: insertedId });
157
- const decryptedCredential = await this.encryptionService.decryptFields('Credential', created);
165
+ const created = await findOne(this.prisma, 'Credential', {
166
+ _id: insertedId,
167
+ });
168
+ const decryptedCredential = await this.encryptionService.decryptFields(
169
+ 'Credential',
170
+ created
171
+ );
158
172
  return this._mapCredential(decryptedCredential);
159
173
  }
160
174
 
@@ -163,39 +177,37 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
163
177
  const credential = await findOne(this.prisma, 'Credential', query);
164
178
  if (!credential) return null;
165
179
 
166
- // Decrypt sensitive fields using service
167
- const decryptedCredential = await this.encryptionService.decryptFields('Credential', credential);
180
+ const decryptedCredential = await this.encryptionService.decryptFields(
181
+ 'Credential',
182
+ credential
183
+ );
168
184
  return this._mapCredential(decryptedCredential);
169
185
  }
170
186
 
171
187
  async updateCredential(credentialId, updates) {
172
188
  const objectId = toObjectId(credentialId);
173
189
  if (!objectId) return null;
174
- const existing = await findOne(this.prisma, 'Credential', { _id: objectId });
190
+ const existing = await findOne(this.prisma, 'Credential', {
191
+ _id: objectId,
192
+ });
175
193
  if (!existing) return null;
176
194
 
177
- const {
178
- user,
179
- userId,
180
- authIsValid,
181
- externalId,
182
- ...oauthData
183
- } = updates || {};
195
+ const { authIsValid, ...oauthData } = updates || {};
184
196
 
185
- // Decrypt existing credential data first
186
- const decryptedExisting = await this.encryptionService.decryptFields('Credential', existing);
197
+ const decryptedExisting = await this.encryptionService.decryptFields(
198
+ 'Credential',
199
+ existing
200
+ );
187
201
  const mergedData = { ...(decryptedExisting.data || {}), ...oauthData };
188
202
 
189
- // Build update document
190
203
  const updateDocument = {
191
- userId: toObjectId(userId || user) || existing.userId || null,
192
- externalId: externalId !== undefined ? externalId : existing.externalId,
193
- authIsValid: authIsValid !== undefined ? authIsValid : existing.authIsValid,
204
+ userId: existing.userId,
205
+ externalId: existing.externalId,
206
+ authIsValid: authIsValid,
194
207
  data: mergedData,
195
208
  updatedAt: new Date(),
196
209
  };
197
210
 
198
- // Encrypt before storing
199
211
  const encryptedUpdate = await this.encryptionService.encryptFields(
200
212
  'Credential',
201
213
  { data: updateDocument.data }
@@ -216,9 +228,13 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
216
228
  }
217
229
  );
218
230
 
219
- // Read back and decrypt
220
- const updated = await findOne(this.prisma, 'Credential', { _id: objectId });
221
- const decryptedCredential = await this.encryptionService.decryptFields('Credential', updated);
231
+ const updated = await findOne(this.prisma, 'Credential', {
232
+ _id: objectId,
233
+ });
234
+ const decryptedCredential = await this.encryptionService.decryptFields(
235
+ 'Credential',
236
+ updated
237
+ );
222
238
  return this._mapCredential(decryptedCredential);
223
239
  }
224
240
 
@@ -228,9 +244,8 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
228
244
  const idObj = toObjectId(identifiers._id || identifiers.id);
229
245
  if (idObj) filter._id = idObj;
230
246
  }
231
- if (identifiers.user || identifiers.userId) {
232
- const userObj = toObjectId(identifiers.user || identifiers.userId);
233
- if (userObj) filter.userId = userObj;
247
+ if (identifiers.userId) {
248
+ filter.userId = identifiers.userId;
234
249
  }
235
250
  if (identifiers.externalId !== undefined) {
236
251
  filter.externalId = identifiers.externalId;
@@ -245,9 +260,8 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
245
260
  const idObj = toObjectId(filter.credentialId || filter.id);
246
261
  if (idObj) query._id = idObj;
247
262
  }
248
- if (filter.user || filter.userId) {
249
- const userObj = toObjectId(filter.user || filter.userId);
250
- if (userObj) query.userId = userObj;
263
+ if (filter.userId !== undefined) {
264
+ query.userId = filter.userId;
251
265
  }
252
266
  if (filter.externalId !== undefined) {
253
267
  query.externalId = filter.externalId;
@@ -256,15 +270,14 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
256
270
  }
257
271
 
258
272
  /**
259
- * Map credential document to application format (without legacy fields)
260
- * Used by findCredential, upsertCredential, updateCredential
273
+ * Map credential document to application format
261
274
  * Matches MongoDB repository format
262
275
  * @private
263
276
  */
264
277
  _mapCredential(doc) {
265
278
  const data = doc?.data || {};
266
279
  const id = fromObjectId(doc?._id);
267
- const userId = fromObjectId(doc?.userId);
280
+ const userId = doc?.userId;
268
281
  return {
269
282
  id,
270
283
  userId,
@@ -274,20 +287,12 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
274
287
  };
275
288
  }
276
289
 
277
- /**
278
- * Map credential document with legacy fields for findCredentialById
279
- * Includes _id and user fields for backward compatibility
280
- * Matches MongoDB repository format
281
- * @private
282
- */
283
290
  _mapCredentialById(doc) {
284
291
  const data = doc?.data || {};
285
292
  const id = fromObjectId(doc?._id);
286
- const userId = fromObjectId(doc?.userId);
293
+ const userId = doc?.userId;
287
294
  return {
288
- _id: id,
289
295
  id,
290
- user: userId,
291
296
  userId,
292
297
  externalId: doc?.externalId ?? null,
293
298
  authIsValid: doc?.authIsValid ?? null,
@@ -297,4 +302,3 @@ class CredentialRepositoryDocumentDB extends CredentialRepositoryInterface {
297
302
  }
298
303
 
299
304
  module.exports = { CredentialRepositoryDocumentDB };
300
-
@@ -38,9 +38,7 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
38
38
  const data = credential.data || {};
39
39
 
40
40
  return {
41
- _id: credential.id,
42
41
  id: credential.id,
43
- user: credential.userId,
44
42
  userId: credential.userId,
45
43
  externalId: credential.externalId,
46
44
  authIsValid: credential.authIsValid,
@@ -80,7 +78,6 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
80
78
  return { acknowledged: true, deletedCount: 1 };
81
79
  } catch (error) {
82
80
  if (error.code === 'P2025') {
83
- // Record not found
84
81
  return { acknowledged: true, deletedCount: 0 };
85
82
  }
86
83
  throw error;
@@ -99,49 +96,32 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
99
96
  if (!identifiers)
100
97
  throw new Error('identifiers required to upsert credential');
101
98
 
102
- if (!identifiers.user && !identifiers.userId) {
103
- throw new Error('user or userId required in identifiers');
99
+ if (!identifiers.userId) {
100
+ throw new Error('userId required in identifiers');
104
101
  }
105
102
  if (!identifiers.externalId) {
106
103
  throw new Error(
107
104
  'externalId required in identifiers to prevent credential collision. ' +
108
- 'When multiple credentials exist for the same user, both userId and externalId ' +
109
- 'are needed to uniquely identify which credential to update.'
105
+ 'When multiple credentials exist for the same user, both userId and externalId ' +
106
+ 'are needed to uniquely identify which credential to update.'
110
107
  );
111
108
  }
112
109
 
113
- // Build where clause from identifiers
114
110
  const where = this._convertIdentifiersToWhere(identifiers);
115
111
 
116
- // Separate schema fields from dynamic OAuth data
117
- const {
118
- user,
119
- userId,
120
- externalId,
121
- authIsValid,
122
-
123
- ...oauthData
124
- } = details;
125
-
126
- // Find existing credential
112
+ const { authIsValid, ...oauthData } = details;
113
+
127
114
  const existing = await this.prisma.credential.findFirst({ where });
128
115
 
129
116
  if (existing) {
130
- // Update existing - merge OAuth data into existing data JSON
131
117
  const mergedData = { ...(existing.data || {}), ...oauthData };
132
118
 
133
119
  const updated = await this.prisma.credential.update({
134
120
  where: { id: existing.id },
135
121
  data: {
136
- userId: userId || user || existing.userId,
137
- externalId:
138
- externalId !== undefined
139
- ? externalId
140
- : existing.externalId,
141
- authIsValid:
142
- authIsValid !== undefined
143
- ? authIsValid
144
- : existing.authIsValid,
122
+ userId: existing.userId,
123
+ externalId: existing.externalId,
124
+ authIsValid: authIsValid,
145
125
  data: mergedData,
146
126
  },
147
127
  });
@@ -155,13 +135,11 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
155
135
  };
156
136
  }
157
137
 
158
- // Create new credential
159
138
  const created = await this.prisma.credential.create({
160
139
  data: {
161
- userId: userId || user,
162
- externalId,
140
+ userId: identifiers.userId,
141
+ externalId: identifiers.externalId,
163
142
  authIsValid: authIsValid,
164
-
165
143
  data: oauthData,
166
144
  },
167
145
  });
@@ -205,7 +183,6 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
205
183
  authIsValid: credential.authIsValid,
206
184
  access_token: data.access_token,
207
185
  refresh_token: data.refresh_token,
208
- domain: data.domain,
209
186
  ...data,
210
187
  };
211
188
  }
@@ -219,7 +196,6 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
219
196
  * @returns {Promise<Object|null>} Updated credential object or null if not found
220
197
  */
221
198
  async updateCredential(credentialId, updates) {
222
- // Get existing credential to merge OAuth data
223
199
  const existing = await this.prisma.credential.findUnique({
224
200
  where: { id: credentialId },
225
201
  });
@@ -228,27 +204,16 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
228
204
  return null;
229
205
  }
230
206
 
231
- // Separate schema fields from OAuth data
232
- const {
233
- user,
234
- userId,
235
- externalId,
236
- authIsValid,
237
-
238
- ...oauthData
239
- } = updates;
240
-
241
- // Merge OAuth data with existing
207
+ const { authIsValid, ...oauthData } = updates;
208
+
242
209
  const mergedData = { ...(existing.data || {}), ...oauthData };
243
210
 
244
211
  const updated = await this.prisma.credential.update({
245
212
  where: { id: credentialId },
246
213
  data: {
247
- userId: userId || user || existing.userId,
248
- externalId:
249
- externalId !== undefined ? externalId : existing.externalId,
250
- authIsValid:
251
- authIsValid !== undefined ? authIsValid : existing.authIsValid,
214
+ userId: existing.userId,
215
+ externalId: existing.externalId,
216
+ authIsValid: authIsValid,
252
217
  data: mergedData,
253
218
  },
254
219
  });
@@ -262,7 +227,6 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
262
227
  authIsValid: updated.authIsValid,
263
228
  access_token: data.access_token,
264
229
  refresh_token: data.refresh_token,
265
- domain: data.domain,
266
230
  ...data,
267
231
  };
268
232
  }
@@ -278,7 +242,6 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
278
242
 
279
243
  if (identifiers._id) where.id = identifiers._id;
280
244
  if (identifiers.id) where.id = identifiers.id;
281
- if (identifiers.user) where.userId = identifiers.user;
282
245
  if (identifiers.userId) where.userId = identifiers.userId;
283
246
  if (identifiers.externalId) where.externalId = identifiers.externalId;
284
247
 
@@ -296,7 +259,6 @@ class CredentialRepositoryMongo extends CredentialRepositoryInterface {
296
259
 
297
260
  if (filter.credentialId) where.id = filter.credentialId;
298
261
  if (filter.id) where.id = filter.id;
299
- if (filter.user) where.userId = filter.user;
300
262
  if (filter.userId) where.userId = filter.userId;
301
263
  if (filter.externalId) where.externalId = filter.externalId;
302
264
 
@@ -36,7 +36,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
36
36
 
37
37
  /**
38
38
  * Find credential by ID
39
- * Replaces: Credential.findById(id)
40
39
  *
41
40
  * @param {string} id - Credential ID (string from application layer)
42
41
  * @returns {Promise<Object|null>} Credential object with string IDs or null
@@ -51,14 +50,11 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
51
50
  return null;
52
51
  }
53
52
 
54
- // Extract data from JSON field
55
53
  const data = credential.data || {};
56
54
 
57
55
  return {
58
- _id: credential.id.toString(),
59
56
  id: credential.id.toString(),
60
- user: credential.userId?.toString(),
61
- userId: credential.userId?.toString(),
57
+ userId: credential.userId.toString(),
62
58
  externalId: credential.externalId,
63
59
  authIsValid: credential.authIsValid,
64
60
  ...data, // Spread OAuth tokens from JSON field
@@ -67,7 +63,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
67
63
 
68
64
  /**
69
65
  * Update authentication status
70
- * Replaces: Credential.updateOne({ _id: credentialId }, { $set: { authIsValid } })
71
66
  *
72
67
  * @param {string} credentialId - Credential ID (string from application layer)
73
68
  * @param {boolean} authIsValid - Authentication validity status
@@ -85,7 +80,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
85
80
 
86
81
  /**
87
82
  * Permanently remove a credential document
88
- * Replaces: Credential.deleteOne({ _id: credentialId })
89
83
  *
90
84
  * @param {string} credentialId - Credential ID (string from application layer)
91
85
  * @returns {Promise<Object>} Deletion result
@@ -108,7 +102,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
108
102
 
109
103
  /**
110
104
  * Create or update credential matching identifiers
111
- * Replaces: Credential.findOneAndUpdate(query, update, { upsert: true })
112
105
  *
113
106
  * @param {{identifiers: Object, details: Object}} credentialDetails
114
107
  * @returns {Promise<Object>} The persisted credential with string IDs
@@ -118,22 +111,21 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
118
111
  if (!identifiers)
119
112
  throw new Error('identifiers required to upsert credential');
120
113
 
121
- if (!identifiers.user && !identifiers.userId) {
122
- throw new Error('user or userId required in identifiers');
114
+ if (!identifiers.userId) {
115
+ throw new Error('userId required in identifiers');
123
116
  }
124
117
  if (!identifiers.externalId) {
125
118
  throw new Error(
126
119
  'externalId required in identifiers to prevent credential collision. ' +
127
- 'When multiple credentials exist for the same user, both userId and externalId ' +
128
- 'are needed to uniquely identify which credential to update.'
120
+ 'When multiple credentials exist for the same user, both userId and externalId ' +
121
+ 'are needed to uniquely identify which credential to update.'
129
122
  );
130
123
  }
131
124
 
132
125
  const where = this._convertIdentifiersToWhere(identifiers);
133
126
 
134
- const { user, externalId } = identifiers;
127
+ const { externalId } = identifiers;
135
128
 
136
- // Separate schema fields from dynamic OAuth data
137
129
  const { authIsValid, ...oauthData } = details;
138
130
 
139
131
  const existing = await this.prisma.credential.findFirst({ where });
@@ -144,15 +136,9 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
144
136
  const updated = await this.prisma.credential.update({
145
137
  where: { id: existing.id },
146
138
  data: {
147
- userId: this._convertId(user || existing.userId),
148
- externalId:
149
- externalId !== undefined
150
- ? externalId
151
- : existing.externalId,
152
- authIsValid:
153
- authIsValid !== undefined
154
- ? authIsValid
155
- : existing.authIsValid,
139
+ userId: this._convertId(existing.userId),
140
+ externalId: existing.externalId,
141
+ authIsValid: authIsValid,
156
142
  data: mergedData,
157
143
  },
158
144
  });
@@ -168,10 +154,9 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
168
154
 
169
155
  const created = await this.prisma.credential.create({
170
156
  data: {
171
- userId: this._convertId(user),
157
+ userId: this._convertId(identifiers.userId),
172
158
  externalId,
173
159
  authIsValid: authIsValid,
174
-
175
160
  data: oauthData,
176
161
  },
177
162
  });
@@ -187,7 +172,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
187
172
 
188
173
  /**
189
174
  * Find a credential by filter criteria
190
- * Replaces: Credential.findOne(query)
191
175
  *
192
176
  * @param {Object} filter
193
177
  * @param {string} [filter.userId] - User ID (string from application layer)
@@ -215,21 +199,18 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
215
199
  authIsValid: credential.authIsValid,
216
200
  access_token: data.access_token,
217
201
  refresh_token: data.refresh_token,
218
- domain: data.domain,
219
202
  ...data,
220
203
  };
221
204
  }
222
205
 
223
206
  /**
224
207
  * Update a credential by ID
225
- * Replaces: Credential.findByIdAndUpdate(credentialId, { $set: updates })
226
208
  *
227
209
  * @param {string} credentialId - Credential ID (string from application layer)
228
210
  * @param {Object} updates - Fields to update
229
211
  * @returns {Promise<Object|null>} Updated credential object with string IDs or null if not found
230
212
  */
231
213
  async updateCredential(credentialId, updates) {
232
- // Get existing credential to merge OAuth data
233
214
  const intId = this._convertId(credentialId);
234
215
  const existing = await this.prisma.credential.findUnique({
235
216
  where: { id: intId },
@@ -239,21 +220,16 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
239
220
  return null;
240
221
  }
241
222
 
242
- // Separate schema fields from OAuth data
243
- const { user, authIsValid, ...oauthData } =
244
- updates;
223
+ const { authIsValid, ...oauthData } = updates;
245
224
 
246
- // Merge OAuth data with existing
247
225
  const mergedData = { ...(existing.data || {}), ...oauthData };
248
226
 
249
227
  const updated = await this.prisma.credential.update({
250
228
  where: { id: intId },
251
229
  data: {
252
- userId: this._convertId(userId || user || existing.userId),
253
- externalId:
254
- externalId !== undefined ? externalId : existing.externalId,
255
- authIsValid:
256
- authIsValid !== undefined ? authIsValid : existing.authIsValid,
230
+ userId: this._convertId(existing.userId),
231
+ externalId: existing.externalId,
232
+ authIsValid: authIsValid,
257
233
  data: mergedData,
258
234
  },
259
235
  });
@@ -267,7 +243,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
267
243
  authIsValid: updated.authIsValid,
268
244
  access_token: data.access_token,
269
245
  refresh_token: data.refresh_token,
270
- domain: data.domain,
271
246
  ...data,
272
247
  };
273
248
  }
@@ -282,7 +257,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
282
257
  const where = {};
283
258
 
284
259
  if (identifiers.id) where.id = this._convertId(identifiers.id);
285
- if (identifiers.user) where.userId = this._convertId(identifiers.user);
286
260
  if (identifiers.userId)
287
261
  where.userId = this._convertId(identifiers.userId);
288
262
  if (identifiers.externalId) where.externalId = identifiers.externalId;
@@ -302,7 +276,6 @@ class CredentialRepositoryPostgres extends CredentialRepositoryInterface {
302
276
  if (filter.credentialId)
303
277
  where.id = this._convertId(filter.credentialId);
304
278
  if (filter.id) where.id = this._convertId(filter.id);
305
- if (filter.user) where.userId = this._convertId(filter.user);
306
279
  if (filter.userId) where.userId = this._convertId(filter.userId);
307
280
  if (filter.externalId) where.externalId = filter.externalId;
308
281