bulltrackers-module 1.0.435 → 1.0.436

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.
@@ -2465,7 +2465,7 @@ async function getSignedInUserPIPersonalizedMetrics(req, res, dependencies, conf
2465
2465
 
2466
2466
  module.exports = {
2467
2467
  getPiAnalytics,
2468
- getUserRecommendations,
2468
+ getUserRecommendations,
2469
2469
  getWatchlist,
2470
2470
  updateWatchlist,
2471
2471
  autoGenerateWatchlist,
@@ -2481,6 +2481,7 @@ module.exports = {
2481
2481
  checkPisInRankings,
2482
2482
  getPiProfile,
2483
2483
  checkIfUserIsPopularInvestor,
2484
+ checkIfUserIsPI, // Export for use in review_helpers
2484
2485
  trackProfileView,
2485
2486
  getSignedInUserPIPersonalizedMetrics
2486
2487
  };
@@ -16,16 +16,27 @@ const RATE_LIMIT_MS = RATE_LIMIT_HOURS * 60 * 60 * 1000;
16
16
  async function requestPiFetch(req, res, dependencies, config) {
17
17
  const { db, logger, pubsub } = dependencies;
18
18
  const { piCid } = req.params;
19
- const userCid = req.user?.etoroCID || req.query?.userCid;
19
+
20
+ // Get userCid from query (same pattern as other endpoints)
21
+ const userCid = req.query?.userCid;
20
22
 
21
23
  if (!userCid) {
22
- return res.status(401).json({
24
+ return res.status(400).json({
23
25
  success: false,
24
- error: "Authentication required",
25
- message: "You must be signed in to request data fetching"
26
+ error: "Missing userCid",
27
+ message: "Please provide userCid as a query parameter"
26
28
  });
27
29
  }
28
30
 
31
+ // Check for dev override impersonation (same pattern as other endpoints)
32
+ const { getEffectiveCid, getDevOverride } = require('./dev_helpers');
33
+ const effectiveCid = await getEffectiveCid(db, userCid, config, logger);
34
+ const devOverride = await getDevOverride(db, userCid, config, logger);
35
+ const isImpersonating = devOverride && devOverride.impersonateCid && effectiveCid !== Number(userCid);
36
+
37
+ // Use effective CID for the request (impersonated or actual)
38
+ const requestUserCid = Number(effectiveCid);
39
+
29
40
  const piCidNum = Number(piCid);
30
41
  if (isNaN(piCidNum) || piCidNum <= 0) {
31
42
  return res.status(400).json({
@@ -36,8 +47,8 @@ async function requestPiFetch(req, res, dependencies, config) {
36
47
  }
37
48
 
38
49
  try {
39
- // Check rate limits
40
- const rateLimitCheck = await checkRateLimits(db, userCid, piCidNum, logger);
50
+ // Check rate limits (use effective CID)
51
+ const rateLimitCheck = await checkRateLimits(db, requestUserCid, piCidNum, logger);
41
52
 
42
53
  if (!rateLimitCheck.allowed) {
43
54
  return res.status(429).json({
@@ -75,22 +86,24 @@ async function requestPiFetch(req, res, dependencies, config) {
75
86
 
76
87
  await requestRef.set({
77
88
  requestId,
78
- userCid: Number(userCid),
89
+ userCid: requestUserCid, // Use effective CID
90
+ actualUserCid: Number(userCid), // Track actual developer CID for audit
79
91
  piCid: piCidNum,
80
92
  piUsername,
81
93
  status: 'queued',
94
+ isImpersonating: isImpersonating || false,
82
95
  createdAt: FieldValue.serverTimestamp(),
83
96
  updatedAt: FieldValue.serverTimestamp()
84
97
  });
85
98
 
86
- // Update user rate limit
99
+ // Update user rate limit (use effective CID)
87
100
  const userRequestRef = db.collection('pi_fetch_requests')
88
101
  .doc(String(piCidNum))
89
102
  .collection('user_requests')
90
- .doc(String(userCid));
103
+ .doc(String(requestUserCid));
91
104
 
92
105
  await userRequestRef.set({
93
- userCid: Number(userCid),
106
+ userCid: requestUserCid,
94
107
  piCid: piCidNum,
95
108
  lastRequestedAt: FieldValue.serverTimestamp(),
96
109
  requestCount: FieldValue.increment(1),
@@ -106,7 +119,7 @@ async function requestPiFetch(req, res, dependencies, config) {
106
119
  await globalRef.set({
107
120
  piCid: piCidNum,
108
121
  lastRequestedAt: FieldValue.serverTimestamp(),
109
- lastRequestedBy: Number(userCid),
122
+ lastRequestedBy: requestUserCid, // Use effective CID
110
123
  totalRequests: FieldValue.increment(1),
111
124
  updatedAt: FieldValue.serverTimestamp()
112
125
  }, { merge: true });
@@ -122,10 +135,12 @@ async function requestPiFetch(req, res, dependencies, config) {
122
135
  priority: 'high',
123
136
  source: 'on_demand',
124
137
  requestId,
125
- requestedBy: Number(userCid),
138
+ requestedBy: requestUserCid, // Use effective CID
139
+ actualRequestedBy: Number(userCid), // Track actual developer CID
126
140
  metadata: {
127
141
  onDemand: true,
128
- requestedAt: now.toISOString()
142
+ requestedAt: now.toISOString(),
143
+ isImpersonating: isImpersonating || false
129
144
  }
130
145
  };
131
146
 
@@ -139,7 +154,7 @@ async function requestPiFetch(req, res, dependencies, config) {
139
154
  updatedAt: FieldValue.serverTimestamp()
140
155
  });
141
156
 
142
- logger.log('INFO', `[requestPiFetch] User ${userCid} requested fetch for PI ${piCidNum} (${piUsername}). Request ID: ${requestId}`);
157
+ logger.log('INFO', `[requestPiFetch] User ${userCid}${isImpersonating ? ` (impersonating ${requestUserCid})` : ''} requested fetch for PI ${piCidNum} (${piUsername}). Request ID: ${requestId}`);
143
158
 
144
159
  return res.status(200).json({
145
160
  success: true,
@@ -170,7 +185,7 @@ async function requestPiFetch(req, res, dependencies, config) {
170
185
  async function getPiFetchStatus(req, res, dependencies, config) {
171
186
  const { db, logger } = dependencies;
172
187
  const { piCid } = req.params;
173
- const userCid = req.user?.etoroCID || req.query?.userCid;
188
+ const userCid = req.query?.userCid; // Optional - for rate limit info
174
189
 
175
190
  const piCidNum = Number(piCid);
176
191
  if (isNaN(piCidNum) || piCidNum <= 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bulltrackers-module",
3
- "version": "1.0.435",
3
+ "version": "1.0.436",
4
4
  "description": "Helper Functions for Bulltrackers.",
5
5
  "main": "index.js",
6
6
  "files": [