bulltrackers-module 1.0.592 → 1.0.593
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/functions/old-generic-api/admin-api/index.js +895 -0
- package/functions/old-generic-api/helpers/api_helpers.js +457 -0
- package/functions/old-generic-api/index.js +204 -0
- package/functions/old-generic-api/user-api/helpers/alerts/alert_helpers.js +355 -0
- package/functions/old-generic-api/user-api/helpers/alerts/subscription_helpers.js +327 -0
- package/functions/old-generic-api/user-api/helpers/alerts/test_alert_helpers.js +212 -0
- package/functions/old-generic-api/user-api/helpers/collection_helpers.js +193 -0
- package/functions/old-generic-api/user-api/helpers/core/compression_helpers.js +68 -0
- package/functions/old-generic-api/user-api/helpers/core/data_lookup_helpers.js +256 -0
- package/functions/old-generic-api/user-api/helpers/core/path_resolution_helpers.js +640 -0
- package/functions/old-generic-api/user-api/helpers/core/user_status_helpers.js +195 -0
- package/functions/old-generic-api/user-api/helpers/data/computation_helpers.js +503 -0
- package/functions/old-generic-api/user-api/helpers/data/instrument_helpers.js +55 -0
- package/functions/old-generic-api/user-api/helpers/data/portfolio_helpers.js +245 -0
- package/functions/old-generic-api/user-api/helpers/data/social_helpers.js +174 -0
- package/functions/old-generic-api/user-api/helpers/data_helpers.js +87 -0
- package/functions/old-generic-api/user-api/helpers/dev/dev_helpers.js +336 -0
- package/functions/old-generic-api/user-api/helpers/fetch/on_demand_fetch_helpers.js +615 -0
- package/functions/old-generic-api/user-api/helpers/metrics/personalized_metrics_helpers.js +231 -0
- package/functions/old-generic-api/user-api/helpers/notifications/notification_helpers.js +641 -0
- package/functions/old-generic-api/user-api/helpers/profile/pi_profile_helpers.js +182 -0
- package/functions/old-generic-api/user-api/helpers/profile/profile_view_helpers.js +137 -0
- package/functions/old-generic-api/user-api/helpers/profile/user_profile_helpers.js +190 -0
- package/functions/old-generic-api/user-api/helpers/recommendations/recommendation_helpers.js +66 -0
- package/functions/old-generic-api/user-api/helpers/reviews/review_helpers.js +550 -0
- package/functions/old-generic-api/user-api/helpers/rootdata/rootdata_aggregation_helpers.js +378 -0
- package/functions/old-generic-api/user-api/helpers/search/pi_request_helpers.js +295 -0
- package/functions/old-generic-api/user-api/helpers/search/pi_search_helpers.js +162 -0
- package/functions/old-generic-api/user-api/helpers/sync/user_sync_helpers.js +677 -0
- package/functions/old-generic-api/user-api/helpers/verification/verification_helpers.js +323 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_analytics_helpers.js +96 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_data_helpers.js +141 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_generation_helpers.js +310 -0
- package/functions/old-generic-api/user-api/helpers/watchlist/watchlist_management_helpers.js +829 -0
- package/functions/old-generic-api/user-api/index.js +109 -0
- package/package.json +2 -2
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Developer Mode Helpers
|
|
3
|
+
* Allows specific developer accounts to override copied PI data for testing
|
|
4
|
+
* SECURITY: Only works for whitelisted developer CIDs
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { FieldValue } = require('@google-cloud/firestore');
|
|
8
|
+
|
|
9
|
+
// Whitelist of developer account CIDs that can use dev mode
|
|
10
|
+
const DEVELOPER_CIDS = [
|
|
11
|
+
29312236 // Aiden Hawkins - marau2021
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if a user CID is a developer account
|
|
16
|
+
*/
|
|
17
|
+
function isDeveloperAccount(userCid) {
|
|
18
|
+
return DEVELOPER_CIDS.includes(Number(userCid));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get developer override data for a user
|
|
23
|
+
* Auto-creates default document if it doesn't exist (for developer accounts only)
|
|
24
|
+
* Returns null if not a developerg,
|
|
25
|
+
*/
|
|
26
|
+
async function getDevOverride(db, userCid, config, logger = null) {
|
|
27
|
+
if (!isDeveloperAccount(userCid)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const devOverridesCollection = config.devOverridesCollection || 'dev_overrides';
|
|
33
|
+
const overrideRef = db.collection(devOverridesCollection).doc(String(userCid));
|
|
34
|
+
const overrideDoc = await overrideRef.get();
|
|
35
|
+
|
|
36
|
+
// Auto-create default document if it doesn't exist
|
|
37
|
+
if (!overrideDoc.exists) {
|
|
38
|
+
const defaultData = {
|
|
39
|
+
userCid: Number(userCid),
|
|
40
|
+
enabled: false,
|
|
41
|
+
fakeCopiedPIs: [],
|
|
42
|
+
pretendToBePI: false,
|
|
43
|
+
impersonateCid: null, // CID to impersonate/view as
|
|
44
|
+
pretendSubscribedToAllAlerts: false, // Pretend to be subscribed to all alert types for all PIs
|
|
45
|
+
createdAt: FieldValue.serverTimestamp(),
|
|
46
|
+
lastUpdated: FieldValue.serverTimestamp()
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
await overrideRef.set(defaultData);
|
|
50
|
+
|
|
51
|
+
const logMsg = `[getDevOverride] Auto-created default dev override document for developer account ${userCid}`;
|
|
52
|
+
if (logger && logger.log) {
|
|
53
|
+
logger.log('INFO', logMsg);
|
|
54
|
+
} else {
|
|
55
|
+
console.log(logMsg);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Return the default (disabled) override
|
|
59
|
+
return {
|
|
60
|
+
enabled: false,
|
|
61
|
+
fakeCopiedPIs: [],
|
|
62
|
+
pretendToBePI: false,
|
|
63
|
+
impersonateCid: null,
|
|
64
|
+
pretendSubscribedToAllAlerts: false,
|
|
65
|
+
lastUpdated: null,
|
|
66
|
+
wasAutoCreated: true
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const data = overrideDoc.data();
|
|
71
|
+
|
|
72
|
+
// Return override data (even if disabled, so caller knows it exists)
|
|
73
|
+
return {
|
|
74
|
+
enabled: data.enabled === true,
|
|
75
|
+
fakeCopiedPIs: data.fakeCopiedPIs || [],
|
|
76
|
+
pretendToBePI: data.pretendToBePI === true,
|
|
77
|
+
impersonateCid: data.impersonateCid ? Number(data.impersonateCid) : null,
|
|
78
|
+
pretendSubscribedToAllAlerts: data.pretendSubscribedToAllAlerts === true,
|
|
79
|
+
lastUpdated: data.lastUpdated,
|
|
80
|
+
wasAutoCreated: false
|
|
81
|
+
};
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('[getDevOverride] Error fetching/creating dev override:', error);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get the list of copied PIs for a user, with dev override support
|
|
90
|
+
* Returns { copiedPIs: Array, isDevOverride: boolean, dataSource: string }
|
|
91
|
+
*/
|
|
92
|
+
async function getCopiedPIsWithDevOverride(db, userCid, config, logger) {
|
|
93
|
+
const userCidNum = Number(userCid);
|
|
94
|
+
|
|
95
|
+
// Check for dev override first (this will auto-create default if needed)
|
|
96
|
+
const devOverride = await getDevOverride(db, userCid, config, logger);
|
|
97
|
+
|
|
98
|
+
if (devOverride && devOverride.enabled && devOverride.fakeCopiedPIs.length > 0) {
|
|
99
|
+
if (logger && logger.log) {
|
|
100
|
+
logger.log('INFO', `[getCopiedPIsWithDevOverride] Using DEV OVERRIDE for user ${userCid}: ${devOverride.fakeCopiedPIs.length} fake copied PIs`);
|
|
101
|
+
} else {
|
|
102
|
+
console.log(`[getCopiedPIsWithDevOverride] Using DEV OVERRIDE for user ${userCid}: ${devOverride.fakeCopiedPIs.length} fake copied PIs`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
copiedPIs: devOverride.fakeCopiedPIs.map(cid => ({
|
|
107
|
+
cid: Number(cid),
|
|
108
|
+
username: 'Dev Override' // Will be resolved from rankings later
|
|
109
|
+
})),
|
|
110
|
+
isDevOverride: true,
|
|
111
|
+
dataSource: 'dev_override'
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Otherwise, use normal logic (computation or portfolio)
|
|
116
|
+
// This will be handled by the calling function
|
|
117
|
+
return {
|
|
118
|
+
copiedPIs: [],
|
|
119
|
+
isDevOverride: false,
|
|
120
|
+
dataSource: 'normal'
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Check if a user has copied a specific PI, with dev override support
|
|
126
|
+
*/
|
|
127
|
+
async function hasUserCopiedWithDevOverride(db, userCid, piCid, config, logger) {
|
|
128
|
+
const userCidNum = Number(userCid);
|
|
129
|
+
const piCidNum = Number(piCid);
|
|
130
|
+
|
|
131
|
+
// Check for dev override first (this will auto-create default if needed)
|
|
132
|
+
const devOverride = await getDevOverride(db, userCid, config, logger);
|
|
133
|
+
|
|
134
|
+
if (devOverride && devOverride.enabled) {
|
|
135
|
+
const hasCopied = devOverride.fakeCopiedPIs.includes(piCidNum);
|
|
136
|
+
if (hasCopied) {
|
|
137
|
+
if (logger && logger.log) {
|
|
138
|
+
logger.log('INFO', `[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} "copies" PI ${piCid}`);
|
|
139
|
+
} else {
|
|
140
|
+
console.log(`[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} "copies" PI ${piCid}`);
|
|
141
|
+
}
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
// If dev override is enabled but PI not in list, return false (don't check real data)
|
|
145
|
+
if (logger && logger.log) {
|
|
146
|
+
logger.log('INFO', `[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} does NOT "copy" PI ${piCid} (override enabled, PI not in fake list)`);
|
|
147
|
+
} else {
|
|
148
|
+
console.log(`[hasUserCopiedWithDevOverride] DEV OVERRIDE: User ${userCid} does NOT "copy" PI ${piCid} (override enabled, PI not in fake list)`);
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Otherwise, use normal logic (will be handled by calling function)
|
|
154
|
+
return null; // null means "not a dev override, use normal logic"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Create or update dev override for a developer account
|
|
159
|
+
* SECURITY: Only works for whitelisted developer CIDs
|
|
160
|
+
*/
|
|
161
|
+
async function setDevOverride(req, res, dependencies, config) {
|
|
162
|
+
const { db, logger } = dependencies;
|
|
163
|
+
const { userCid, enabled, fakeCopiedPIs, pretendToBePI, impersonateCid, pretendSubscribedToAllAlerts } = req.body;
|
|
164
|
+
|
|
165
|
+
if (!userCid) {
|
|
166
|
+
return res.status(400).json({ error: "Missing userCid" });
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// SECURITY CHECK: Only allow whitelisted developer accounts
|
|
170
|
+
if (!isDeveloperAccount(userCid)) {
|
|
171
|
+
logger.log('WARN', `[setDevOverride] Unauthorized attempt to set dev override for user ${userCid}`);
|
|
172
|
+
return res.status(403).json({
|
|
173
|
+
error: "Forbidden",
|
|
174
|
+
message: "Developer mode is only available for authorized developer accounts"
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Validate fakeCopiedPIs (only required if enabled is true)
|
|
179
|
+
if (enabled && (!Array.isArray(fakeCopiedPIs) || fakeCopiedPIs.length === 0)) {
|
|
180
|
+
return res.status(400).json({
|
|
181
|
+
error: "Invalid request",
|
|
182
|
+
message: "When enabled, fakeCopiedPIs must be a non-empty array"
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Validate impersonateCid if provided
|
|
187
|
+
if (impersonateCid !== undefined && impersonateCid !== null) {
|
|
188
|
+
const parsedCid = Number(impersonateCid);
|
|
189
|
+
if (isNaN(parsedCid) || parsedCid <= 0) {
|
|
190
|
+
return res.status(400).json({
|
|
191
|
+
error: "Invalid request",
|
|
192
|
+
message: "impersonateCid must be a positive number, or null to disable impersonation"
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Ensure all CIDs are numbers
|
|
198
|
+
const validatedPIs = enabled ? fakeCopiedPIs.map(cid => Number(cid)).filter(cid => !isNaN(cid) && cid > 0) : [];
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
const devOverridesCollection = config.devOverridesCollection || 'dev_overrides';
|
|
202
|
+
const overrideRef = db.collection(devOverridesCollection).doc(String(userCid));
|
|
203
|
+
|
|
204
|
+
// Get existing override to preserve values not being updated
|
|
205
|
+
const existingDoc = await overrideRef.get();
|
|
206
|
+
const existingData = existingDoc.exists ? existingDoc.data() : {};
|
|
207
|
+
|
|
208
|
+
const overrideData = {
|
|
209
|
+
userCid: Number(userCid),
|
|
210
|
+
enabled: enabled !== undefined ? (enabled === true) : (existingData.enabled || false),
|
|
211
|
+
fakeCopiedPIs: enabled !== undefined ? validatedPIs : (existingData.fakeCopiedPIs || []),
|
|
212
|
+
pretendToBePI: pretendToBePI !== undefined ? (pretendToBePI === true) : (existingData.pretendToBePI || false),
|
|
213
|
+
impersonateCid: impersonateCid !== undefined ? (impersonateCid ? Number(impersonateCid) : null) : (existingData.impersonateCid || null),
|
|
214
|
+
pretendSubscribedToAllAlerts: pretendSubscribedToAllAlerts !== undefined ? (pretendSubscribedToAllAlerts === true) : (existingData.pretendSubscribedToAllAlerts || false),
|
|
215
|
+
lastUpdated: FieldValue.serverTimestamp()
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
await overrideRef.set(overrideData, { merge: true });
|
|
219
|
+
|
|
220
|
+
const logParts = [
|
|
221
|
+
`enabled=${overrideData.enabled}`,
|
|
222
|
+
`pretendToBePI=${overrideData.pretendToBePI}`,
|
|
223
|
+
`impersonateCid=${overrideData.impersonateCid || 'null'}`,
|
|
224
|
+
`pretendSubscribedToAllAlerts=${overrideData.pretendSubscribedToAllAlerts}`,
|
|
225
|
+
`${validatedPIs.length} fake PIs`
|
|
226
|
+
];
|
|
227
|
+
logger.log('SUCCESS', `[setDevOverride] Updated dev override for user ${userCid}: ${logParts.join(', ')}`);
|
|
228
|
+
|
|
229
|
+
return res.status(200).json({
|
|
230
|
+
success: true,
|
|
231
|
+
message: "Developer override updated",
|
|
232
|
+
override: overrideData
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
} catch (error) {
|
|
236
|
+
logger.log('ERROR', `[setDevOverride] Error updating dev override:`, error);
|
|
237
|
+
return res.status(500).json({ error: error.message });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Get current dev override status for a developer account
|
|
243
|
+
*/
|
|
244
|
+
async function getDevOverrideStatus(req, res, dependencies, config) {
|
|
245
|
+
const { db, logger } = dependencies;
|
|
246
|
+
const { userCid } = req.query;
|
|
247
|
+
|
|
248
|
+
if (!userCid) {
|
|
249
|
+
return res.status(400).json({ error: "Missing userCid" });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// SECURITY CHECK: Only allow whitelisted developer accounts
|
|
253
|
+
if (!isDeveloperAccount(userCid)) {
|
|
254
|
+
return res.status(403).json({
|
|
255
|
+
error: "Forbidden",
|
|
256
|
+
message: "Developer mode is only available for authorized developer accounts"
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
// This will auto-create default document if it doesn't exist
|
|
262
|
+
const devOverride = await getDevOverride(db, userCid, config, logger);
|
|
263
|
+
|
|
264
|
+
if (!devOverride) {
|
|
265
|
+
// Should not happen for developer accounts, but handle gracefully
|
|
266
|
+
return res.status(200).json({
|
|
267
|
+
enabled: false,
|
|
268
|
+
fakeCopiedPIs: [],
|
|
269
|
+
message: "No dev override configured"
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return res.status(200).json({
|
|
274
|
+
enabled: devOverride.enabled,
|
|
275
|
+
fakeCopiedPIs: devOverride.fakeCopiedPIs,
|
|
276
|
+
pretendToBePI: devOverride.pretendToBePI || false,
|
|
277
|
+
impersonateCid: devOverride.impersonateCid || null,
|
|
278
|
+
pretendSubscribedToAllAlerts: devOverride.pretendSubscribedToAllAlerts || false,
|
|
279
|
+
lastUpdated: devOverride.lastUpdated,
|
|
280
|
+
wasAutoCreated: devOverride.wasAutoCreated || false
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
} catch (error) {
|
|
284
|
+
logger.log('ERROR', `[getDevOverrideStatus] Error fetching dev override:`, error);
|
|
285
|
+
return res.status(500).json({ error: error.message });
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Get the effective CID to use for a developer account
|
|
291
|
+
* Returns impersonateCid if set, otherwise returns the actual userCid
|
|
292
|
+
* Only works for developer accounts
|
|
293
|
+
*
|
|
294
|
+
* Note: If pretendToBePI is false, impersonation will not be used for PI-related checks
|
|
295
|
+
* to prevent unintended impersonation when the user doesn't want to pretend to be a PI
|
|
296
|
+
*/
|
|
297
|
+
async function getEffectiveCid(db, userCid, config, logger = null) {
|
|
298
|
+
if (!isDeveloperAccount(userCid)) {
|
|
299
|
+
return Number(userCid); // Not a developer, return actual CID
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const devOverride = await getDevOverride(db, userCid, config, logger);
|
|
303
|
+
// Only use impersonation if dev override is enabled AND impersonateCid is set
|
|
304
|
+
// BUT: If pretendToBePI is explicitly false, don't use impersonation (user doesn't want to be treated as PI)
|
|
305
|
+
if (devOverride && devOverride.enabled && devOverride.impersonateCid) {
|
|
306
|
+
// Check if user explicitly doesn't want to pretend to be a PI
|
|
307
|
+
// If pretendToBePI is false, don't use impersonation (respects user intent)
|
|
308
|
+
if (devOverride.pretendToBePI === false) {
|
|
309
|
+
if (logger && logger.log) {
|
|
310
|
+
logger.log('INFO', `[getEffectiveCid] DEV OVERRIDE: User ${userCid} has impersonateCid set but pretendToBePI=false, using actual CID ${userCid} instead`);
|
|
311
|
+
} else {
|
|
312
|
+
console.log(`[getEffectiveCid] DEV OVERRIDE: User ${userCid} has impersonateCid set but pretendToBePI=false, using actual CID ${userCid} instead`);
|
|
313
|
+
}
|
|
314
|
+
return Number(userCid);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (logger && logger.log) {
|
|
318
|
+
logger.log('INFO', `[getEffectiveCid] DEV OVERRIDE: User ${userCid} impersonating CID ${devOverride.impersonateCid}`);
|
|
319
|
+
} else {
|
|
320
|
+
console.log(`[getEffectiveCid] DEV OVERRIDE: User ${userCid} impersonating CID ${devOverride.impersonateCid}`);
|
|
321
|
+
}
|
|
322
|
+
return Number(devOverride.impersonateCid);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return Number(userCid);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
module.exports = {
|
|
329
|
+
isDeveloperAccount,
|
|
330
|
+
getDevOverride,
|
|
331
|
+
getCopiedPIsWithDevOverride,
|
|
332
|
+
hasUserCopiedWithDevOverride,
|
|
333
|
+
setDevOverride,
|
|
334
|
+
getDevOverrideStatus,
|
|
335
|
+
getEffectiveCid
|
|
336
|
+
};
|