+++
title = "Implement auth code session storage — utility module and AuthModal pre-fill integration"
priority = 7
status = "todo"
ticket_type = "task"
dependencies = []
+++
Resolved from TRIAGE ticket 0bc655. The auth code (4-word passphrase) that authorises edit and
delete operations must be available to the UI without forcing the user to re-enter it on every
interaction within a browsing session.
Chosen strategy: **session storage per quote ID**. The code is stored in the browser's
`sessionStorage` under the key `auth_code_{id}` when first entered. It is automatically cleared
when the tab closes. No explicit clear-on-delete is required (session storage is short-lived by
design), but it is good practice and should be included.
Options considered:
- localStorage: ruled out — indefinite persistence is unnecessary; the app tells users to store
the code externally anyway, and localStorage has a wider XSS exposure window.
- Component state only: ruled out — code is lost on any page navigation or reload, making the
edit/delete flow unusable in practice.
**Part 1 — Storage utility (`src/bin/ui/storage.rs`)**
Create a module with three public functions that wrap the browser's `sessionStorage` API:
```rust
use web_sys::window;
/// Retrieve the stored auth code for a given quote ID, if any.
pub fn get_auth_code(quote_id: &str) -> Option {
let storage = window()?.session_storage().ok()??;
storage.get_item(&format!("auth_code_{quote_id}")).ok()?
}
/// Persist the auth code for a quote ID in sessionStorage.
pub fn set_auth_code(quote_id: &str, code: &str) {
if let Some(Ok(storage)) = window().map(|w| w.session_storage()) {
if let Some(storage) = storage {
let _ = storage.set_item(&format!("auth_code_{quote_id}"), code);
}
}
}
/// Remove the auth code for a quote ID from sessionStorage (call after DELETE).
pub fn clear_auth_code(quote_id: &str) {
if let Some(Ok(storage)) = window().map(|w| w.session_storage()) {
if let Some(storage) = storage {
let _ = storage.remove_item(&format!("auth_code_{quote_id}"));
}
}
}
```
Expose this module from the UI binary root: add `mod storage;` to `src/bin/ui/main.rs`.
**Part 2 — AuthModal pre-fill**
Update the `AuthModal` component (ticket f850c6) to accept an `initial_value: Option`
prop. Pre-populate the `` value from this prop when the modal opens. The parent
component is responsible for reading from storage and passing the value in.
```rust
#[derive(Properties, PartialEq)]
pub struct AuthModalProps {
pub on_submit: Callback,
pub on_cancel: Callback<()>,
pub initial_value: Option, // pre-fill if auth code is already stored
}
```
**Part 3 — SingleQuotePage integration**
In the SingleQuotePage (or whichever component renders edit/delete for a quote), integrate
storage around the `AuthModal`:
- Before opening the modal: read `storage::get_auth_code("e.id)` and pass it as
`initial_value` to `AuthModal`.
- After a successful **edit** (POST /api/quotes/:id returns 200): call
`storage::set_auth_code("e.id, &submitted_code)`.
- After a successful **delete** (DELETE /api/quotes/:id returns 204): call
`storage::clear_auth_code("e.id)`.
- If the API returns 403 (wrong code): do NOT store the code; clear any existing stored value
with `storage::clear_auth_code("e.id)` so a stale code is not re-offered.
- The storage utility must compile only for `wasm32-unknown-unknown` — `web_sys::window()` is
not available on the host target. Gate the module under `#[cfg(target_arch = "wasm32")]` or
ensure it is only imported by the `ui` binary, which is always compiled for wasm32.
- `web_sys` must be available with the `Window`, `Storage` features — confirm these are included
in the `web_sys` dependency in `Cargo.toml` (ticket 93515e covers UI Cargo.toml setup).
- Do NOT use `gloo-storage` — it wraps localStorage by default and the API difference matters.
Use `web_sys` directly as shown above.
- The key pattern is `auth_code_{quote_id}` (underscore separator, not slash or dot).
- Session storage is tab-scoped: no cross-tab contamination is possible — no additional
scoping by domain or user is needed.
```sh
trunk build
```
`feat(quotesdb): implement auth code session storage utility and AuthModal pre-fill`
quotesdb/ui