@buoy-gg/impersonate 3.0.1 → 4.0.1
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/lib/commonjs/impersonate/utils/impersonateStore.js +60 -0
- package/lib/commonjs/index.js +19 -0
- package/lib/commonjs/preset.js +7 -0
- package/lib/commonjs/sync/impersonateSyncAdapter.js +68 -0
- package/lib/module/impersonate/utils/impersonateStore.js +60 -0
- package/lib/module/index.js +7 -1
- package/lib/module/preset.js +7 -1
- package/lib/module/sync/impersonateSyncAdapter.js +62 -0
- package/lib/typescript/impersonate/utils/impersonateStore.d.ts +14 -0
- package/lib/typescript/impersonate/utils/impersonateStore.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/preset.d.ts +9 -0
- package/lib/typescript/preset.d.ts.map +1 -1
- package/lib/typescript/sync/impersonateSyncAdapter.d.ts +59 -0
- package/lib/typescript/sync/impersonateSyncAdapter.d.ts.map +1 -0
- package/package.json +2 -2
|
@@ -310,6 +310,32 @@ class ImpersonateStore {
|
|
|
310
310
|
return () => this.listeners.delete(listener);
|
|
311
311
|
};
|
|
312
312
|
|
|
313
|
+
// ===========================================================================
|
|
314
|
+
// REMOTE MIRROR MODE
|
|
315
|
+
// ===========================================================================
|
|
316
|
+
|
|
317
|
+
remoteHandler = null;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Remote mirror mode (desktop dashboard): while a handler is set, every
|
|
321
|
+
* mutation forwards (method, params) to the synced device instead of
|
|
322
|
+
* running locally — header patching, data nuking and persistence all
|
|
323
|
+
* happen on the device, and the resulting state comes back via
|
|
324
|
+
* replaceState(). Pass null to restore local behavior.
|
|
325
|
+
*/
|
|
326
|
+
setRemoteHandler(handler) {
|
|
327
|
+
this.remoteHandler = handler;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Replace the mirrored state from a synced device snapshot. Does not
|
|
332
|
+
* persist or touch the fetch listener — the device owns both.
|
|
333
|
+
*/
|
|
334
|
+
replaceState(state) {
|
|
335
|
+
this.state = state;
|
|
336
|
+
this.notify();
|
|
337
|
+
}
|
|
338
|
+
|
|
313
339
|
// ===========================================================================
|
|
314
340
|
// IMPERSONATION ACTIONS
|
|
315
341
|
// ===========================================================================
|
|
@@ -324,6 +350,12 @@ class ImpersonateStore {
|
|
|
324
350
|
* the visual symptom of "I clicked a user and nothing changed."
|
|
325
351
|
*/
|
|
326
352
|
async startImpersonation(user) {
|
|
353
|
+
if (this.remoteHandler) {
|
|
354
|
+
this.remoteHandler("startImpersonation", {
|
|
355
|
+
user
|
|
356
|
+
});
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
327
359
|
const historyEntry = {
|
|
328
360
|
user,
|
|
329
361
|
lastUsedAt: new Date().toISOString()
|
|
@@ -358,6 +390,10 @@ class ImpersonateStore {
|
|
|
358
390
|
* before nuking caches so subsequent refetches go out without the header.
|
|
359
391
|
*/
|
|
360
392
|
async stopImpersonation() {
|
|
393
|
+
if (this.remoteHandler) {
|
|
394
|
+
this.remoteHandler("stopImpersonation");
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
361
397
|
// eslint-disable-next-line no-console
|
|
362
398
|
console.log(`[impersonate] stopImpersonation: isActive ${this.state.isActive} -> false, listeners=${this.listeners.size}`);
|
|
363
399
|
this.state = {
|
|
@@ -376,6 +412,10 @@ class ImpersonateStore {
|
|
|
376
412
|
* Pause impersonation (temporarily stop injecting headers)
|
|
377
413
|
*/
|
|
378
414
|
async pauseImpersonation() {
|
|
415
|
+
if (this.remoteHandler) {
|
|
416
|
+
this.remoteHandler("pauseImpersonation");
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
379
419
|
if (!this.state.isActive || this.state.isPaused) return;
|
|
380
420
|
this.state = {
|
|
381
421
|
...this.state,
|
|
@@ -396,6 +436,10 @@ class ImpersonateStore {
|
|
|
396
436
|
* Resume impersonation (start injecting headers again)
|
|
397
437
|
*/
|
|
398
438
|
async resumeImpersonation() {
|
|
439
|
+
if (this.remoteHandler) {
|
|
440
|
+
this.remoteHandler("resumeImpersonation");
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
399
443
|
if (!this.state.isActive || !this.state.isPaused) return;
|
|
400
444
|
this.state = {
|
|
401
445
|
...this.state,
|
|
@@ -427,6 +471,12 @@ class ImpersonateStore {
|
|
|
427
471
|
* Update settings (header key, ignore patterns, data nuke settings, show banner)
|
|
428
472
|
*/
|
|
429
473
|
async updateSettings(settings) {
|
|
474
|
+
if (this.remoteHandler) {
|
|
475
|
+
this.remoteHandler("updateSettings", {
|
|
476
|
+
settings
|
|
477
|
+
});
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
430
480
|
this.state = {
|
|
431
481
|
...this.state,
|
|
432
482
|
headerKey: settings.headerKey ?? this.state.headerKey,
|
|
@@ -454,6 +504,12 @@ class ImpersonateStore {
|
|
|
454
504
|
* Remove a user from history
|
|
455
505
|
*/
|
|
456
506
|
async removeFromHistory(userId) {
|
|
507
|
+
if (this.remoteHandler) {
|
|
508
|
+
this.remoteHandler("removeFromHistory", {
|
|
509
|
+
userId
|
|
510
|
+
});
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
457
513
|
this.state = {
|
|
458
514
|
...this.state,
|
|
459
515
|
history: this.state.history.filter(entry => entry.user.id !== userId)
|
|
@@ -466,6 +522,10 @@ class ImpersonateStore {
|
|
|
466
522
|
* Clear all history
|
|
467
523
|
*/
|
|
468
524
|
async clearHistory() {
|
|
525
|
+
if (this.remoteHandler) {
|
|
526
|
+
this.remoteHandler("clearHistory");
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
469
529
|
this.state = {
|
|
470
530
|
...this.state,
|
|
471
531
|
history: []
|
package/lib/commonjs/index.js
CHANGED
|
@@ -27,6 +27,12 @@ Object.defineProperty(exports, "ImpersonateHistoryList", {
|
|
|
27
27
|
return _ImpersonateHistoryList.ImpersonateHistoryList;
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
|
+
Object.defineProperty(exports, "ImpersonateIcon", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _preset.ImpersonateIcon;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
30
36
|
Object.defineProperty(exports, "ImpersonateModal", {
|
|
31
37
|
enumerable: true,
|
|
32
38
|
get: function () {
|
|
@@ -51,6 +57,12 @@ Object.defineProperty(exports, "UserSearchView", {
|
|
|
51
57
|
return _UserSearchView.UserSearchView;
|
|
52
58
|
}
|
|
53
59
|
});
|
|
60
|
+
Object.defineProperty(exports, "createImpersonateSyncAdapter", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _impersonateSyncAdapter.createImpersonateSyncAdapter;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
54
66
|
Object.defineProperty(exports, "createImpersonateTool", {
|
|
55
67
|
enumerable: true,
|
|
56
68
|
get: function () {
|
|
@@ -75,6 +87,12 @@ Object.defineProperty(exports, "impersonateStore", {
|
|
|
75
87
|
return _impersonateStore.impersonateStore;
|
|
76
88
|
}
|
|
77
89
|
});
|
|
90
|
+
Object.defineProperty(exports, "impersonateSyncAdapter", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _impersonateSyncAdapter.impersonateSyncAdapter;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
78
96
|
Object.defineProperty(exports, "isImpersonating", {
|
|
79
97
|
enumerable: true,
|
|
80
98
|
get: function () {
|
|
@@ -112,6 +130,7 @@ Object.defineProperty(exports, "useImpersonateHistory", {
|
|
|
112
130
|
}
|
|
113
131
|
});
|
|
114
132
|
var _preset = require("./preset");
|
|
133
|
+
var _impersonateSyncAdapter = require("./sync/impersonateSyncAdapter");
|
|
115
134
|
var _ImpersonateModal = require("./impersonate/components/ImpersonateModal");
|
|
116
135
|
var _ImpersonateBanner = require("./impersonate/components/ImpersonateBanner");
|
|
117
136
|
var _ImpersonateOverlay = require("./impersonate/components/ImpersonateOverlay");
|
package/lib/commonjs/preset.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.ImpersonateIcon = ImpersonateIcon;
|
|
6
7
|
exports.createImpersonateTool = createImpersonateTool;
|
|
7
8
|
var _react = _interopRequireDefault(require("react"));
|
|
8
9
|
var _reactNative = require("react-native");
|
|
@@ -10,6 +11,7 @@ var _ImpersonateModal = require("./impersonate/components/ImpersonateModal");
|
|
|
10
11
|
var _ImpersonateBanner = require("./impersonate/components/ImpersonateBanner");
|
|
11
12
|
var _impersonateStore = require("./impersonate/utils/impersonateStore");
|
|
12
13
|
var _impersonateListener = require("./impersonate/utils/impersonateListener");
|
|
14
|
+
var _impersonateSyncAdapter = require("./sync/impersonateSyncAdapter");
|
|
13
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
17
|
/**
|
|
@@ -175,6 +177,11 @@ function createImpersonateTool(config) {
|
|
|
175
177
|
_impersonateStore.impersonateStore.setDeveloperDefaults(defaults);
|
|
176
178
|
}
|
|
177
179
|
|
|
180
|
+
// Make the app's user search available to the zero-config external-sync
|
|
181
|
+
// adapter (FloatingDevTools auto-sync), so the desktop dashboard can proxy
|
|
182
|
+
// searches without separate wiring.
|
|
183
|
+
(0, _impersonateSyncAdapter.registerImpersonateSearchUsers)(onSearchUsers ?? null);
|
|
184
|
+
|
|
178
185
|
// Patch fetch and restore persisted impersonation state up-front. Fire and
|
|
179
186
|
// forget — bootstrapImpersonate guards itself against double-invocation.
|
|
180
187
|
void bootstrapImpersonate();
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createImpersonateSyncAdapter = createImpersonateSyncAdapter;
|
|
7
|
+
exports.impersonateSyncAdapter = void 0;
|
|
8
|
+
exports.registerImpersonateSearchUsers = registerImpersonateSearchUsers;
|
|
9
|
+
var _impersonateStore = require("../impersonate/utils/impersonateStore");
|
|
10
|
+
// Registered by createImpersonateTool, so the zero-config adapter (see
|
|
11
|
+
// FloatingDevTools' auto external sync) can proxy the dashboard's user
|
|
12
|
+
// search without the app wiring anything twice.
|
|
13
|
+
let registeredSearchUsers = null;
|
|
14
|
+
|
|
15
|
+
/** @internal Called by createImpersonateTool with the app's onSearchUsers. */
|
|
16
|
+
function registerImpersonateSearchUsers(handler) {
|
|
17
|
+
registeredSearchUsers = handler;
|
|
18
|
+
}
|
|
19
|
+
function buildActions(onSearchUsers) {
|
|
20
|
+
return {
|
|
21
|
+
searchUsers: params => onSearchUsers(params.query),
|
|
22
|
+
startImpersonation: params => _impersonateStore.impersonateStore.startImpersonation(params.user),
|
|
23
|
+
stopImpersonation: () => _impersonateStore.impersonateStore.stopImpersonation(),
|
|
24
|
+
pauseImpersonation: () => _impersonateStore.impersonateStore.pauseImpersonation(),
|
|
25
|
+
resumeImpersonation: () => _impersonateStore.impersonateStore.resumeImpersonation(),
|
|
26
|
+
updateSettings: params => _impersonateStore.impersonateStore.updateSettings(params.settings),
|
|
27
|
+
removeFromHistory: params => _impersonateStore.impersonateStore.removeFromHistory(params.userId),
|
|
28
|
+
clearHistory: () => _impersonateStore.impersonateStore.clearHistory()
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a sync adapter for the impersonate tool, consumed by
|
|
33
|
+
* @buoy-gg/external-sync's `useExternalSync` (structurally matches its
|
|
34
|
+
* ToolSyncAdapter interface so this package doesn't need a dependency on it).
|
|
35
|
+
*
|
|
36
|
+
* The dashboard mirrors the impersonation state and forwards every mutation
|
|
37
|
+
* back as an action — header patching, data nuking and persistence all run
|
|
38
|
+
* on the device, so impersonating from the desktop behaves exactly like
|
|
39
|
+
* tapping the modal on the phone.
|
|
40
|
+
*/
|
|
41
|
+
function createImpersonateSyncAdapter({
|
|
42
|
+
onSearchUsers
|
|
43
|
+
}) {
|
|
44
|
+
return {
|
|
45
|
+
version: 1,
|
|
46
|
+
getSnapshot: () => _impersonateStore.impersonateStore.getState(),
|
|
47
|
+
subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
|
|
48
|
+
actions: buildActions(onSearchUsers)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Zero-config variant used by FloatingDevTools' auto external sync. User
|
|
54
|
+
* search proxies to the onSearchUsers the app passed to
|
|
55
|
+
* createImpersonateTool; if the tool was never configured, the search action
|
|
56
|
+
* reports a descriptive error to the dashboard.
|
|
57
|
+
*/
|
|
58
|
+
const impersonateSyncAdapter = exports.impersonateSyncAdapter = {
|
|
59
|
+
version: 1,
|
|
60
|
+
getSnapshot: () => _impersonateStore.impersonateStore.getState(),
|
|
61
|
+
subscribe: onChange => _impersonateStore.impersonateStore.subscribe(onChange),
|
|
62
|
+
actions: buildActions(query => {
|
|
63
|
+
if (!registeredSearchUsers) {
|
|
64
|
+
throw new Error("No onSearchUsers configured — pass it to createImpersonateTool()");
|
|
65
|
+
}
|
|
66
|
+
return registeredSearchUsers(query);
|
|
67
|
+
})
|
|
68
|
+
};
|
|
@@ -307,6 +307,32 @@ class ImpersonateStore {
|
|
|
307
307
|
return () => this.listeners.delete(listener);
|
|
308
308
|
};
|
|
309
309
|
|
|
310
|
+
// ===========================================================================
|
|
311
|
+
// REMOTE MIRROR MODE
|
|
312
|
+
// ===========================================================================
|
|
313
|
+
|
|
314
|
+
remoteHandler = null;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Remote mirror mode (desktop dashboard): while a handler is set, every
|
|
318
|
+
* mutation forwards (method, params) to the synced device instead of
|
|
319
|
+
* running locally — header patching, data nuking and persistence all
|
|
320
|
+
* happen on the device, and the resulting state comes back via
|
|
321
|
+
* replaceState(). Pass null to restore local behavior.
|
|
322
|
+
*/
|
|
323
|
+
setRemoteHandler(handler) {
|
|
324
|
+
this.remoteHandler = handler;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Replace the mirrored state from a synced device snapshot. Does not
|
|
329
|
+
* persist or touch the fetch listener — the device owns both.
|
|
330
|
+
*/
|
|
331
|
+
replaceState(state) {
|
|
332
|
+
this.state = state;
|
|
333
|
+
this.notify();
|
|
334
|
+
}
|
|
335
|
+
|
|
310
336
|
// ===========================================================================
|
|
311
337
|
// IMPERSONATION ACTIONS
|
|
312
338
|
// ===========================================================================
|
|
@@ -321,6 +347,12 @@ class ImpersonateStore {
|
|
|
321
347
|
* the visual symptom of "I clicked a user and nothing changed."
|
|
322
348
|
*/
|
|
323
349
|
async startImpersonation(user) {
|
|
350
|
+
if (this.remoteHandler) {
|
|
351
|
+
this.remoteHandler("startImpersonation", {
|
|
352
|
+
user
|
|
353
|
+
});
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
324
356
|
const historyEntry = {
|
|
325
357
|
user,
|
|
326
358
|
lastUsedAt: new Date().toISOString()
|
|
@@ -355,6 +387,10 @@ class ImpersonateStore {
|
|
|
355
387
|
* before nuking caches so subsequent refetches go out without the header.
|
|
356
388
|
*/
|
|
357
389
|
async stopImpersonation() {
|
|
390
|
+
if (this.remoteHandler) {
|
|
391
|
+
this.remoteHandler("stopImpersonation");
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
358
394
|
// eslint-disable-next-line no-console
|
|
359
395
|
console.log(`[impersonate] stopImpersonation: isActive ${this.state.isActive} -> false, listeners=${this.listeners.size}`);
|
|
360
396
|
this.state = {
|
|
@@ -373,6 +409,10 @@ class ImpersonateStore {
|
|
|
373
409
|
* Pause impersonation (temporarily stop injecting headers)
|
|
374
410
|
*/
|
|
375
411
|
async pauseImpersonation() {
|
|
412
|
+
if (this.remoteHandler) {
|
|
413
|
+
this.remoteHandler("pauseImpersonation");
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
376
416
|
if (!this.state.isActive || this.state.isPaused) return;
|
|
377
417
|
this.state = {
|
|
378
418
|
...this.state,
|
|
@@ -393,6 +433,10 @@ class ImpersonateStore {
|
|
|
393
433
|
* Resume impersonation (start injecting headers again)
|
|
394
434
|
*/
|
|
395
435
|
async resumeImpersonation() {
|
|
436
|
+
if (this.remoteHandler) {
|
|
437
|
+
this.remoteHandler("resumeImpersonation");
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
396
440
|
if (!this.state.isActive || !this.state.isPaused) return;
|
|
397
441
|
this.state = {
|
|
398
442
|
...this.state,
|
|
@@ -424,6 +468,12 @@ class ImpersonateStore {
|
|
|
424
468
|
* Update settings (header key, ignore patterns, data nuke settings, show banner)
|
|
425
469
|
*/
|
|
426
470
|
async updateSettings(settings) {
|
|
471
|
+
if (this.remoteHandler) {
|
|
472
|
+
this.remoteHandler("updateSettings", {
|
|
473
|
+
settings
|
|
474
|
+
});
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
427
477
|
this.state = {
|
|
428
478
|
...this.state,
|
|
429
479
|
headerKey: settings.headerKey ?? this.state.headerKey,
|
|
@@ -451,6 +501,12 @@ class ImpersonateStore {
|
|
|
451
501
|
* Remove a user from history
|
|
452
502
|
*/
|
|
453
503
|
async removeFromHistory(userId) {
|
|
504
|
+
if (this.remoteHandler) {
|
|
505
|
+
this.remoteHandler("removeFromHistory", {
|
|
506
|
+
userId
|
|
507
|
+
});
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
454
510
|
this.state = {
|
|
455
511
|
...this.state,
|
|
456
512
|
history: this.state.history.filter(entry => entry.user.id !== userId)
|
|
@@ -463,6 +519,10 @@ class ImpersonateStore {
|
|
|
463
519
|
* Clear all history
|
|
464
520
|
*/
|
|
465
521
|
async clearHistory() {
|
|
522
|
+
if (this.remoteHandler) {
|
|
523
|
+
this.remoteHandler("clearHistory");
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
466
526
|
this.state = {
|
|
467
527
|
...this.state,
|
|
468
528
|
history: []
|
package/lib/module/index.js
CHANGED
|
@@ -26,7 +26,13 @@
|
|
|
26
26
|
// FACTORY (Primary entry point)
|
|
27
27
|
// =============================================================================
|
|
28
28
|
|
|
29
|
-
export { createImpersonateTool } from "./preset";
|
|
29
|
+
export { createImpersonateTool, ImpersonateIcon } from "./preset";
|
|
30
|
+
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// EXTERNAL SYNC (Adapter for @buoy-gg/external-sync's useExternalSync)
|
|
33
|
+
// =============================================================================
|
|
34
|
+
|
|
35
|
+
export { createImpersonateSyncAdapter, impersonateSyncAdapter } from "./sync/impersonateSyncAdapter";
|
|
30
36
|
|
|
31
37
|
// =============================================================================
|
|
32
38
|
// COMPONENTS (For custom UI implementations)
|
package/lib/module/preset.js
CHANGED
|
@@ -13,6 +13,7 @@ import { ImpersonateModal } from "./impersonate/components/ImpersonateModal";
|
|
|
13
13
|
import { ImpersonateBanner } from "./impersonate/components/ImpersonateBanner";
|
|
14
14
|
import { impersonateStore } from "./impersonate/utils/impersonateStore";
|
|
15
15
|
import { impersonateListener } from "./impersonate/utils/impersonateListener";
|
|
16
|
+
import { registerImpersonateSearchUsers } from "./sync/impersonateSyncAdapter";
|
|
16
17
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
18
|
// =============================================================================
|
|
18
19
|
// EAGER BOOTSTRAP
|
|
@@ -79,7 +80,7 @@ async function bootstrapImpersonate() {
|
|
|
79
80
|
/**
|
|
80
81
|
* Impersonate tool icon - a mask/person symbol
|
|
81
82
|
*/
|
|
82
|
-
function ImpersonateIcon({
|
|
83
|
+
export function ImpersonateIcon({
|
|
83
84
|
size,
|
|
84
85
|
color = "#F59E0B"
|
|
85
86
|
}) {
|
|
@@ -170,6 +171,11 @@ export function createImpersonateTool(config) {
|
|
|
170
171
|
impersonateStore.setDeveloperDefaults(defaults);
|
|
171
172
|
}
|
|
172
173
|
|
|
174
|
+
// Make the app's user search available to the zero-config external-sync
|
|
175
|
+
// adapter (FloatingDevTools auto-sync), so the desktop dashboard can proxy
|
|
176
|
+
// searches without separate wiring.
|
|
177
|
+
registerImpersonateSearchUsers(onSearchUsers ?? null);
|
|
178
|
+
|
|
173
179
|
// Patch fetch and restore persisted impersonation state up-front. Fire and
|
|
174
180
|
// forget — bootstrapImpersonate guards itself against double-invocation.
|
|
175
181
|
void bootstrapImpersonate();
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { impersonateStore } from "../impersonate/utils/impersonateStore";
|
|
4
|
+
// Registered by createImpersonateTool, so the zero-config adapter (see
|
|
5
|
+
// FloatingDevTools' auto external sync) can proxy the dashboard's user
|
|
6
|
+
// search without the app wiring anything twice.
|
|
7
|
+
let registeredSearchUsers = null;
|
|
8
|
+
|
|
9
|
+
/** @internal Called by createImpersonateTool with the app's onSearchUsers. */
|
|
10
|
+
export function registerImpersonateSearchUsers(handler) {
|
|
11
|
+
registeredSearchUsers = handler;
|
|
12
|
+
}
|
|
13
|
+
function buildActions(onSearchUsers) {
|
|
14
|
+
return {
|
|
15
|
+
searchUsers: params => onSearchUsers(params.query),
|
|
16
|
+
startImpersonation: params => impersonateStore.startImpersonation(params.user),
|
|
17
|
+
stopImpersonation: () => impersonateStore.stopImpersonation(),
|
|
18
|
+
pauseImpersonation: () => impersonateStore.pauseImpersonation(),
|
|
19
|
+
resumeImpersonation: () => impersonateStore.resumeImpersonation(),
|
|
20
|
+
updateSettings: params => impersonateStore.updateSettings(params.settings),
|
|
21
|
+
removeFromHistory: params => impersonateStore.removeFromHistory(params.userId),
|
|
22
|
+
clearHistory: () => impersonateStore.clearHistory()
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a sync adapter for the impersonate tool, consumed by
|
|
27
|
+
* @buoy-gg/external-sync's `useExternalSync` (structurally matches its
|
|
28
|
+
* ToolSyncAdapter interface so this package doesn't need a dependency on it).
|
|
29
|
+
*
|
|
30
|
+
* The dashboard mirrors the impersonation state and forwards every mutation
|
|
31
|
+
* back as an action — header patching, data nuking and persistence all run
|
|
32
|
+
* on the device, so impersonating from the desktop behaves exactly like
|
|
33
|
+
* tapping the modal on the phone.
|
|
34
|
+
*/
|
|
35
|
+
export function createImpersonateSyncAdapter({
|
|
36
|
+
onSearchUsers
|
|
37
|
+
}) {
|
|
38
|
+
return {
|
|
39
|
+
version: 1,
|
|
40
|
+
getSnapshot: () => impersonateStore.getState(),
|
|
41
|
+
subscribe: onChange => impersonateStore.subscribe(onChange),
|
|
42
|
+
actions: buildActions(onSearchUsers)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Zero-config variant used by FloatingDevTools' auto external sync. User
|
|
48
|
+
* search proxies to the onSearchUsers the app passed to
|
|
49
|
+
* createImpersonateTool; if the tool was never configured, the search action
|
|
50
|
+
* reports a descriptive error to the dashboard.
|
|
51
|
+
*/
|
|
52
|
+
export const impersonateSyncAdapter = {
|
|
53
|
+
version: 1,
|
|
54
|
+
getSnapshot: () => impersonateStore.getState(),
|
|
55
|
+
subscribe: onChange => impersonateStore.subscribe(onChange),
|
|
56
|
+
actions: buildActions(query => {
|
|
57
|
+
if (!registeredSearchUsers) {
|
|
58
|
+
throw new Error("No onSearchUsers configured — pass it to createImpersonateTool()");
|
|
59
|
+
}
|
|
60
|
+
return registeredSearchUsers(query);
|
|
61
|
+
})
|
|
62
|
+
};
|
|
@@ -83,6 +83,20 @@ declare class ImpersonateStore {
|
|
|
83
83
|
* Returns unsubscribe function
|
|
84
84
|
*/
|
|
85
85
|
subscribe: (listener: StateListener) => (() => void);
|
|
86
|
+
private remoteHandler;
|
|
87
|
+
/**
|
|
88
|
+
* Remote mirror mode (desktop dashboard): while a handler is set, every
|
|
89
|
+
* mutation forwards (method, params) to the synced device instead of
|
|
90
|
+
* running locally — header patching, data nuking and persistence all
|
|
91
|
+
* happen on the device, and the resulting state comes back via
|
|
92
|
+
* replaceState(). Pass null to restore local behavior.
|
|
93
|
+
*/
|
|
94
|
+
setRemoteHandler(handler: ((method: string, params?: unknown) => void) | null): void;
|
|
95
|
+
/**
|
|
96
|
+
* Replace the mirrored state from a synced device snapshot. Does not
|
|
97
|
+
* persist or touch the fetch listener — the device owns both.
|
|
98
|
+
*/
|
|
99
|
+
replaceState(state: ImpersonationState): void;
|
|
86
100
|
/**
|
|
87
101
|
* Start impersonating a user.
|
|
88
102
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"impersonateStore.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateStore.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,IAAI,EAEJ,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAmClB,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAEzD,UAAU,aAAa;IACrB,UAAU,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAiDD;;;;;;;;GAQG;AACH,cAAM,gBAAgB;IACpB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAGP;IAChB,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,mBAAmB,CAA6B;IACxD,OAAO,CAAC,iBAAiB,CAAoC;;IAqB7D;;OAEG;IACH,OAAO,CAAC,eAAe;IA2CvB;;;OAGG;IACH,eAAe,CAAC,YAAY,EAAE;QAC5B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACjD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACxD,GAAG,IAAI;IASR;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAkBzD;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAW5B;;OAEG;IACH,oBAAoB,IAAI,mBAAmB,GAAG,IAAI;IAIlD;;;OAGG;IACG,eAAe,CAAC,YAAY,CAAC,EAAE;QACnC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QACjD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACxD,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CjB;;OAEG;IACH,qBAAqB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI;IAQrD;;OAEG;IACH,QAAQ,IAAI,kBAAkB;IAI9B;;;OAGG;IACH,WAAW,QAAO,kBAAkB,CAElC;IAEF;;;OAGG;IACH,SAAS,GAAI,UAAU,aAAa,KAAG,CAAC,MAAM,IAAI,CAAC,CAGjD;IAMF;;;;;;;;OAQG;IACG,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"impersonateStore.d.ts","sourceRoot":"","sources":["../../../../src/impersonate/utils/impersonateStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
* <FloatingDevTools apps={[impersonateTool]} />
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
export { createImpersonateTool } from "./preset";
|
|
22
|
+
export { createImpersonateTool, ImpersonateIcon } from "./preset";
|
|
23
|
+
export { createImpersonateSyncAdapter, impersonateSyncAdapter, } from "./sync/impersonateSyncAdapter";
|
|
23
24
|
export { ImpersonateModal } from "./impersonate/components/ImpersonateModal";
|
|
24
25
|
export { ImpersonateBanner, ImpersonateBannerMinimal, } from "./impersonate/components/ImpersonateBanner";
|
|
25
26
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAMlE,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AAMvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAC7E,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,4CAA4C,CAAC;AACpD;;;;GAIG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,gBAAgB,IAAI,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAC1G,OAAO,EAAE,sBAAsB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AAMrF,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,YAAY,EACV,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAClF,YAAY,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAM7F,YAAY,EACV,IAAI,EACJ,gBAAgB,IAAI,oBAAoB,EACxC,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAC;AAM7B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,EACf,qBAAqB,GACtB,MAAM,yCAAyC,CAAC"}
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { ImpersonateBanner } from "./impersonate/components/ImpersonateBanner";
|
|
9
9
|
import type { ImpersonateToolConfig } from "./impersonate/types";
|
|
10
|
+
interface IconProps {
|
|
11
|
+
size: number;
|
|
12
|
+
color?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Impersonate tool icon - a mask/person symbol
|
|
16
|
+
*/
|
|
17
|
+
export declare function ImpersonateIcon({ size, color }: IconProps): React.JSX.Element;
|
|
10
18
|
/**
|
|
11
19
|
* Create an impersonate tool with custom configuration
|
|
12
20
|
*
|
|
@@ -70,4 +78,5 @@ export declare function createImpersonateTool(config: ImpersonateToolConfig): {
|
|
|
70
78
|
};
|
|
71
79
|
Banner: typeof ImpersonateBanner;
|
|
72
80
|
};
|
|
81
|
+
export {};
|
|
73
82
|
//# sourceMappingURL=preset.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../../src/preset.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAI/E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAyEjE,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,KAAiB,EAAE,EAAE,SAAS,qBAmBrE;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB;;;;;qBAkC9C;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;uBAGd;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAAE;;;;;EAmB3H"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { User, ImpersonationState } from "../impersonate/types";
|
|
2
|
+
type SearchUsersHandler = (query: string) => Promise<User[]>;
|
|
3
|
+
/** @internal Called by createImpersonateTool with the app's onSearchUsers. */
|
|
4
|
+
export declare function registerImpersonateSearchUsers(handler: SearchUsersHandler | null): void;
|
|
5
|
+
interface CreateImpersonateSyncAdapterOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Same user-search callback you pass to the ImpersonateModal — the
|
|
8
|
+
* dashboard's search box proxies here.
|
|
9
|
+
*/
|
|
10
|
+
onSearchUsers: SearchUsersHandler;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create a sync adapter for the impersonate tool, consumed by
|
|
14
|
+
* @buoy-gg/external-sync's `useExternalSync` (structurally matches its
|
|
15
|
+
* ToolSyncAdapter interface so this package doesn't need a dependency on it).
|
|
16
|
+
*
|
|
17
|
+
* The dashboard mirrors the impersonation state and forwards every mutation
|
|
18
|
+
* back as an action — header patching, data nuking and persistence all run
|
|
19
|
+
* on the device, so impersonating from the desktop behaves exactly like
|
|
20
|
+
* tapping the modal on the phone.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createImpersonateSyncAdapter({ onSearchUsers, }: CreateImpersonateSyncAdapterOptions): {
|
|
23
|
+
version: number;
|
|
24
|
+
getSnapshot: () => ImpersonationState;
|
|
25
|
+
subscribe: (onChange: () => void) => () => void;
|
|
26
|
+
actions: {
|
|
27
|
+
searchUsers: (params: unknown) => Promise<User[]>;
|
|
28
|
+
startImpersonation: (params: unknown) => Promise<void>;
|
|
29
|
+
stopImpersonation: () => Promise<void>;
|
|
30
|
+
pauseImpersonation: () => Promise<void>;
|
|
31
|
+
resumeImpersonation: () => Promise<void>;
|
|
32
|
+
updateSettings: (params: unknown) => Promise<void>;
|
|
33
|
+
removeFromHistory: (params: unknown) => Promise<void>;
|
|
34
|
+
clearHistory: () => Promise<void>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Zero-config variant used by FloatingDevTools' auto external sync. User
|
|
39
|
+
* search proxies to the onSearchUsers the app passed to
|
|
40
|
+
* createImpersonateTool; if the tool was never configured, the search action
|
|
41
|
+
* reports a descriptive error to the dashboard.
|
|
42
|
+
*/
|
|
43
|
+
export declare const impersonateSyncAdapter: {
|
|
44
|
+
version: number;
|
|
45
|
+
getSnapshot: () => ImpersonationState;
|
|
46
|
+
subscribe: (onChange: () => void) => () => void;
|
|
47
|
+
actions: {
|
|
48
|
+
searchUsers: (params: unknown) => Promise<User[]>;
|
|
49
|
+
startImpersonation: (params: unknown) => Promise<void>;
|
|
50
|
+
stopImpersonation: () => Promise<void>;
|
|
51
|
+
pauseImpersonation: () => Promise<void>;
|
|
52
|
+
resumeImpersonation: () => Promise<void>;
|
|
53
|
+
updateSettings: (params: unknown) => Promise<void>;
|
|
54
|
+
removeFromHistory: (params: unknown) => Promise<void>;
|
|
55
|
+
clearHistory: () => Promise<void>;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=impersonateSyncAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impersonateSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/impersonateSyncAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAErE,KAAK,kBAAkB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAO7D,8EAA8E;AAC9E,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,kBAAkB,GAAG,IAAI,GACjC,IAAI,CAEN;AAyBD,UAAU,mCAAmC;IAC3C;;;OAGG;IACH,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,aAAa,GACd,EAAE,mCAAmC;;uBAGjB,kBAAkB;0BACb,MAAM,IAAI;;8BA7CV,OAAO;qCAEA,OAAO;;;;iCAKX,OAAO;oCAQJ,OAAO;;;EAiCtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;uBAEhB,kBAAkB;0BACb,MAAM,IAAI;;8BA3DR,OAAO;qCAEA,OAAO;;;;iCAKX,OAAO;oCAQJ,OAAO;;;CAqDtC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/impersonate",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "User impersonation tool for Buoy DevTools - inject custom headers for admin testing",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"sideEffects": false,
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@buoy-gg/shared-ui": "
|
|
29
|
+
"@buoy-gg/shared-ui": "4.0.1"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": "*",
|