Skip to content

feat: public budget share page and share link actions - #33

Open
claude-for-timatic[bot] wants to merge 2 commits into
mainfrom
feat/14-public-budget-share-page
Open

claude-for-timatic[bot] wants to merge 2 commits into
mainfrom
feat/14-public-budget-share-page

Conversation

@claude-for-timatic

Copy link
Copy Markdown
Contributor

Closes #14

Needs Timatic/timatic-backend#100.

What it does

  • Public page /shared-budgets/:id:
    • No login. The token is read from the URL fragment (#token) and sent as X-Share-Token instead of the bearer.
    • It reuses the budget detail page (now BudgetDetail with an isPublic prop) without these: entries, prices and rates, change number, account manager, supervisor, allowed users, and all actions.
    • A 401 shows "This link is no longer valid". Any other failure shows a generic error.
    • The page is marked noindex.
  • Share action on the internal budget page (needs budgets.update):
    • Create or regenerate a link. When one exists, the modal warns that the old link stops working.
    • The URL is shown once, with a Copy button.
    • The link can be revoked.
    • Creating a link is disabled, with the reason shown, when the budget isn't shown to the customer.

Decisions

  • Description stays visible: the public page shows the description, since the issue says "the same page minus entries". The share modal says so.
  • Plain-text description: it now renders as plain text (whitespace-pre-line) instead of v-html. That closes an XSS that a public page would expose to customers.
  • Public page bypasses the app: it skips the login redirect and the app's data loading. The layout loads the app's data once, the first time a logged-in user is on a non-public route.
  • Error messages: BaseModal shows Laravel's message when an error has no JSON:API errors (the 422 text).
  • Archived budgets can be shared: the Share button follows budgets.update, not the archived-aware edit check, because the backend keeps archived budgets readable.

Review

A code, security and usability review found no blockers. Applied:

  • the XSS fix
  • error handling for a revoked or throttled link
  • a more robust layout bootstrap
  • share modal fixes: clipboard error, keyboard-accessible revoke, Close label, stale error reset
  • logging no longer prints request headers
  • noindex

Verification

nuxt build passes. Not tried in a browser. ESLint doesn't run: ESLint 10 doesn't read the repo's existing .eslintrc.js, which predates this PR.

Users who can update budgets create, regenerate and revoke the link from
the budget detail page. The link opens the budget detail page without a
login: no entries, prices, change number or people.

Closes #14
- Render the budget description as text instead of html.
- Tell the user the description is visible through the link.
- Show the invalid-link state when periods or the chart fail to load.
- Load the app's data once the first internal page is reached.
- Disable creating a link for budgets hidden from the customer.
- Keep the share token out of the console and search engines.

Refs #14
@tomasvanrijsse
tomasvanrijsse self-requested a review November 9, 2026 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Public budget share page

1 participant