@buoy-gg/impersonate 7.0.40 → 7.0.42

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.
Files changed (81) hide show
  1. package/README.md +12 -76
  2. package/lib/commonjs/impersonate/components/DataNukeSettings.js +8 -675
  3. package/lib/commonjs/impersonate/components/ImpersonateBanner.js +1 -221
  4. package/lib/commonjs/impersonate/components/ImpersonateHistoryList.js +1 -181
  5. package/lib/commonjs/impersonate/components/ImpersonateModal.js +1 -319
  6. package/lib/commonjs/impersonate/components/ImpersonateOverlay.js +1 -26
  7. package/lib/commonjs/impersonate/components/ImpersonateStatusBar.js +1 -130
  8. package/lib/commonjs/impersonate/components/UserAvatar.js +1 -146
  9. package/lib/commonjs/impersonate/components/UserCard.js +1 -201
  10. package/lib/commonjs/impersonate/components/UserSearchView.js +1 -227
  11. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.js +1 -0
  12. package/lib/commonjs/impersonate/hooks/asyncStoragePeer.web.js +1 -0
  13. package/lib/commonjs/impersonate/hooks/useAutoClearAsyncStorage.js +1 -144
  14. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.js +1 -155
  15. package/lib/commonjs/impersonate/hooks/useAutoClearReactQuery.web.js +1 -0
  16. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.js +1 -188
  17. package/lib/commonjs/impersonate/hooks/useAutoClearRedux.web.js +1 -0
  18. package/lib/commonjs/impersonate/hooks/useImpersonate.js +1 -215
  19. package/lib/commonjs/impersonate/hooks/useImpersonateHistory.js +1 -56
  20. package/lib/commonjs/impersonate/types/index.js +1 -16
  21. package/lib/commonjs/impersonate/types/types.js +1 -1
  22. package/lib/commonjs/impersonate/utils/impersonateListener.js +1 -335
  23. package/lib/commonjs/impersonate/utils/impersonateStore.js +1 -675
  24. package/lib/commonjs/index.js +1 -150
  25. package/lib/commonjs/preset.js +1 -232
  26. package/lib/commonjs/sync/impersonateSyncAdapter.js +1 -161
  27. package/lib/module/impersonate/components/DataNukeSettings.js +8 -670
  28. package/lib/module/impersonate/components/ImpersonateBanner.js +1 -215
  29. package/lib/module/impersonate/components/ImpersonateHistoryList.js +1 -176
  30. package/lib/module/impersonate/components/ImpersonateModal.js +1 -314
  31. package/lib/module/impersonate/components/ImpersonateOverlay.js +1 -21
  32. package/lib/module/impersonate/components/ImpersonateStatusBar.js +1 -125
  33. package/lib/module/impersonate/components/UserAvatar.js +1 -140
  34. package/lib/module/impersonate/components/UserCard.js +1 -196
  35. package/lib/module/impersonate/components/UserSearchView.js +1 -222
  36. package/lib/module/impersonate/hooks/asyncStoragePeer.js +1 -0
  37. package/lib/module/impersonate/hooks/asyncStoragePeer.web.js +1 -0
  38. package/lib/module/impersonate/hooks/useAutoClearAsyncStorage.js +1 -140
  39. package/lib/module/impersonate/hooks/useAutoClearReactQuery.js +1 -151
  40. package/lib/module/impersonate/hooks/useAutoClearReactQuery.web.js +1 -0
  41. package/lib/module/impersonate/hooks/useAutoClearRedux.js +1 -183
  42. package/lib/module/impersonate/hooks/useAutoClearRedux.web.js +1 -0
  43. package/lib/module/impersonate/hooks/useImpersonate.js +1 -212
  44. package/lib/module/impersonate/hooks/useImpersonateHistory.js +1 -52
  45. package/lib/module/impersonate/types/index.js +1 -3
  46. package/lib/module/impersonate/types/types.js +1 -1
  47. package/lib/module/impersonate/utils/impersonateListener.js +1 -326
  48. package/lib/module/impersonate/utils/impersonateStore.js +1 -672
  49. package/lib/module/index.js +1 -117
  50. package/lib/module/preset.js +1 -216
  51. package/lib/module/sync/impersonateSyncAdapter.js +1 -153
  52. package/lib/typescript/impersonate/hooks/asyncStoragePeer.d.ts +7 -0
  53. package/lib/typescript/impersonate/hooks/asyncStoragePeer.web.d.ts +2 -0
  54. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts +3 -12
  55. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.web.d.ts +3 -0
  56. package/lib/typescript/impersonate/hooks/useAutoClearRedux.web.d.ts +4 -0
  57. package/lib/typescript/impersonate/types/types.d.ts +6 -0
  58. package/lib/typescript/impersonate/utils/impersonateListener.d.ts +1 -0
  59. package/lib/web/index.mjs +10 -0
  60. package/package.json +32 -10
  61. package/lib/typescript/impersonate/components/DataNukeSettings.d.ts.map +0 -1
  62. package/lib/typescript/impersonate/components/ImpersonateBanner.d.ts.map +0 -1
  63. package/lib/typescript/impersonate/components/ImpersonateHistoryList.d.ts.map +0 -1
  64. package/lib/typescript/impersonate/components/ImpersonateModal.d.ts.map +0 -1
  65. package/lib/typescript/impersonate/components/ImpersonateOverlay.d.ts.map +0 -1
  66. package/lib/typescript/impersonate/components/ImpersonateStatusBar.d.ts.map +0 -1
  67. package/lib/typescript/impersonate/components/UserAvatar.d.ts.map +0 -1
  68. package/lib/typescript/impersonate/components/UserCard.d.ts.map +0 -1
  69. package/lib/typescript/impersonate/components/UserSearchView.d.ts.map +0 -1
  70. package/lib/typescript/impersonate/hooks/useAutoClearAsyncStorage.d.ts.map +0 -1
  71. package/lib/typescript/impersonate/hooks/useAutoClearReactQuery.d.ts.map +0 -1
  72. package/lib/typescript/impersonate/hooks/useAutoClearRedux.d.ts.map +0 -1
  73. package/lib/typescript/impersonate/hooks/useImpersonate.d.ts.map +0 -1
  74. package/lib/typescript/impersonate/hooks/useImpersonateHistory.d.ts.map +0 -1
  75. package/lib/typescript/impersonate/types/index.d.ts.map +0 -1
  76. package/lib/typescript/impersonate/types/types.d.ts.map +0 -1
  77. package/lib/typescript/impersonate/utils/impersonateListener.d.ts.map +0 -1
  78. package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +0 -1
  79. package/lib/typescript/index.d.ts.map +0 -1
  80. package/lib/typescript/preset.d.ts.map +0 -1
  81. package/lib/typescript/sync/impersonateSyncAdapter.d.ts.map +0 -1
