bulltrackers-module 1.0.910 → 1.0.911
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.
|
@@ -22,9 +22,9 @@ function createIdentityMiddleware() {
|
|
|
22
22
|
let targetUserId = null;
|
|
23
23
|
let identitySource = null;
|
|
24
24
|
|
|
25
|
-
// Some routes (billing, computations) must always act as the authenticated
|
|
26
|
-
// should ignore X-Target-User / query overrides.
|
|
27
|
-
//
|
|
25
|
+
// Some routes (billing, computations, workspace) must always act as the authenticated
|
|
26
|
+
// user and should ignore X-Target-User / query overrides. SignedInUsers documents are
|
|
27
|
+
// keyed by CID (eToro internal ID from verification); we resolve to CID when available.
|
|
28
28
|
const path = req.path || '';
|
|
29
29
|
const selfOnly = /^\/(billing|computations|workspace)\b/.test(path);
|
|
30
30
|
|
|
@@ -50,38 +50,44 @@ function createIdentityMiddleware() {
|
|
|
50
50
|
|
|
51
51
|
if (!targetUserId) {
|
|
52
52
|
// No header/query: acting user is the authenticated user.
|
|
53
|
-
//
|
|
54
|
-
if (
|
|
55
|
-
targetUserId = uid;
|
|
56
|
-
identitySource = 'firebase';
|
|
57
|
-
} else if (req.firebaseUser.email) {
|
|
53
|
+
// SignedInUsers is keyed by CID; prefer CID from email lookup when available.
|
|
54
|
+
if (req.firebaseUser.email) {
|
|
58
55
|
try {
|
|
59
56
|
const lookup = await authService.lookupCidByEmail(req.firebaseUser.email);
|
|
60
|
-
if (lookup?.cid) {
|
|
61
|
-
targetUserId = lookup.cid;
|
|
57
|
+
if (lookup?.cid != null) {
|
|
58
|
+
targetUserId = String(lookup.cid);
|
|
62
59
|
identitySource = 'firebase';
|
|
63
60
|
}
|
|
64
61
|
} catch (lookupError) {
|
|
65
62
|
console.warn(`[Identity] Email lookup failed: ${lookupError.message}`);
|
|
66
63
|
}
|
|
67
64
|
}
|
|
65
|
+
if (!targetUserId && uid) {
|
|
66
|
+
targetUserId = uid;
|
|
67
|
+
identitySource = 'firebase';
|
|
68
|
+
}
|
|
68
69
|
} else {
|
|
69
|
-
// Header/query set a target.
|
|
70
|
+
// Header/query set a target. SignedInUsers is keyed by CID; if client sent
|
|
71
|
+
// Firebase UID (e.g. extension only has uid), resolve to CID for same user.
|
|
70
72
|
const targetStr = String(targetUserId);
|
|
71
73
|
const uidStr = uid != null && uid !== '' ? String(uid) : '';
|
|
72
74
|
const targetMatchesUid = uidStr && targetStr === uidStr;
|
|
73
|
-
let
|
|
74
|
-
|
|
75
|
-
if (!targetMatchesUid && req.firebaseUser.email) {
|
|
75
|
+
let myCid = null;
|
|
76
|
+
if (req.firebaseUser.email) {
|
|
76
77
|
try {
|
|
77
78
|
const lookup = await authService.lookupCidByEmail(req.firebaseUser.email);
|
|
78
|
-
if (lookup?.cid != null)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
} catch (lookupError) {
|
|
82
|
-
// ignore; will fall through to developer check
|
|
79
|
+
if (lookup?.cid != null) myCid = String(lookup.cid);
|
|
80
|
+
} catch {
|
|
81
|
+
// ignore
|
|
83
82
|
}
|
|
84
83
|
}
|
|
84
|
+
// If client sent UID and it's me, use my CID for SignedInUsers paths
|
|
85
|
+
if (targetMatchesUid && myCid) {
|
|
86
|
+
targetUserId = myCid;
|
|
87
|
+
identitySource = 'header';
|
|
88
|
+
}
|
|
89
|
+
const targetMatchesMyCid = myCid && targetStr === myCid;
|
|
90
|
+
let targetIsPi = false;
|
|
85
91
|
if (!targetMatchesUid && !targetMatchesMyCid) {
|
|
86
92
|
try {
|
|
87
93
|
targetIsPi = await userDataService.isPopularInvestor(targetStr);
|
|
@@ -178,10 +178,14 @@ async function checkVerificationUserLimit(userId) {
|
|
|
178
178
|
|
|
179
179
|
/**
|
|
180
180
|
* Apply rate limit middleware: use Upstash when configured, otherwise use express-rate-limit.
|
|
181
|
+
* Skip rate limiting in development so the dev server is not impacted by API-V3 limits.
|
|
181
182
|
* @param {Object} app - Express app
|
|
182
183
|
* @param {Function} expressRateLimit - express-rate-limit function
|
|
183
184
|
*/
|
|
184
185
|
function applyRateLimits(app, expressRateLimit) {
|
|
186
|
+
const devBypass = process.env.NODE_ENV === 'development' || process.env.API_RATE_LIMIT_DEV_BYPASS === 'true';
|
|
187
|
+
if (devBypass) return;
|
|
188
|
+
|
|
185
189
|
if (isUpstashEnabled()) {
|
|
186
190
|
app.use('/verification', verificationRateLimit);
|
|
187
191
|
// Apply global API rate limit to all routes EXCEPT /verification to avoid double counting.
|