mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 06:06:10 +00:00
fix(demo): the profile route writes only the baseline fields in the demo
Allowlisting `PUT /api/auth/profile` so the setup flow's baseline step could finish also handed every visitor the shared demo account's contact email, its display name, its full name and its insurer fields: the allowlist admits a path and a method, and every field the handler behind it writes comes with them. The justification beside the entry named three fields; the entry admitted eleven. The write is narrowed on the server, in `applyProfileUpdate`, to height, date of birth and sex while `DEMO_MODE` is set — not in the client, which is the party the allowlist exists to distrust. It happens ahead of the email conflict check, which would otherwise answer "is this address registered here?" to anybody who can open the demo. The display-name box goes read-only there, as the anamnesis card already is, so nothing accepts input it will discard. The entry's comment now lists what the handler writes and what is admitted.
This commit is contained in:
1 parent
ceefbc5571
commit
45599c527e
7 files changed
+338
-6
No files matched your search
@@ -144,4 +144,21 @@ describe("<ConfirmScreen> — the anamnesis card on a shared demo account", () =
|
||||
expect(html).toContain('data-slot="onboarding-anamnesis"');
|
||||
expect(html).toContain('data-readonly="true"');
|
||||
});
|
||||
|
||||
it("takes no display name in the demo either", () => {
|
||||
// `PUT /api/auth/profile` is allowlisted for the demo, but the server
|
||||
// drops every field outside height / date of birth / sex — the display
|
||||
// name would otherwise be the next visitor's. A box that accepts input
|
||||
// and silently discards it is the same dishonesty as a failed save, so
|
||||
// it does not accept input.
|
||||
const html = render(state(), {}, true);
|
||||
expect(html).toMatch(/id="ob-baseline-display-name"[^>]*disabled/);
|
||||
// The three the step exists for still take their answers.
|
||||
expect(html).not.toMatch(/id="ob-baseline-height"[^>]*disabled/);
|
||||
});
|
||||
|
||||
it("takes a display name on an ordinary instance", () => {
|
||||
const html = render(state());
|
||||
expect(html).not.toMatch(/id="ob-baseline-display-name"[^>]*disabled/);
|
||||
});
|
||||
});
|
||||
@@ -60,6 +60,7 @@ export function BaselineFields({
|
||||
onChange,
|
||||
heightAdapter,
|
||||
errors,
|
||||
readOnlyDisplayName = false,
|
||||
}: {
|
||||
value: BaselineFieldValues;
|
||||
onChange: <K extends keyof BaselineFieldValues>(
|
||||
@@ -68,6 +69,15 @@ export function BaselineFields({
|
||||
) => void;
|
||||
heightAdapter: HeightUnitAdapter;
|
||||
errors: BaselineFieldErrors;
|
||||
/**
|
||||
* v1.39 — the instance cannot persist a display name, so the box does not
|
||||
* take one. True under `DEMO_MODE`, where `applyProfileUpdate` writes only
|
||||
* height, date of birth and sex: the demo's single published account means
|
||||
* a display name typed here would be the next visitor's. A field that
|
||||
* accepts input and silently discards it is the same dishonesty as a save
|
||||
* that fails, which is why it is disabled rather than merely ignored.
|
||||
*/
|
||||
readOnlyDisplayName?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslations();
|
||||
|
||||
@@ -85,6 +95,7 @@ export function BaselineFields({
|
||||
id={IDS.displayName}
|
||||
value={value.displayName}
|
||||
onChange={(e) => onChange("displayName", e.target.value)}
|
||||
disabled={readOnlyDisplayName}
|
||||
autoComplete="nickname"
|
||||
maxLength={50}
|
||||
placeholder={t("onboarding.baseline.displayNamePlaceholder")}
|
||||
|
||||
@@ -117,8 +117,10 @@ export function BaselineForm({
|
||||
confirming?: boolean;
|
||||
/**
|
||||
* True on a `DEMO_MODE` instance, where the shared account's self-context
|
||||
* write is off the edge allowlist. Makes the anamnesis card read-only so
|
||||
* the refusal never reaches a visitor as a failed confirm.
|
||||
* write is off the edge allowlist and its profile write is narrowed to the
|
||||
* three baseline fields. Makes the anamnesis card and the display-name box
|
||||
* read-only, so neither refusal reaches a visitor as a failed confirm or as
|
||||
* an answer that silently vanished.
|
||||
*/
|
||||
demoMode?: boolean;
|
||||
}) {
|
||||
@@ -253,6 +255,7 @@ export function BaselineForm({
|
||||
onChange={patch}
|
||||
heightAdapter={heightAdapter}
|
||||
errors={fieldErrors}
|
||||
readOnlyDisplayName={demoMode}
|
||||
/>
|
||||
|
||||
<AnamnesisCard
|
||||
|
||||
Reference in new issue
Block a user