Skip to content

feat(auth): add two-factor authentication - #65

Open
RedStar071 wants to merge 1 commit into
mainfrom
feat/two-factor-auth
Open

feat(auth): add two-factor authentication#65
RedStar071 wants to merge 1 commit into
mainfrom
feat/two-factor-auth

Conversation

@RedStar071

@RedStar071 RedStar071 commented Aug 24, 2026

Copy link
Copy Markdown
Member

Summary

  • add opt-in TOTP two-factor authentication to every account through Better Auth
  • provide an authenticated enrollment/disable flow and a pre-session TOTP or backup-code challenge at /two-factor
  • persist two-factor state through a checked-in Drizzle migration and expose the flow in the user menu with English and Italian copy

Why

Accounts currently authenticate with a single factor. This change adds password-confirmed TOTP enrollment, one-time backup codes, trusted-device support, and the matching sign-in challenge without moving authentication policy into the dashboard or persistence concerns into the auth package. packages/auth owns Better Auth policy, packages/database owns the schema and migration, and apps/dashboard remains the composition and presentation boundary.

Verification

  • aube run check:repo — blocked by pre-existing turborepo-monorepo skill frontmatter errors
  • aube run lint:ci — targeted auth/database/dashboard lint passed; the full command was not completed in this Windows environment
  • aube run typecheck — auth, database, and dashboard filters passed; the full workspace command timed out without diagnostics
  • aube testaube run test --filter=@agent-zero/auth --filter=@agent-zero/database passed (65 tests)
  • aube run build — the dashboard production build passed; the root wrapper is blocked by existing Windows aube/junction issues

Manual production-preview verification covered enrollment, QR/TOTP confirmation, backup-code generation, a fresh password sign-in redirect, TOTP completion, and trusted-device session creation. The signed-out Playwright challenge scenario also passed. Nuxt component tests remain blocked by the existing file:///__uno.css test-environment failure, which reproduces on the unchanged login spec.

Safety and compatibility

  • I added or updated deterministic tests for changed behavior.
  • I preserved observe mode as read-only, or explained the policy change above.
  • Runtime commands and target-repository writes remain inside the runner boundary.
  • I did not expose secrets, tokens, personal data, or untrusted output in logs.
  • I updated documentation and Agent Skills when workflows or boundaries changed.

The migration is additive. Better Auth encrypts TOTP secrets and backup codes with the deployment auth secret before persistence, requires the account password for enrollment and disable operations, and marks two-factor enabled only after the first valid TOTP code.

Agent context

  • Agent/tools used: Codex in T3 Code; Agent Zero architecture, Nuxt, test-driven-development, git-commit, and create-pull-request skills; PowerShell, Vitest, Nuxt build, Playwright, and GitHub CLI.
  • What the agent did, and what you changed or verified yourself: Codex implemented the feature, migration, UI, translations, documentation, and tests, then ran the verification described above. The user supplied the Better Auth guide and requested the implementation and PR; no additional manual code changes were reported.

Reviewer notes

  • Apply aube run db:migrate before exercising two-factor enrollment against an existing database.
  • Review the intentionally public /two-factor route rule: the page serves both the pending pre-session challenge and authenticated account management, while Better Auth enforces the appropriate cookie/session on each endpoint.
  • CI should run the complete repository matrix in Linux and confirm the checks that were blocked by the local Windows toolchain.

Note

Add TOTP two-factor authentication with enrollment, challenge, and backup codes

  • Adds the Better Auth twoFactor plugin in auth.ts and a new /two-factor route in two-factor.vue that serves both pre-session second-factor challenges and authenticated enrollment
  • Introduces DB migration 0004_outstanding_mister_sinister adding the two_factor table and two_factor_enabled column on user in schema/auth.ts; the schema is exported through the aggregated schema so Better Auth can resolve the model
  • Enrollment flow shows a QR code (via qrcode) and one-time backup codes, verifies the first TOTP code before completing setup, and supports disabling with password confirmation
  • Adds i18n strings (en/it), user menu link, TwoFactorError component, e2e and unit tests, and docs in README and architecture
  • Behavioral Change: /two-factor has auth disabled via route rule in nuxt.config.ts to allow both challenge and enrollment states on the same route; the in-memory e2e adapter in server/auth.config.ts now initializes an empty twoFactor collection
📊 Macroscope summarized fad036e. 14 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted

🗂️ Filtered Issues

@vercel

vercel Bot commented Aug 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-zero-dashboard Error Error Aug 24, 2026 12:32pm
agent-zero-docs Ready Ready Preview Aug 24, 2026 12:32pm
agent-zero-marketing Ready Ready Preview Aug 24, 2026 12:32pm

Comment thread README.md
those policy variables, rebuild the app, or the auth pages will keep advertising the old
capabilities (the server still enforces its own policy either way).

Every account can enable TOTP two-factor authentication from the signed-in user menu. Setup at

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High README.md:194

OAuth-only accounts cannot enable TOTP, so the statement that Every account can enable it is incorrect. With allowPasswordless disabled, /two-factor/enable requires validatePassword, which returns false when no password credential exists; either support enrollment for OAuth-only users or qualify this documentation.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @README.md around line 194:

OAuth-only accounts cannot enable TOTP, so the statement that `Every account can enable` it is incorrect. With `allowPasswordless` disabled, `/two-factor/enable` requires `validatePassword`, which returns false when no password credential exists; either support enrollment for OAuth-only users or qualify this documentation.

@macroscopeapp

macroscopeapp Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a complete two-factor authentication capability with new sign-in challenges, enrollment and recovery flows, trusted-device behavior, and persistent authentication data. Because it changes sensitive authentication paths and includes an unresolved OAuth-only account limitation, the security and runtime behavior warrant human review.

Not approved because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​types/​qrcode@​1.5.61001007481100
Addedqrcode@​1.5.410010010082100

View full report

@socket-security

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
License policy violation: npm dijkstrajs

License: HPND-sell-MIT-disclaimer-xserver - The applicable license policy does not permit this license (5) (package/LICENSE.md)

From: pnpm-lock.yamlnpm/qrcode@1.5.4npm/dijkstrajs@1.0.3

ℹ Read more on: This package | This alert | What is a license policy violation?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Find a package that does not violate your license policy or adjust your policy to allow this package's license.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/dijkstrajs@1.0.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

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.

1 participant