Commit Graph

53 Commits

Author SHA1 Message Date
Dan Milne
37e6e2cc19 Show copy-pasteable OIDC env vars after creating an app
Surfaces OIDC_CLIENT_ID/SECRET, discovery URL, provider name, and PKCE
flag in a single textarea on the credentials flash so the client config
can be dropped straight into a consuming app's .env file.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 08:30:30 +10:00
Dan Milne
cc93f72f0a Notify users out-of-band when security settings change
Previously only TOTP-enabled triggered an email. Every other
security-relevant change — password change, TOTP disable, passkey
add/remove, API key create/revoke, email address change, backup-code
regeneration — happened silently, so an attacker on a stolen session
could quietly drop 2FA or hijack the email with no signal to the
account holder.

Add SecurityMailer with one method per event. Each email carries the
request IP, user-agent, and timestamp so the user can spot unfamiliar
activity. Email-address changes notify both the old and new addresses
with directional language; the old-address copy explicitly warns that
whoever made the change can now receive password reset emails.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 23:52:12 +10:00
Dan Milne
7d352654fd Fix broken password reset email templates
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / scan_container (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
Both templates called `@user.password_reset_token` and
`@user.password_reset_token_expires_in`, which don't exist —
`generates_token_for` only adds class-level helpers, not instance
accessors. Every password reset email was failing at render time.
Use `generate_token_for(:password_reset)` and a literal expiry string
matching the 1-hour TTL on the token.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 23:40:43 +10:00
Dan Milne
e39721c7e6 Fix broken invitation email text template
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / scan_container (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
The text part used non-existent helpers (`invite_url`,
`@user.invitation_login_token`) and Ruby string interpolation in an ERB
file, so multipart delivery failed at render time and no invite mail
went out. Mirror the HTML template instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 23:39:29 +10:00
Dan Milne
b876e02c3a Hold TOTP enrollment secret server-side and email user on activation
TOTP enrollment previously round-tripped the generated secret through a
hidden form field and saved whatever the client submitted, letting an
attacker with session access enroll a 2FA device they control by posting
their own secret plus a matching code. Stash the secret in the session
at GET /totp/new, read it only from the session at POST /totp, and drop
the hidden field from the view. Notify the user by email on successful
enrollment so unauthorized activations are visible even if a new vector
appears later.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
2026-04-20 18:17:50 +10:00
Dan Milne
9197524c88 Add remember me checkbox, center and narrow sign-in form
- Add "Remember me for 30 days" checkbox (30-day vs 24-hour session expiry)
- Center heading and constrain form width to max-w-md
- Preserve remember_me preference through TOTP and WebAuthn auth flows

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:22:51 +10:00
Dan Milne
3d98261a51 Add dark mode with toggle and localStorage persistence
Uses Tailwind v4 class-based dark mode with a Stimulus controller for
toggling. Respects prefers-color-scheme as default, prevents FOUC with
an inline script, and persists the user's choice in localStorage. All
views updated with dark: variants for backgrounds, text, borders,
badges, buttons, and form inputs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 00:37:58 +11:00
Dan Milne
43958f50ce Add @tailwindcss/forms plugin and improve application form UX
Install @tailwindcss/forms to fix missing padding on form inputs across
the app. Move the Application Type selector earlier in the new application
form (after slug, before description) so it gates type-specific fields
sooner. On the edit page, replace the confusing disabled dropdown with a
read-only badge since the type can't be changed after creation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 00:36:37 +11:00
Dan Milne
f65df76d99 Show user-friendly error when passkey authentication fails
Add error target to login page so WebAuthn errors are visible instead
of only appearing in the console. Use a helpful fallback message that
suggests a browser extension may be interfering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:11:43 +11:00
Dan Milne
c5898bd9a4 Add passkey option on TOTP page and auto-trigger passkey for TOTP users
When a user has both passkeys and TOTP configured, auto-trigger the
passkey flow on login to save them from the password→TOTP path. Also
add a "Use Passkey Instead" button on the TOTP verification page as
an escape hatch for users who end up there.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:09:01 +11:00
Dan Milne
fd8785a43d Add API keys / bearer tokens for forward auth
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / scan_container (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
Enables server-to-server authentication for forward auth applications
(e.g., video players accessing WebDAV) where browser cookies aren't
available. API keys use clk_ prefixed tokens stored as HMAC hashes.

Bearer token auth is checked before cookie auth in /api/verify.
Invalid tokens return 401 JSON (no redirect). Requests without
bearer tokens fall through to existing cookie flow unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:45:40 +11:00
Dan Milne
5c5662eaab Expose 'username' via forward auth headers 2026-01-05 15:12:24 +11:00
Dan Milne
27d77ebf47 Expose 'username' via forward auth headers 2026-01-05 15:12:02 +11:00
Dan Milne
25e1043312 Add skip-consent, correctly use 303, rather than 302, actually rename per app 'logout' to 'require re-auth'. Add helper methods for token lifetime - allowing 10d for 10days for example. 2026-01-05 12:03:01 +11:00
Dan Milne
16e34ffaf0 Updates for oidc conformance 2026-01-03 10:11:10 +11:00
Dan Milne
bb5aa2e6d6 Add rails encryption for totp - allow configuration of encryption secrets from env, or derive them from SECRET_KEY_BASE. Don't leak email address via web_authn, rate limit web_authn, escape oidc state value, require password for changing email address, allow settings the hmac secret for token prefix generation 2025-12-31 10:33:56 +11:00
Dan Milne
cc7beba9de PKCE is now default enabled. You can now create public / no-secret apps OIDC apps 2025-12-31 09:22:18 +11:00
Dan Milne
283feea175 Update depenencies, bump versoin 2025-11-30 23:13:25 +11:00
Dan Milne
f8543f98cc Add a subdirectory for active storage
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-27 19:12:09 +11:00
Dan Milne
6be23c2c37 Add backchannel logout, per application logout.
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-27 16:38:27 +11:00
Dan Milne
d6029556d3 Add OIDC fixes, add prefered_username, add application-user claims 2025-11-25 16:29:40 +11:00
Dan Milne
7796c38c08 Add pairwise SID with a UUIDv4, a significatant upgrade over User.id.to_s. Complete allowing admin to enforce TOTP per user
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-23 11:16:06 +11:00
Dan Milne
e882a4d6d1 More complete oidc
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-18 20:03:03 +11:00
Dan Milne
67f28faaca Improve some front end views. More descriptive error condition reporting. Updates to CLINCH_HOST for better WEBAUTHN 2025-11-12 16:24:05 +11:00
Dan Milne
4df2eee4d9 Bug fix for domain names with empty string instead of null. Form errors and some security fixes
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-09 12:22:41 +11:00
Dan Milne
d9f11abbbf Fixes for OIDC and HTML 2025-11-09 12:04:26 +11:00
Dan Milne
f02665f690 Consolidate all the error messages - add some stimulus controller. 2025-11-07 16:58:28 +11:00
Dan Milne
6049429a41 Fix mobile view menu popout. Add an option SENTRY_DSN support, which uses rails event reporting
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-04 23:16:28 +11:00
Dan Milne
4c5ac344bd Bug updating OIDC apps. Update readme
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-04 20:14:41 +11:00
Dan Milne
fb14ce032f Strip out more inline javascript code. Encrypt backup codes and treat the backup codes attribute as a json array 2025-11-04 18:46:11 +11:00
Dan Milne
bf104a9983 Fix CSP errors - migrate inline JS to stimulus controllers. Add a URL for applications so users can discover them
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-04 17:06:53 +11:00
Dan Milne
57abc0b804 Add webauthn
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-04 16:20:11 +11:00
Dan Milne
19bfc21f11 Move sessions into their own view for easier management
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-04 15:19:39 +11:00
Dan Milne
ef15db77f9 Massive refactor. Merge forward_auth into App, remove references to unimplemented OIDC federation and SAML features. Add group and user custom claims. Groups now allocate which apps a user can use
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-11-04 13:21:55 +11:00
Dan Milne
7074242907 Update docs. Implemented a one-time token to work around domain cookies not being immediately return by the browser. Reduce db queries on /api/verify requests. 2025-10-28 08:27:19 +11:00
Dan Milne
c80bcafdb7 Bug fix 2025-10-28 08:27:19 +11:00
Dan Milne
d98f777e7d Refactor email delivery and background jobs system
- Switch from SolidQueue to async job processor for simpler background job handling
- Remove SolidQueue gem and related configuration files
- Add letter_opener gem for development email preview
- Fix invitation email template issues (invitation_login_token method and route helper)
- Configure SMTP settings via environment variables in application.rb
- Add email delivery configuration banner on admin users page
- Improve admin users page with inline action buttons and SMTP configuration warnings
- Update development and production environments to use async processor
- Add helper methods to detect SMTP configuration and filter out localhost settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 16:30:02 +11:00
Dan Milne
88428bfd97 Add configuration foward-auth headers 2025-10-26 14:41:20 +11:00
Dan Milne
5921cf82c2 Add invite button and routes for resending invitations 2025-10-25 13:49:10 +11:00
Dan Milne
39757a43dc Add an invite system
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 23:26:07 +11:00
Dan Milne
5463723455 Increase the thing
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 20:48:58 +11:00
Dan Milne
2db7f6a9df Don't use turbo when we expect to redirect
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 16:27:05 +11:00
Dan Milne
12e0ef66ed OIDC app creation with encrypted secrets and application roles
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 14:47:24 +11:00
Dan Milne
ad70841689 Pass the redirect url through the forms
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 11:36:11 +11:00
Dan Milne
9be6ef09ff Add missing file
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 11:08:43 +11:00
Dan Milne
21bdc21486 Switch menu order 2025-10-24 11:08:28 +11:00
Dan Milne
fc9afcd1b7 Separate Forward auth into it's own models + controller
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-24 10:56:27 +11:00
Dan Milne
ec2eb27da1 Add user admin 2025-10-23 21:13:50 +11:00
Dan Milne
d480d7dd0a Start implementing OIDC
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-23 18:22:52 +11:00
Dan Milne
07e87dbaeb User registation working. Sidebar built. Dashboard built. TOTP enable works - TOTP login works
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
2025-10-23 18:07:49 +11:00