Account lifecycle

Release 0.3.0 · Reviewed 2026-09-09

Optional integration in 0.3.0

Install the published add_auth package through your Rails app’s Gemfile, then rehearse these changes in an isolated copy of the app. Enable only the capabilities you need. Review the release status and upgrade procedure first.

Add account forms while keeping profile fields, permissions and onboarding in your Rails app.

In the Rails app’s Gemfile, select the reviewed 0.3 release line:

RubyGemfile
gem "add_auth", "~> 0.3.0"

Run bundle install from the app’s root. Confirm bundle exec ruby -e 'require "add_auth"; puts AddAuth::VERSION' reports the selected version before generating files.

Prepare Rails authentication and delivery

First establish the generated User/Session/Authentication contracts and the database, atomic counters, durable jobs and email configuration. Map existing confirmation, disabled, deleted, timed-lock and manual-lock states. Do not mark imported users confirmed merely to make sign-in pass.

Generate and review

In the isolated destination app:

Shell
bin/rails generate add_auth:accounts
RAILS_ENV=test bin/rails db:migrate

The generator prepares lifecycle persistence, notifications, reauthentication and account routes. It leaves lifecycle disabled. After reviewing policy and existing routes:

Rubyconfig/initializers/add_auth.rb
AddAuth.configure do |config|
  config.lifecycle.enabled = true
end

Run bin/rails add_auth:doctor. Resolve its configuration findings before exposing account pages.

Exercise the user journeys

Visit /account/sign-up. Invalid forms must return 422; accepted registration redirects to a generic check-email page. Read the actual delivered confirmation email. GET only previews the proof; the confirmation POST consumes it once. Confirmation does not itself sign the user in.

Request a password reset at /account/requests/reset_password and an unlock at /account/requests/unlock. Unknown accounts receive the generic request outcome. Automatic lock recovery must not clear a host’s manual lock. Test delivery failure/retry and expired, wrong-purpose and replayed links.

Signed-in account pages live at /account/email, /account/password and /account/delete. Sensitive writes require fresh proof for their specific purpose and recheck policy in the transaction. Address changes require independent confirmation; password/account changes invalidate affected authority.

Keep host behavior explicit

Use a thin controller with an explicit allowlist for name or consent fields. The optional lifecycle.profile_attributes callback maps host profile attributes; it cannot assign authentication, authority or role fields. The lifecycle.provision callback performs local transactional onboarding after confirmation. Keep remote calls in host jobs with their own retry contract.

Keep roles, authorization, invitations, consent and email appearance in the app. Direct canonical email updates are rejected when lifecycle is enabled; route them through the account lifecycle command so confirmation and address ownership remain coherent.

Verify each browser mode

Run registration, confirmation, reset, unlock and account management with Turbo, ordinary JavaScript without Turbo and JavaScript disabled. Password/email alternatives remain subject to strict policy and configured captcha requirements. Ejected pages must retain cache exemption, 422 failures, 303 mutation redirects and the shared Core decisions.

If a link keeps expiring or an account stays locked, use migration recovery. Next, preserve provider sign-in.

Something unclear? Suggest a correction Release status

Search documentation

Type to find a guide.

Use Tab to move through results. Escape closes search.