@arvoretech/bug-jar 0.4.0 → 0.6.0
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/README.md +38 -12
- package/dist/index.d.mts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.global.js +72 -46
- package/dist/index.js +73 -47
- package/dist/index.mjs +73 -47
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -110,18 +110,44 @@ private S3 bucket via a presigned URL. No AWS credentials ever reach the browser
|
|
|
110
110
|
Flow:
|
|
111
111
|
|
|
112
112
|
1. Staff (admin) calls `POST /debug-sessions` with the target app URL and gets back
|
|
113
|
-
a `debugLink` (`https://app.../?debug=<token>`), the
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
3. The user
|
|
118
|
-
(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
113
|
+
a `debugLink` (`https://app.../?debug=<token>`), the server public key, and an expiry.
|
|
114
|
+
2. The user opens the link. Bug Jar detects `?debug=<token>`, persists the token in
|
|
115
|
+
a `.arvore.com.br` cookie, fetches the session, starts screen recording, and
|
|
116
|
+
shows an animated **session border** (no button, no banner).
|
|
117
|
+
3. The user just uses the app. The session survives navigation across apps
|
|
118
|
+
(app-v2 → legacy → reader) by re-hydrating the token from the cookie on each
|
|
119
|
+
page. Each page streams **encrypted chunks** to S3 in real time:
|
|
120
|
+
- **data** (network/console/errors/actions/storage) every 5s as JSONL
|
|
121
|
+
- **video** chunks straight from `MediaRecorder` as they are produced
|
|
122
|
+
Chunks are uploaded to `debug/<token>/<pageId>/<stream>/<seq>.bin` via per-chunk
|
|
123
|
+
presigned PUT URLs (`POST /debug-sessions/:token/chunk-url`). Page metadata goes
|
|
124
|
+
to `debug/<token>/<pageId>/meta.json` (`POST /debug-sessions/:token/meta`).
|
|
125
|
+
4. Staff reconstructs the session offline:
|
|
126
|
+
```bash
|
|
127
|
+
BUG_JAR_API=https://api.arvore.com.br/debug-sessions \
|
|
128
|
+
BUG_JAR_API_TOKEN=<admin-jwt> \
|
|
129
|
+
node scripts/decrypt-session.cjs <token> ./out
|
|
130
|
+
```
|
|
131
|
+
This reads the X25519 private key from Secrets Manager (`bug-jar/keypair`),
|
|
132
|
+
downloads all chunks via `GET /debug-sessions/:token/download`, decrypts each
|
|
133
|
+
per-page stream, and writes `<pageId>/data.jsonl`, `<pageId>/video.webm`,
|
|
134
|
+
`<pageId>/meta.json`.
|
|
135
|
+
|
|
136
|
+
## Encryption
|
|
137
|
+
|
|
138
|
+
Each stream (data and video, per page) is encrypted with libsodium
|
|
139
|
+
`crypto_secretstream_xchacha20poly1305`: a random symmetric key drives the stream,
|
|
140
|
+
and that key is sealed with `crypto_box_seal` (X25519) to the server public key.
|
|
141
|
+
The first chunk of every stream is `[magic][version][sealedKeyLen][sealedKey][header]`;
|
|
142
|
+
subsequent chunks are the encrypted stream messages, the last carrying `TAG_FINAL`.
|
|
143
|
+
Chunks leave the browser already unreadable; only the holder of the X25519 private
|
|
144
|
+
key can open them. `libsodium-wrappers` is loaded dynamically, so it only ships
|
|
145
|
+
when debug mode is actually used.
|
|
146
|
+
|
|
147
|
+
> Cross-app continuity works because all apps live under `*.arvore.com.br` and
|
|
148
|
+
> share the session cookie. Screen recording restarts per app (the browser does
|
|
149
|
+
> not allow `getDisplayMedia` to persist across full page loads / origins), so the
|
|
150
|
+
> video is reconstructed per page rather than as one continuous file.
|
|
125
151
|
|
|
126
152
|
|
|
127
153
|
## Privacy & Security
|
package/dist/index.d.mts
CHANGED
|
@@ -136,8 +136,6 @@ declare function exportAsZip(report: BugReport, videoBlob: Blob | null): Promise
|
|
|
136
136
|
interface DebugSessionPayload {
|
|
137
137
|
token: string;
|
|
138
138
|
publicKey: string;
|
|
139
|
-
presignedPut: string;
|
|
140
|
-
reportId: string;
|
|
141
139
|
expiresAt: number;
|
|
142
140
|
}
|
|
143
141
|
|
|
@@ -153,8 +151,13 @@ declare class BugJar {
|
|
|
153
151
|
private screenshot;
|
|
154
152
|
private featureFlags;
|
|
155
153
|
private screenRecorder;
|
|
156
|
-
private
|
|
154
|
+
private sessionBorder;
|
|
157
155
|
private debugSession;
|
|
156
|
+
private dataUploader;
|
|
157
|
+
private videoUploader;
|
|
158
|
+
private pageId;
|
|
159
|
+
private dataInterval;
|
|
160
|
+
private finalized;
|
|
158
161
|
private started;
|
|
159
162
|
constructor(config?: Partial<BugJarConfig>);
|
|
160
163
|
start(): void;
|
|
@@ -165,7 +168,10 @@ declare class BugJar {
|
|
|
165
168
|
captureAndExport(userDescription?: string): Promise<BugReport>;
|
|
166
169
|
getReport(): Promise<BugReport>;
|
|
167
170
|
private startDebugSession;
|
|
168
|
-
private
|
|
171
|
+
private startDataStreaming;
|
|
172
|
+
private registerFlushHandlers;
|
|
173
|
+
private finalizePage;
|
|
174
|
+
endDebugSession(): void;
|
|
169
175
|
}
|
|
170
176
|
declare function init(config?: Partial<BugJarConfig>): BugJar;
|
|
171
177
|
|
package/dist/index.d.ts
CHANGED
|
@@ -136,8 +136,6 @@ declare function exportAsZip(report: BugReport, videoBlob: Blob | null): Promise
|
|
|
136
136
|
interface DebugSessionPayload {
|
|
137
137
|
token: string;
|
|
138
138
|
publicKey: string;
|
|
139
|
-
presignedPut: string;
|
|
140
|
-
reportId: string;
|
|
141
139
|
expiresAt: number;
|
|
142
140
|
}
|
|
143
141
|
|
|
@@ -153,8 +151,13 @@ declare class BugJar {
|
|
|
153
151
|
private screenshot;
|
|
154
152
|
private featureFlags;
|
|
155
153
|
private screenRecorder;
|
|
156
|
-
private
|
|
154
|
+
private sessionBorder;
|
|
157
155
|
private debugSession;
|
|
156
|
+
private dataUploader;
|
|
157
|
+
private videoUploader;
|
|
158
|
+
private pageId;
|
|
159
|
+
private dataInterval;
|
|
160
|
+
private finalized;
|
|
158
161
|
private started;
|
|
159
162
|
constructor(config?: Partial<BugJarConfig>);
|
|
160
163
|
start(): void;
|
|
@@ -165,7 +168,10 @@ declare class BugJar {
|
|
|
165
168
|
captureAndExport(userDescription?: string): Promise<BugReport>;
|
|
166
169
|
getReport(): Promise<BugReport>;
|
|
167
170
|
private startDebugSession;
|
|
168
|
-
private
|
|
171
|
+
private startDataStreaming;
|
|
172
|
+
private registerFlushHandlers;
|
|
173
|
+
private finalizePage;
|
|
174
|
+
endDebugSession(): void;
|
|
169
175
|
}
|
|
170
176
|
declare function init(config?: Partial<BugJarConfig>): BugJar;
|
|
171
177
|
|