Skip to content

Add bearer API shield updates and Preact dashboard#356

Open
donatj wants to merge 32 commits into
masterfrom
feat/user-token-shield-api
Open

Add bearer API shield updates and Preact dashboard#356
donatj wants to merge 32 commits into
masterfrom
feat/user-token-shield-api

Conversation

@donatj

@donatj donatj commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

  • add user bearer-token support for creating and updating shields by shield ID
  • add the shield API ID migration and dashboard validation
  • migrate the logged-in dashboard SPA to Preact

Verification

  • make build
  • go test ./...
  • npx tsc --noEmit
  • git diff --check

Copilot AI review requested due to automatic review settings July 24, 2026 22:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds user-level bearer-token support for creating/updating shields via the API host, introduces user API-token management endpoints, and migrates the authenticated dashboard frontend from imperative controllers to a Preact SPA, along with schema migrations and local-dev tooling updates.

Changes:

  • Add Authorization: Bearer <user-token> + X-Shielded-Shield-ID flow to the API host, including last-used stamping.
  • Add dashboard endpoints and frontend UI to create/list/revoke user API tokens.
  • Migrate the dashboard SPA to Preact (new TSX entrypoint + JSX compiler config) and update schema/local-run tooling accordingly.

Reviewed changes

Copilot reviewed 31 out of 38 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tsconfig.json Switch TS JSX to automatic runtime configured for Preact.
ts/model/ShieldsModel.ts Remove old model/event-emitter dashboard state layer.
ts/EventEmitter.ts Remove old event emitter used by controller-based dashboard.
ts/Dashboard.tsx New Preact dashboard SPA for shields + user token management.
ts/Dashboard.ts Remove old controller-based dashboard bootstrap.
ts/Controllers/ShieldController.ts Remove imperative DOM-based shield editor controller.
ts/Controllers/SecretInputContoller.ts Remove imperative secret input controller.
ts/Controllers/MarkdownInputController.ts Remove imperative markdown input controller.
ts/Controllers/ErrorDialogController.ts Remove imperative error dialog controller.
ts/Controllers/DashboardController.ts Remove imperative dashboard controller wrapper.
ts/Controllers/ApiExampleController.ts Export example generators for reuse by Preact UI.
ts/api/tokens.ts Add browser client for dashboard user API token endpoints.
ts/api/shields.ts Extend shield type with optional APIID.
static/style/style.css Update generated CSS for new dashboard/token UI styling.
static/main.js Update generated JS bundle for Preact dashboard + new APIs.
scss/_dashboard.scss Add styles for API-token dashboard section + validation display.
schema/002_shield_api_id.sql Add nullable api_id and per-user uniqueness constraint.
schema/001_user_api_tokens.sql Add user_api_tokens table for bearer-token storage.
schema/000_BASELINE.sql Provide baseline schema snapshot for clean provisioning.
run-local.sh Add clean local runner (MySQL container + migrations + Caddy).
pages/privacy_templ.go Regenerate templ output (version bump).
pages/index_templ.go Regenerate templ output (version bump).
pages/dashboard.templ Update dashboard page to mount the Preact SPA + add nav.
pages/dashboard_templ.go Regenerate dashboard templ output to match template changes.
pages/common_templ.go Regenerate common templ output (attribute handling/version bump).
package.json Add preact dependency for the dashboard SPA.
package-lock.json Lockfile updates for preact dependency.
model/user_api_tokens.go Add mapper for hashed user API tokens + create/revoke/mark-used.
model/shields.go Persist/load optional api_id and support lookups by (user_id, api_id).
dashboardapitokenhandlers.go Add dashboard handlers for listing/creating/deleting user API tokens.
dashboardapihandlers.go Add/validate shield API IDs and enforce per-user uniqueness.
dashboardapihandlers_test.go Add unit tests for shield API ID validation regex.
cmd/shielded/main.go Wire new token mapper/handlers and update dashboard route path.
Caddyfile.local Add local HTTPS reverse-proxy config for host-based routing.
authhandlers.go Redirect auth flows to /dashboard instead of /dashboard.html.
ARCHITECTURE.md Add high-level architecture and behavior documentation for the system.
AGENTS.md Add contributor guidance and repo working conventions.
apihandler.go Add bearer-token shield updates/creates on API host + field validation.
Files not reviewed (5)
  • pages/common_templ.go: Generated file
  • pages/dashboard_templ.go: Generated file
  • pages/index_templ.go: Generated file
  • pages/privacy_templ.go: Generated file
  • static/style/style.css: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scss/_dashboard.scss Outdated
