Example App
A Rails demo application showcasing all Custos features
Example App
Custos includes a complete Rails demo application in the example/ directory of the gem. It demonstrates every plugin and feature in a working application.
What's Included
The example app showcases:
- Registration and sign-in with email + password
- Passwordless sign-in via magic link
- Two-factor authentication (TOTP + backup codes + SMS)
- API authentication with bearer tokens
- Account lockout after failed attempts
- Email confirmation
- Remember me (persistent sessions)
- Session management (list active sessions, revoke, sign out everywhere)
- Two authenticatable models:
UserandApiClient
Models
User (Full Plugin Suite)
class User < ApplicationRecord
include Custos::Authenticatable
custos do
plugin :password, min_length: 8, require_digit: true
plugin :magic_link
plugin :mfa
plugin :lockout, max_attempts: 3, lockout_duration: 30 * 60
plugin :email_confirmation
plugin :remember_me
on(:magic_link_created) do |record, token|
AuthMailer.magic_link(record, token).deliver_later
end
on(:email_confirmation_requested) do |record, token|
AuthMailer.confirm_email(record, token).deliver_later
end
on(:sms_code_created) do |record, code|
SmsService.send(record.phone, "Your code: #{code}")
end
end
endApiClient (API Tokens Only)
class ApiClient < ApplicationRecord
include Custos::Authenticatable
custos do
plugin :api_tokens
end
endRunning the Example
cd example
bundle install
rails db:create db:migrate
rails serverKey Flows
Sign Up
- User submits email and password
- Account is created with
password=(hashed with Argon2) - Email confirmation token is generated
:email_confirmation_requestedcallback sends the email- User clicks the link to confirm
Sign In with Password
User.find_by_email_and_password(email:, password:)is called- If Lockout is enabled, locked accounts are rejected
- On success, a session is created via
SessionManager.create - If MFA is enabled, user is redirected to MFA verification
- Optionally, a remember token is generated
Sign In with Magic Link
User.generate_magic_link(email)generates a token:magic_link_createdcallback sends the email- User clicks the link
User.authenticate_magic_link(token)verifies and consumes the token- A session is created
MFA Setup
user.setup_totp(issuer: "ExampleApp")generates a provisioning URI- User scans the QR code
user.confirm_totp!(code)confirms the setup- Backup codes are generated with
user.generate_backup_codes
Session Management
SessionManager.active_for(user)lists all active sessions- Each session shows IP, user agent, and last activity
- Individual sessions can be revoked
- "Sign out everywhere" revokes all sessions
Directory Structure
example/
├── app/
│ ├── controllers/
│ │ ├── sessions_controller.rb
│ │ ├── registrations_controller.rb
│ │ ├── magic_links_controller.rb
│ │ ├── mfa/
│ │ │ ├── totp_controller.rb
│ │ │ └── verifications_controller.rb
│ │ ├── email_confirmations_controller.rb
│ │ └── api/
│ │ └── tokens_controller.rb
│ ├── models/
│ │ ├── user.rb
│ │ └── api_client.rb
│ ├── mailers/
│ │ └── auth_mailer.rb
│ └── views/
│ └── ...
├── config/
│ ├── initializers/
│ │ └── custos.rb
│ └── routes.rb
└── db/
└── migrate/
└── ...