Improve metadata prompts; fix upload error + remove debug log
- Replace bracketed metadata placeholders with prompting questions - Fix upload error message (response.statusContents -> statusText) - Remove stray debug console.log on reactive screen updates - Document the upload token's security model in the app README Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,21 @@ When you click **Upload**, your readings will be:
|
|||||||
|
|
||||||
All uploaded readings are public and available for research and analysis. By uploading, you consent to releasing your diagnostic under a public domain license.
|
All uploaded readings are public and available for research and analysis. By uploading, you consent to releasing your diagnostic under a public domain license.
|
||||||
|
|
||||||
|
#### Upload credentials and security model
|
||||||
|
|
||||||
|
The upload feature posts directly from the user's browser to the Gitea API using an access token defined in `src/components/ExportControls.svelte` (`GITEA_TOKEN`).
|
||||||
|
|
||||||
|
**This token is intentionally embedded in the client bundle, and that is acceptable here.** Because this is a purely static app, the browser must make the API call itself — there is no server-side code of ours to hold the token. Any credential the browser uses is therefore necessarily public; build-time environment variables would still be baked into the shipped JavaScript, so they would offer no real protection. The exposure is contained by *what the token can do* rather than by hiding it:
|
||||||
|
|
||||||
|
- The token belongs to a **dedicated `bicorder-bot` account**, not to a personal account.
|
||||||
|
- `bicorder-bot` is a **collaborator with write access only to the public [`protocol-bicorder-data`](https://git.medlab.host/ntnsndr/protocol-bicorder-data) repo**. It cannot push to any other repository.
|
||||||
|
- It has **`admin: false`** on that repo, so it can only add/modify files — it cannot delete the repo or change its settings.
|
||||||
|
- The token scope is `write:repository` (it cannot even read user account details).
|
||||||
|
|
||||||
|
The entire worst-case blast radius is therefore: someone extracts the token and spams or vandalizes the contents of the public data repo. This is recoverable (revert the commits) and the repo contains only public submissions.
|
||||||
|
|
||||||
|
**If the token is ever abused:** revoke it under the `bicorder-bot` account (Gitea → Settings → Applications → Access Tokens — note that tokens live under the *user account*, not the repo), generate a replacement with the same `write:repository` scope, update `GITEA_TOKEN` in `ExportControls.svelte`, and rebuild. Optionally, enable branch protection on the data repo's `main` branch as an additional safeguard.
|
||||||
|
|
||||||
## Browser Support
|
## Browser Support
|
||||||
|
|
||||||
- Modern browsers (Chrome, Firefox, Safari, Edge)
|
- Modern browsers (Chrome, Firefox, Safari, Edge)
|
||||||
|
|||||||
@@ -77,11 +77,6 @@
|
|||||||
$: currentScreenData = screens[currentScreen];
|
$: currentScreenData = screens[currentScreen];
|
||||||
$: totalScreens = screens.length;
|
$: totalScreens = screens.length;
|
||||||
|
|
||||||
// Debug: log when screens change
|
|
||||||
$: if (screens) {
|
|
||||||
console.log(`Screens updated: ${screens.length} total, shortform: ${data.metadata.shortform}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function goToNextScreen() {
|
function goToNextScreen() {
|
||||||
if (currentScreen < totalScreens - 1) {
|
if (currentScreen < totalScreens - 1) {
|
||||||
currentScreen++;
|
currentScreen++;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
showUploadDialog = false;
|
showUploadDialog = false;
|
||||||
} else {
|
} else {
|
||||||
const errorData = await response.json();
|
const errorData = await response.json();
|
||||||
throw new Error(errorData.message || `Upload failed: ${response.statusContents}`);
|
throw new Error(errorData.message || `Upload failed: ${response.statusText}`);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Upload error:', err);
|
console.error('Upload error:', err);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<input
|
<input
|
||||||
id="protocol"
|
id="protocol"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="[Protocol]"
|
placeholder="What protocol are you analyzing?"
|
||||||
value={metadata.protocol || ''}
|
value={metadata.protocol || ''}
|
||||||
on:input={(e) => handleInput('protocol', e.currentTarget.value)}
|
on:input={(e) => handleInput('protocol', e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<label for="description">Description:</label>
|
<label for="description">Description:</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="description"
|
id="description"
|
||||||
placeholder="[Description]"
|
placeholder="Briefly, what is this protocol?"
|
||||||
value={metadata.description || ''}
|
value={metadata.description || ''}
|
||||||
on:input={(e) => handleInput('description', e.currentTarget.value)}
|
on:input={(e) => handleInput('description', e.currentTarget.value)}
|
||||||
rows="3"
|
rows="3"
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<input
|
<input
|
||||||
id="analyst"
|
id="analyst"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="[Analyst]"
|
placeholder="How do you identify yourself?"
|
||||||
value={metadata.analyst || ''}
|
value={metadata.analyst || ''}
|
||||||
on:input={(e) => handleInput('analyst', e.currentTarget.value)}
|
on:input={(e) => handleInput('analyst', e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<input
|
<input
|
||||||
id="standpoint"
|
id="standpoint"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="[Standpoint]"
|
placeholder="What is your relationship to the protocol?"
|
||||||
value={metadata.standpoint || ''}
|
value={metadata.standpoint || ''}
|
||||||
on:input={(e) => handleInput('standpoint', e.currentTarget.value)}
|
on:input={(e) => handleInput('standpoint', e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user