propro-utils 1.5.64 → 1.5.66
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.
- package/middlewares/account_info.js +239 -103
- package/package.json +1 -1
|
@@ -102,7 +102,10 @@ async function createDefaultFolders(folderSchema, accountId) {
|
|
|
102
102
|
|
|
103
103
|
const debugLog = (area, message, data = null) => {
|
|
104
104
|
const timestamp = new Date().toISOString();
|
|
105
|
-
console.log(
|
|
105
|
+
console.log(
|
|
106
|
+
`[${timestamp}] [${area}] ${message}`,
|
|
107
|
+
data ? JSON.stringify(data, null, 2) : ''
|
|
108
|
+
);
|
|
106
109
|
};
|
|
107
110
|
|
|
108
111
|
const DEFAULT_THEME = {
|
|
@@ -113,142 +116,275 @@ const DEFAULT_THEME = {
|
|
|
113
116
|
name: 'Default Theme',
|
|
114
117
|
};
|
|
115
118
|
|
|
119
|
+
const timeoutPromise = (promise, timeout, name) => {
|
|
120
|
+
return Promise.race([
|
|
121
|
+
promise,
|
|
122
|
+
new Promise((_, reject) =>
|
|
123
|
+
setTimeout(
|
|
124
|
+
() =>
|
|
125
|
+
reject(new Error(`${name} operation timed out after ${timeout}ms`)),
|
|
126
|
+
timeout
|
|
127
|
+
)
|
|
128
|
+
),
|
|
129
|
+
]);
|
|
130
|
+
};
|
|
131
|
+
|
|
116
132
|
const checkIfUserExists = async accountId => {
|
|
133
|
+
const startTime = Date.now();
|
|
117
134
|
try {
|
|
135
|
+
if (!accountId) {
|
|
136
|
+
throw new Error('AccountId is required');
|
|
137
|
+
}
|
|
118
138
|
debugLog('init', `Starting user check for accountId: ${accountId}`);
|
|
119
139
|
|
|
120
|
-
//
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
ServiceManager.getService('UserStyleSchema'),
|
|
125
|
-
ServiceManager.getService('FolderSchema'),
|
|
126
|
-
ServiceManager.getService('Theme'),
|
|
127
|
-
]);
|
|
128
|
-
|
|
129
|
-
debugLog('services', 'All services initialized');
|
|
130
|
-
|
|
131
|
-
// Find user and theme in parallel
|
|
132
|
-
const [user, existingTheme] = await Promise.all([
|
|
133
|
-
userSchema.findOne({ accountId }).populate('userGlobalStyles'),
|
|
134
|
-
Theme.findOne({
|
|
135
|
-
name: 'Default Theme',
|
|
136
|
-
accountId,
|
|
137
|
-
}),
|
|
138
|
-
]);
|
|
139
|
-
|
|
140
|
-
debugLog('query', 'Initial queries complete', {
|
|
141
|
-
userFound: !!user,
|
|
142
|
-
themeFound: !!existingTheme,
|
|
143
|
-
});
|
|
140
|
+
// Initialize services with timeout and individual error handling
|
|
141
|
+
let services;
|
|
142
|
+
try {
|
|
143
|
+
debugLog('services', 'Initializing services...');
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
145
|
+
// Wrap each service request in a proper Promise chain
|
|
146
|
+
const serviceRequests = [
|
|
147
|
+
Promise.resolve(ServiceManager.getService('UserSchema')).then(
|
|
148
|
+
service => service,
|
|
149
|
+
error => {
|
|
150
|
+
throw new Error(`Failed to get UserSchema: ${error.message}`);
|
|
151
|
+
}
|
|
152
|
+
),
|
|
153
|
+
Promise.resolve(ServiceManager.getService('UserStyleSchema')).then(
|
|
154
|
+
service => service,
|
|
155
|
+
error => {
|
|
156
|
+
throw new Error(`Failed to get UserStyleSchema: ${error.message}`);
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
Promise.resolve(ServiceManager.getService('FolderSchema')).then(
|
|
160
|
+
service => service,
|
|
161
|
+
error => {
|
|
162
|
+
throw new Error(`Failed to get FolderSchema: ${error.message}`);
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
Promise.resolve(ServiceManager.getService('Theme')).then(
|
|
166
|
+
service => service,
|
|
167
|
+
error => {
|
|
168
|
+
throw new Error(`Failed to get Theme: ${error.message}`);
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
];
|
|
153
172
|
|
|
154
|
-
|
|
173
|
+
services = await timeoutPromise(
|
|
174
|
+
Promise.all(serviceRequests),
|
|
175
|
+
5000,
|
|
176
|
+
'Service initialization'
|
|
177
|
+
);
|
|
155
178
|
|
|
156
|
-
|
|
157
|
-
|
|
179
|
+
debugLog('services', 'Services initialized successfully', {
|
|
180
|
+
serviceCount: services.length,
|
|
181
|
+
initTime: Date.now() - startTime,
|
|
182
|
+
});
|
|
183
|
+
} catch (error) {
|
|
184
|
+
debugLog('error', 'Service initialization failed', {
|
|
185
|
+
error: error.message,
|
|
186
|
+
});
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
158
189
|
|
|
159
|
-
|
|
190
|
+
const [userSchema, userStyleSchema, folderSchema, Theme] = services;
|
|
160
191
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
192
|
+
// Find user and theme with timeout
|
|
193
|
+
let user, existingTheme;
|
|
194
|
+
try {
|
|
195
|
+
debugLog('query', 'Starting user and theme queries');
|
|
196
|
+
[user, existingTheme] = await timeoutPromise(
|
|
197
|
+
Promise.all([
|
|
198
|
+
userSchema
|
|
199
|
+
.findOne({ accountId })
|
|
200
|
+
.populate('userGlobalStyles')
|
|
201
|
+
.exec()
|
|
202
|
+
.catch(e => {
|
|
203
|
+
throw new Error(`Failed to find user: ${e.message}`);
|
|
204
|
+
}),
|
|
205
|
+
Theme.findOne({
|
|
206
|
+
name: 'Default Theme',
|
|
207
|
+
accountId,
|
|
208
|
+
})
|
|
209
|
+
.exec()
|
|
210
|
+
.catch(e => {
|
|
211
|
+
throw new Error(`Failed to find theme: ${e.message}`);
|
|
212
|
+
}),
|
|
213
|
+
]),
|
|
214
|
+
5000,
|
|
215
|
+
'Initial queries'
|
|
216
|
+
);
|
|
166
217
|
|
|
167
|
-
|
|
168
|
-
user
|
|
169
|
-
|
|
170
|
-
|
|
218
|
+
debugLog('query', 'Queries completed', {
|
|
219
|
+
userFound: !!user,
|
|
220
|
+
themeFound: !!existingTheme,
|
|
221
|
+
queryTime: Date.now() - startTime,
|
|
222
|
+
});
|
|
223
|
+
} catch (error) {
|
|
224
|
+
debugLog('error', 'Query operations failed', { error: error.message });
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Create or use existing theme
|
|
229
|
+
let defaultTheme;
|
|
230
|
+
try {
|
|
231
|
+
if (!existingTheme) {
|
|
232
|
+
debugLog('theme', 'Creating new theme');
|
|
233
|
+
defaultTheme = await timeoutPromise(
|
|
234
|
+
Theme.create({
|
|
235
|
+
...DEFAULT_THEME,
|
|
236
|
+
id: uuidv4(),
|
|
237
|
+
accountId,
|
|
238
|
+
}),
|
|
239
|
+
5000,
|
|
240
|
+
'Theme creation'
|
|
171
241
|
);
|
|
172
|
-
|
|
173
|
-
} else
|
|
174
|
-
|
|
175
|
-
|
|
242
|
+
debugLog('theme', 'New theme created', { themeId: defaultTheme._id });
|
|
243
|
+
} else {
|
|
244
|
+
defaultTheme = existingTheme;
|
|
245
|
+
debugLog('theme', 'Using existing theme', {
|
|
246
|
+
themeId: defaultTheme._id,
|
|
247
|
+
});
|
|
176
248
|
}
|
|
249
|
+
} catch (error) {
|
|
250
|
+
debugLog('error', 'Theme operation failed', { error: error.message });
|
|
251
|
+
throw error;
|
|
252
|
+
}
|
|
177
253
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
254
|
+
if (user) {
|
|
255
|
+
debugLog('user', 'Processing existing user');
|
|
256
|
+
const updates = [];
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
// Theme update if needed
|
|
260
|
+
if (!user.theme) {
|
|
261
|
+
debugLog('update', 'Adding theme to user');
|
|
262
|
+
user.theme = defaultTheme._id;
|
|
263
|
+
updates.push('theme');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Global styles update if needed
|
|
267
|
+
if (!user.userGlobalStyles) {
|
|
268
|
+
debugLog('update', 'Creating user global styles');
|
|
269
|
+
user.userGlobalStyles = await timeoutPromise(
|
|
270
|
+
createUserGlobalStyles(userStyleSchema, accountId),
|
|
271
|
+
5000,
|
|
272
|
+
'Global styles creation'
|
|
273
|
+
);
|
|
274
|
+
updates.push('userGlobalStyles');
|
|
275
|
+
} else if (user.userGlobalStyles.styleShortcuts.length === 0) {
|
|
276
|
+
debugLog('update', 'Updating empty style shortcuts');
|
|
277
|
+
user.userGlobalStyles.styleShortcuts =
|
|
278
|
+
defaultUserGlobalStyleShortcuts;
|
|
279
|
+
await timeoutPromise(
|
|
280
|
+
user.userGlobalStyles.save(),
|
|
281
|
+
5000,
|
|
282
|
+
'Style shortcuts update'
|
|
283
|
+
);
|
|
284
|
+
}
|
|
187
285
|
|
|
188
|
-
|
|
189
|
-
debugLog(
|
|
190
|
-
|
|
191
|
-
|
|
286
|
+
// Folder checks
|
|
287
|
+
debugLog('folders', 'Checking user folders');
|
|
288
|
+
const userFolders = await timeoutPromise(
|
|
289
|
+
folderSchema.find({ user_id: user.id }, { name: 1 }),
|
|
290
|
+
5000,
|
|
291
|
+
'Folder query'
|
|
192
292
|
);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
user_id: user.id,
|
|
198
|
-
})
|
|
199
|
-
)
|
|
293
|
+
|
|
294
|
+
const userFolderNames = new Set(userFolders.map(f => f.name));
|
|
295
|
+
const foldersToCreate = defaultFolders.filter(
|
|
296
|
+
f => !userFolderNames.has(f.name)
|
|
200
297
|
);
|
|
201
|
-
}
|
|
202
298
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
299
|
+
if (foldersToCreate.length > 0) {
|
|
300
|
+
debugLog('folders', 'Creating missing folders', {
|
|
301
|
+
count: foldersToCreate.length,
|
|
302
|
+
});
|
|
303
|
+
await timeoutPromise(
|
|
304
|
+
Promise.all(
|
|
305
|
+
foldersToCreate.map(folder =>
|
|
306
|
+
folderSchema.create({
|
|
307
|
+
...folder,
|
|
308
|
+
user_id: user.id,
|
|
309
|
+
})
|
|
310
|
+
)
|
|
311
|
+
),
|
|
312
|
+
5000,
|
|
313
|
+
'Folder creation'
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Save user if there were updates
|
|
318
|
+
if (updates.length > 0) {
|
|
319
|
+
debugLog('update', 'Saving user updates', { updates });
|
|
320
|
+
await timeoutPromise(user.save(), 5000, 'User save');
|
|
321
|
+
}
|
|
322
|
+
} catch (error) {
|
|
323
|
+
debugLog('error', 'User update operations failed', {
|
|
324
|
+
error: error.message,
|
|
325
|
+
});
|
|
326
|
+
throw error;
|
|
207
327
|
}
|
|
208
328
|
|
|
209
|
-
debugLog('complete', 'Existing user processed
|
|
329
|
+
debugLog('complete', 'Existing user processed', {
|
|
330
|
+
userId: user.id,
|
|
331
|
+
totalTime: Date.now() - startTime,
|
|
332
|
+
});
|
|
210
333
|
return user;
|
|
211
334
|
}
|
|
212
335
|
|
|
213
|
-
|
|
336
|
+
// Create new user
|
|
337
|
+
try {
|
|
338
|
+
debugLog('create', 'Creating new user');
|
|
339
|
+
const userGlobalStyles = await timeoutPromise(
|
|
340
|
+
createUserGlobalStyles(userStyleSchema, accountId),
|
|
341
|
+
5000,
|
|
342
|
+
'Global styles creation'
|
|
343
|
+
);
|
|
214
344
|
|
|
215
|
-
|
|
216
|
-
const userGlobalStyles = await createUserGlobalStyles(
|
|
217
|
-
userStyleSchema,
|
|
218
|
-
accountId
|
|
219
|
-
);
|
|
345
|
+
const newUserId = uuidv4();
|
|
220
346
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
347
|
+
const [newUser, newFolders] = await timeoutPromise(
|
|
348
|
+
Promise.all([
|
|
349
|
+
userSchema.create({
|
|
350
|
+
accountId,
|
|
351
|
+
id: newUserId,
|
|
352
|
+
verified: false,
|
|
353
|
+
userGlobalStyles: userGlobalStyles._id,
|
|
354
|
+
theme: defaultTheme._id,
|
|
355
|
+
}),
|
|
356
|
+
createDefaultFolders(folderSchema, newUserId),
|
|
357
|
+
]),
|
|
358
|
+
5000,
|
|
359
|
+
'User and folders creation'
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
newUser.folders = newFolders.map(folder => folder._id);
|
|
363
|
+
await timeoutPromise(newUser.save(), 5000, 'New user save');
|
|
364
|
+
|
|
365
|
+
debugLog('complete', 'New user created', {
|
|
366
|
+
userId: newUser.id,
|
|
367
|
+
totalTime: Date.now() - startTime,
|
|
368
|
+
});
|
|
369
|
+
return newUser;
|
|
370
|
+
} catch (error) {
|
|
371
|
+
debugLog('error', 'User creation failed', { error: error.message });
|
|
372
|
+
throw error;
|
|
373
|
+
}
|
|
239
374
|
} catch (error) {
|
|
375
|
+
const totalTime = Date.now() - startTime;
|
|
240
376
|
debugLog('error', 'Operation failed', {
|
|
241
377
|
error: error.message,
|
|
242
378
|
stack: error.stack,
|
|
379
|
+
totalTime,
|
|
243
380
|
});
|
|
244
381
|
|
|
245
|
-
|
|
246
|
-
throw new Error('Failed to get or create user', {
|
|
382
|
+
throw new Error(`Failed to get or create user: ${error.message}`, {
|
|
247
383
|
cause: error,
|
|
248
|
-
accountId,
|
|
249
384
|
});
|
|
250
385
|
}
|
|
251
386
|
};
|
|
387
|
+
|
|
252
388
|
module.exports = {
|
|
253
389
|
getAccountProfile,
|
|
254
390
|
checkIfUserExists,
|