Comment on lines +69 to +73
> div:nth-of-type(1) {
display: flex;
gap: 0.5rem;

input {
Comment thread ts/Dashboard.tsx Outdated
Comment thread apihandler.go Outdated
Comment thread apihandler.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 39 changed files in this pull request and generated 2 comments.

Files not reviewed (5)
  • pages/common_templ.go: Generated file
  • pages/dashboard_templ.go: Generated file
  • pages/index_templ.go: Generated file
  • pages/privacy_templ.go: Generated file
  • static/style/style.css: Generated file

Comment thread schema/000_BASELINE.sql
Comment thread ARCHITECTURE.md Outdated
@donatj
donatj force-pushed the feat/user-token-shield-api branch from 78736e9 to 98f9f69 Compare July 25, 2026 11:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 39 changed files in this pull request and generated 3 comments.

Files not reviewed (5)
  • pages/common_templ.go: Generated file
  • pages/dashboard_templ.go: Generated file
  • pages/index_templ.go: Generated file
  • pages/privacy_templ.go: Generated file
  • static/style/style.css: Generated file

Comment thread dashboardapihandlers.go
Comment on lines +136 to +146
func secureStringWithCharset(length int, charset string) (string, error) {
b := make([]byte, length)
limit := big.NewInt(int64(len(charset)))
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
index, err := cryptorand.Int(cryptorand.Reader, limit)
if err != nil {
return "", err
}
b[i] = charset[index.Int64()]
}
return string(b)
return string(b), nil

@donatj donatj Jul 25, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change needed: Go permits any integer type, including int64, as a string index. The current test suite and production build compile this exact code successfully.

Comment thread ts/Dashboard.tsx Outdated
<Input label="Shield key" name="ShieldKey" value={draft.ShieldKey || ""} pattern="[a-z0-9\\-]{5,64}" title="Optional: 5-64 lowercase letters, digits, or hyphens" placeholder="e.g. production-status" autoComplete="off" spellcheck={false} aria-invalid={shieldKeyInvalid} aria-describedby={shieldKeyInvalid ? shieldKeyErrorID : undefined} />
{shieldKeyInvalid && <p id={shieldKeyErrorID} class="input-error" role="alert">Shield key must be 5-64 lowercase letters, digits, or hyphens.</p>}
</section>
<section class="shield-container"><img src={`https://${env.ImgHost}/s/${draft.PublicID}?break=${imageTick}`} /></section>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 5f82759. The shield preview now has descriptive alt text based on its current title and text.

Comment thread ts/Dashboard.tsx
Comment on lines +235 to +237
function Input({ label, ...attributes }: JSX.InputHTMLAttributes<HTMLInputElement> & { label: string }) {
return <div class="input-container"><label>{label}</label><input {...attributes} /></div>;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 5f82759. The reusable Input component now generates a stable Preact ID and pairs its label with the input using for/id. The related Markdown, shield-token, and newly created user-token fields are also associated with labels.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 39 changed files in this pull request and generated 1 comment.

Files not reviewed (5)
  • pages/common_templ.go: Generated file
  • pages/dashboard_templ.go: Generated file
  • pages/index_templ.go: Generated file
  • pages/privacy_templ.go: Generated file
  • static/style/style.css: Generated file

Comment thread ts/Dashboard.tsx
Comment on lines +97 to +107

const saveShield = async (shield: ShieldInterface) => {
setError("");
try {
const savedShield = await api.saveShield(shield);
setShields((current) => (current || []).map((item) => item.ShieldID === savedShield.ShieldID ? savedShield : item));
} catch (requestError) {
setError(errorMessage(requestError));
throw requestError;
}
};
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.

2 participants