@@ -1,335 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.getImpersonatedUserId = getImpersonatedUserId;
7
- exports.impersonateListener = impersonateListener;
8
- exports.isImpersonating = isImpersonating;
9
- exports.setImpersonateConfig = setImpersonateConfig;
10
- exports.startImpersonateListener = startImpersonateListener;
11
- exports.stopImpersonateListener = stopImpersonateListener;
12
- /**
13
- * Impersonate Listener - Header Injection via Fetch/XHR Monkey-Patching
14
- *
15
- * This module intercepts all network requests and injects the impersonation
16
- * header when impersonation is active. It follows the same singleton pattern
17
- * as @buoy-gg/network's networkListener.
18
- */
19
-
20
- // Extended XMLHttpRequest interface for tracking URL
21
-
22
- /**
23
- * Default URL patterns to ignore (won't inject header)
24
- * These are development-related URLs that shouldn't have impersonation
25
- */
26
- const DEFAULT_IGNORE_PATTERNS = [/\/symbolicate$/, /\/logs$/, /\/debugger-proxy/, /\/reload$/, /\/launch-js-devtools/, /localhost:8081/, /100\.64\.\d+\.\d+:8081/,
27
- // iOS simulator Metro
28
- /10\.0\.\d+\.\d+:8081/,
29
- // Android emulator Metro
30
- /\.hot-update\./, /__metro/];
31
-
32
- /**
33
- * Impersonation header injector for network requests
34
- *
35
- * This class monkey-patches fetch and XMLHttpRequest to inject the
36
- * impersonation header on all outgoing requests when impersonation is active.
37
- *
38
- * @example
39
- * ```typescript
40
- * // Get the singleton instance
41
- * const listener = impersonateListener();
42
- *
43
- * // Configure impersonation
44
- * listener.setConfig({
45
- * headerKey: 'x-impersonate-user-id',
46
- * userId: '12345',
47
- * ignorePatterns: [/\/health/]
48
- * });
49
- *
50
- * // Start injecting headers
51
- * listener.startListening();
52
- *
53
- * // All fetch/XHR requests will now include the header
54
- *
55
- * // Stop injecting when done
56
- * listener.stopListening();
57
- * ```
58
- */
59
- /**
60
- * Cooperating-interceptor protocol with @buoy-gg/network: its interceptors
61
- * carry `__buoy*` marker properties, and it re-installs itself whenever the
62
- * marker disappears from the live global (that's how it survives being
63
- * clobbered by Expo/DevTools re-assigning fetch). We wrap its functions, so
64
- * the markers must ride along on our wrappers — otherwise the network tool
65
- * would conclude it lost interception and stack a fresh patch on every check.
66
- */
67
- function carryBuoyMarkers(wrapper, wrapped) {
68
- for (const key of Object.keys(wrapped)) {
69
- if (key.startsWith("__buoy")) {
70
- wrapper[key] = wrapped[key];
71
- }
72
- }
73
- }
74
- class ImpersonateListener {
75
- isListeningFlag = false;
76
-
77
- // Store original methods - MUST be captured before other tools patch
78
-
79
- /**
80
- * The wrappers this instance installed, for identity checks — stopListening
81
- * only restores globals that are still literally ours (see there).
82
- */
83
- patchedFetch = null;
84
- patchedXHROpen = null;
85
- patchedXHRSend = null;
86
- constructor() {
87
- // Initialize with current fetch - will be re-captured in startListening
88
- this.originalFetch = globalThis.fetch.bind(globalThis);
89
- this.originalXHROpen = XMLHttpRequest.prototype.open;
90
- this.originalXHRSend = XMLHttpRequest.prototype.send;
91
- this.config = {
92
- headerKey: "x-impersonate-user-id",
93
- userId: null,
94
- ignorePatterns: [...DEFAULT_IGNORE_PATTERNS]
95
- };
96
- }
97
-
98
- /**
99
- * Update impersonation config without restarting listener
100
- *
101
- * This is the primary way to activate/deactivate impersonation.
102
- * Set userId to null to stop injecting headers.
103
- */
104
- setConfig(partial) {
105
- this.config = {
106
- ...this.config,
107
- ...partial
108
- };
109
-
110
- // Merge ignore patterns if provided
111
- if (partial.ignorePatterns) {
112
- this.config.ignorePatterns = [...DEFAULT_IGNORE_PATTERNS, ...partial.ignorePatterns];
113
- }
114
- }
115
-
116
- /**
117
- * Get current configuration
118
- */
119
- getConfig() {
120
- return {
121
- ...this.config
122
- };
123
- }
124
-
125
- /**
126
- * Check if URL should have header injected
127
- *
128
- * Returns false if:
129
- * - No userId is set (not impersonating)
130
- * - URL matches any ignore pattern
131
- */
132
- shouldInjectHeader(url) {
133
- // Not impersonating
134
- if (!this.config.userId) {
135
- return false;
136
- }
137
-
138
- // Check ignore patterns
139
- return !this.config.ignorePatterns.some(pattern => pattern.test(url));
140
- }
141
-
142
- /**
143
- * Extract URL from various input types
144
- */
145
- extractUrl(input) {
146
- if (typeof input === "string") {
147
- return input;
148
- }
149
- if (input instanceof URL) {
150
- return input.href;
151
- }
152
- // Request object
153
- return input.url;
154
- }
155
-
156
- /**
157
- * Start intercepting and injecting headers
158
- *
159
- * This patches globalThis.fetch and XMLHttpRequest.prototype methods
160
- * to inject the impersonation header on all requests.
161
- */
162
- startListening() {
163
- if (this.isListeningFlag) {
164
- return;
165
- }
166
-
167
- // CRITICAL: Re-capture fetch/XHR NOW, not at construction time
168
- // This ensures we patch OVER any existing interceptors (like @buoy-gg/network)
169
- // so our modifications are visible to them
170
- //
171
- // Keep the UNBOUND functions too: @buoy-gg/network stamps `__buoy*` marker
172
- // properties on its interceptors and re-installs when the marker vanishes
173
- // from the live global — and `.bind()` drops own properties, so the
174
- // markers must be read off the unbound originals and carried forward onto
175
- // our wrappers (see below).
176
- const wrappedFetch = globalThis.fetch;
177
- const wrappedXHROpen = XMLHttpRequest.prototype.open;
178
- const wrappedXHRSend = XMLHttpRequest.prototype.send;
179
- this.originalFetch = wrappedFetch.bind(globalThis);
180
- this.originalXHROpen = wrappedXHROpen;
181
- this.originalXHRSend = wrappedXHRSend;
182
- const self = this;
183
-
184
- // =======================================================================
185
- // PATCH FETCH
186
- // =======================================================================
187
- const patchedFetch = async function (input, init) {
188
- const url = self.extractUrl(input);
189
- if (self.shouldInjectHeader(url)) {
190
- // Create new headers with impersonation header added
191
- const existingHeaders = init?.headers;
192
- const headers = new Headers(existingHeaders);
193
- headers.set(self.config.headerKey, self.config.userId);
194
-
195
- // Call original fetch with modified init
196
- return self.originalFetch(input, {
197
- ...init,
198
- headers
199
- });
200
- }
201
-
202
- // Not injecting - call original fetch as-is
203
- return self.originalFetch(input, init);
204
- };
205
- carryBuoyMarkers(patchedFetch, wrappedFetch);
206
- this.patchedFetch = patchedFetch;
207
- globalThis.fetch = this.patchedFetch;
208
-
209
- // =======================================================================
210
- // PATCH XMLHttpRequest
211
- // =======================================================================
212
-
213
- // Patch open() to store the URL for later use in send()
214
- const patchedOpen = function (method, url, async = true, username, password) {
215
- const xhr = this;
216
- xhr._impersonateUrl = typeof url === "string" ? url : url.href;
217
- const urlStr = typeof url === "string" ? url : url.toString();
218
- return self.originalXHROpen.call(this, method, urlStr, async, username, password);
219
- };
220
-
221
- // Patch send() to inject header before sending
222
- const patchedSend = function (body) {
223
- const xhr = this;
224
- if (xhr._impersonateUrl && self.shouldInjectHeader(xhr._impersonateUrl)) {
225
- // Inject the impersonation header
226
- this.setRequestHeader(self.config.headerKey, self.config.userId);
227
- }
228
- return self.originalXHRSend.call(this, body);
229
- };
230
- carryBuoyMarkers(patchedOpen, wrappedXHROpen);
231
- carryBuoyMarkers(patchedSend, wrappedXHRSend);
232
- this.patchedXHROpen = patchedOpen;
233
- this.patchedXHRSend = patchedSend;
234
- XMLHttpRequest.prototype.open = this.patchedXHROpen;
235
- XMLHttpRequest.prototype.send = this.patchedXHRSend;
236
- this.isListeningFlag = true;
237
- }
238
-
239
- /**
240
- * Stop intercepting - restore original methods
241
- *
242
- * Note: This restores fetch/XHR to their state when ImpersonateListener
243
- * was constructed. If other interceptors were installed after, this may
244
- * break their functionality.
245
- */
246
- stopListening() {
247
- if (!this.isListeningFlag) {
248
- return;
249
- }
250
-
251
- // Restore ONLY what is still literally ours: if another interceptor
252
- // patched after us (the network tool re-asserting itself, a debugger),
253
- // assigning our saved originals would silently wipe its patch. Leaving our
254
- // wrapper in a foreign chain is safe — with no userId configured it is a
255
- // pure pass-through.
256
- if (this.patchedFetch && globalThis.fetch === this.patchedFetch) {
257
- globalThis.fetch = this.originalFetch;
258
- }
259
- if (this.patchedXHROpen && XMLHttpRequest.prototype.open === this.patchedXHROpen) {
260
- XMLHttpRequest.prototype.open = this.originalXHROpen;
261
- }
262
- if (this.patchedXHRSend && XMLHttpRequest.prototype.send === this.patchedXHRSend) {
263
- XMLHttpRequest.prototype.send = this.originalXHRSend;
264
- }
265
- this.patchedFetch = null;
266
- this.patchedXHROpen = null;
267
- this.patchedXHRSend = null;
268
- this.isListeningFlag = false;
269
- }
270
-
271
- /**
272
- * Check if listener is currently active
273
- */
274
- get isListening() {
275
- return this.isListeningFlag;
276
- }
277
-
278
- /**
279
- * Check if impersonation is currently active (has userId set)
280
- */
281
- get isImpersonating() {
282
- return this.config.userId !== null;
283
- }
284
- }
285
-
286
- // =============================================================================
287
- // SINGLETON PATTERN
288
- // =============================================================================
289
-
290
- let _instance = null;
291
-
292
- /**
293
- * Get the singleton ImpersonateListener instance
294
- */
295
- function impersonateListener() {
296
- if (!_instance) {
297
- _instance = new ImpersonateListener();
298
- }
299
- return _instance;
300
- }
301
-
302
- /**
303
- * Convenience function to start the listener
304
- */
305
- function startImpersonateListener() {
306
- impersonateListener().startListening();
307
- }
308
-
309
- /**
310
- * Convenience function to stop the listener
311
- */
312
- function stopImpersonateListener() {
313
- impersonateListener().stopListening();
314
- }
315
-
316
- /**
317
- * Convenience function to update config
318
- */
319
- function setImpersonateConfig(config) {
320
- impersonateListener().setConfig(config);
321
- }
322
-
323
- /**
324
- * Convenience function to check if impersonating
325
- */
326
- function isImpersonating() {
327
- return _instance?.isImpersonating ?? false;
328
- }
329
-
330
- /**
331
- * Convenience function to get impersonated user ID
332
- */
333
- function getImpersonatedUserId() {
334
- return _instance?.getConfig().userId ?? null;
335
- }
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getImpersonatedUserId=getImpersonatedUserId;exports.impersonateListener=impersonateListener;exports.isImpersonating=isImpersonating;exports.setImpersonateConfig=setImpersonateConfig;exports.startImpersonateListener=startImpersonateListener;exports.stopImpersonateListener=stopImpersonateListener;const DEFAULT_IGNORE_PATTERNS=[/\/symbolicate$/,/\/logs$/,/\/debugger-proxy/,/\/reload$/,/\/launch-js-devtools/,/localhost:8081/,/100\.64\.\d+\.\d+:8081/,/10\.0\.\d+\.\d+:8081/,/\.hot-update\./,/__metro/];function carryBuoyMarkers(r,e){for(const s of Object.keys(e)){if(s.startsWith("__buoy")){r[s]=e[s]}}}class ImpersonateListener{isListeningFlag=false;patchedFetch=null;patchedXHROpen=null;patchedXHRSend=null;constructor(){this.originalFetch=globalThis.fetch.bind(globalThis);this.originalXHROpen=XMLHttpRequest.prototype.open;this.originalXHRSend=XMLHttpRequest.prototype.send;this.config={headerKey:"x-impersonate-user-id",userId:null,ignorePatterns:[...DEFAULT_IGNORE_PATTERNS]}}setConfig(e){this.config={...this.config,...e};if(e.ignorePatterns){this.config.ignorePatterns=[...DEFAULT_IGNORE_PATTERNS,...e.ignorePatterns]}}getConfig(){return{...this.config}}shouldInjectHeader(e){if(!this.config.userId){return false}if(this.config.gate&&!this.config.gate()){return false}return!this.config.ignorePatterns.some(s=>s.test(e))}extractUrl(e){if(typeof e==="string"){return e}if(e instanceof URL){return e.href}return e.url}startListening(){if(this.isListeningFlag){return}const e=globalThis.fetch;const s=XMLHttpRequest.prototype.open;const c=XMLHttpRequest.prototype.send;this.originalFetch=e.bind(globalThis);this.originalXHROpen=s;this.originalXHRSend=c;const n=this;const p=async function(i,t){const a=n.extractUrl(i);if(n.shouldInjectHeader(a)){const h=t?.headers??(typeof i==="object"&&"headers"in i?i.headers:void 0);const o=new Headers(h);o.set(n.config.headerKey,n.config.userId);return n.originalFetch(i,{...t,headers:o})}return n.originalFetch(i,t)};carryBuoyMarkers(p,e);this.patchedFetch=p;globalThis.fetch=this.patchedFetch;const d=function(i,t,a=true,h,o){const u=this;u._impersonateUrl=typeof t==="string"?t:t.href;const H=typeof t==="string"?t:t.toString();return n.originalXHROpen.call(this,i,H,a,h,o)};const g=function(i){const t=this;if(t._impersonateUrl&&n.shouldInjectHeader(t._impersonateUrl)){this.setRequestHeader(n.config.headerKey,n.config.userId)}return n.originalXHRSend.call(this,i)};carryBuoyMarkers(d,s);carryBuoyMarkers(g,c);this.patchedXHROpen=d;this.patchedXHRSend=g;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;const f=globalThis;const l=f.__buoyHeaderInjectors??=[];if(!l.includes(this.reportHeader))l.push(this.reportHeader);this.isListeningFlag=true}reportHeader=e=>this.shouldInjectHeader(e)?{[this.config.headerKey]:this.config.userId}:null;stopListening(){if(!this.isListeningFlag){return}if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;const e=globalThis.__buoyHeaderInjectors;const s=e?.indexOf(this.reportHeader)??-1;if(e&&s>=0)e.splice(s,1);this.isListeningFlag=false}get isListening(){return this.isListeningFlag}get isImpersonating(){return this.config.userId!==null&&(this.config.gate?.()??true)}}let _instance=null;function impersonateListener(){if(!_instance){_instance=new ImpersonateListener}return _instance}function startImpersonateListener(){impersonateListener().startListening()}function stopImpersonateListener(){impersonateListener().stopListening()}function setImpersonateConfig(r){impersonateListener().setConfig(r)}function isImpersonating(){return _instance?.isImpersonating??false}function getImpersonatedUserId(){return _instance?.getConfig().userId??null}