WIP: WebAuthn/passkey authentication - #6
Open
burning-bush-dev wants to merge 11 commits into
Open
burning-bush-dev wants to merge 11 commits into
burning-bush-dev wants to merge 11 commits into
Conversation
Housekeeping - Add root AGPL-3.0 LICENSE file - Fix surname across all source files and Makefile.PL AUTHOR fields - Remove stale META.yml files (generated by make dist) - Update README with current status, Docker quickstart, fix forum link - Add .gitignore entry for test-results/ CI: container-based builds - Multi-stage Dockerfile (dist/docker/Dockerfile): base stage has all deps pre-installed, production stage adds source and entrypoint. CI builds --target base; docker.yml builds the full production image. - ci.yml: runs Perl tests in the CI container with MySQL 8 service container (replaces bare-runner apt-get/cpanm from scratch) - ci-image.yml: builds and pushes the CI base image to GHCR on master when Dockerfile or Makefile.PL dependencies change - docker.yml: updated to actions/checkout@v6 and ubuntu-24.04 Release workflow - Automated release via workflow_dispatch with version input - Preflight validation (format, tag existence, version ordering) - Container-based test suite (same as CI) - Version bump, commit, tag, push - Build and upload Perl distribution tarballs to GitHub Releases - Build and push production Docker image to GHCR with version tags Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Apr 6, 2026
Build the base Docker image locally in CI instead of requiring a pre-existing image in GHCR, breaking the bootstrap chicken-and-egg. Uses GHCR + GHA cache layers when available, builds from scratch when not. Also removes dead forums link per review feedback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add passkey support as an alternative login method. Disabled by default; enable by setting webauthn_enabled=1 in nt_options alongside webauthn_rp_id and webauthn_origin. Password auth is unchanged. Server: - NicToolServer::WebAuthn module with registration/authentication ceremonies - TOCTOU-safe challenge consumption (atomic UPDATE, check affected rows) - Usernameless login via discoverable credentials (empty allowCredentials) - Feature flag: webauthn_enabled option (default off) - Session dispatch for pre-auth WebAuthn endpoints (no session required) Client: - nt-webauthn.js: browser-side WebAuthn ceremony helpers (ES5/jQuery) - webauthn.cgi: JSON API proxy with action whitelist, CSRF validation, parameter injection prevention, cookie sanitization via CGI::cookie() - Login page passkey button (works without entering username) - User profile passkey management (register, rename, revoke) Schema: - nt_user_webauthn_credential table (full-column UNIQUE on credential_id) - nt_user_webauthn_challenge table (full-column UNIQUE on challenge) - Migration in upgrade.pl with CREATE TABLE IF NOT EXISTS for robustness - passkey_login added to session_log action ENUM Tests: - server/t/05_webauthn.t: 12 subtests covering feature flag, challenge lifecycle, registration/auth options, credential CRUD, mocked happy paths, cross-user isolation - client/t/e2e/webauthn.spec.ts: CSRF protection, session requirements, login page UI, virtual authenticator ceremonies, revocation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
burning-bush-dev
force-pushed
the
webauthn-wip
branch
from
April 6, 2026 18:42
fcd1f50 to
e36813b
Compare
esc() is HTML-entity escaping, which is wrong inside a JS string literal. js_escape() handles backslashes, quotes, and line separators correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add passkey support as an alternative login method. Disabled by default; enable by setting webauthn_enabled=1 in nt_options alongside webauthn_rp_id and webauthn_origin. Password auth is unchanged. Server: - NicToolServer::WebAuthn module with registration/authentication ceremonies - TOCTOU-safe challenge consumption (atomic UPDATE, check affected rows) - Usernameless login via discoverable credentials (empty allowCredentials) - Feature flag: webauthn_enabled option (default off) - Session dispatch for pre-auth WebAuthn endpoints (no session required) Client: - nt-webauthn.js: browser-side WebAuthn ceremony helpers (ES5/jQuery) - webauthn.cgi: JSON API proxy with action whitelist, CSRF validation, parameter injection prevention, cookie sanitization via CGI::cookie() - Login page passkey button (works without entering username) - User profile passkey management (register, rename, revoke) Schema: - nt_user_webauthn_credential table (full-column UNIQUE on credential_id) - nt_user_webauthn_challenge table (full-column UNIQUE on challenge) - Migration in upgrade.pl with CREATE TABLE IF NOT EXISTS for robustness - passkey_login added to session_log action ENUM Tests: - server/t/05_webauthn.t: 12 subtests covering feature flag, challenge lifecycle, registration/auth options, credential CRUD, mocked happy paths, cross-user isolation - client/t/e2e/webauthn.spec.ts: CSRF protection, session requirements, login page UI, virtual authenticator ceremonies, revocation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…uption The -status parameter in CGI.pm's header() appears to produce extra content in the response body under ModPerl::Registry with +ParseHeaders, causing JSON parse errors in E2E tests. Drop -status (tests check json.error_code, not HTTP status), add -charset utf-8, remove trailing 1;. Also add debug logging to W1 tests to capture exact response text on failure. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- setup-test-env.pl: insert webauthn_enabled, webauthn_rp_id, and webauthn_origin into nt_options so W4-W7 ceremony tests actually run in CI instead of being skipped - security.spec.ts: narrow T8 XSS assertion from /<script>/i (which matches legitimate script tags added for passkey support) to the specific injected payload Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
setup-test-env.pl now pre-populates webauthn_enabled=1 for E2E tests. The unit test needs to save/clear/restore it like the other options, and T1b uses ON DUPLICATE KEY UPDATE defensively. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three bugs:
- W4, W7: cleanup used page.context().request (an APIRequestContext)
where apiLogin() expects the playwright fixture. Changed test
signatures to destructure { page, playwright } and wrapped cleanup
in try/catch.
- W5: passkey login check used +verData.error_code === 200, but
successful session responses don't include error_code. Check for
nt_user_session instead.
- Added "Logging In" section to Docker README.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WIP: WebAuthn support, mentioned within issue NicTool#339 but otherwise out of the English blue