{"id":48454220,"url":"https://github.com/hasinhayder/tyro-login","last_synced_at":"2026-04-06T22:02:27.548Z","repository":{"id":327188630,"uuid":"1106918535","full_name":"hasinhayder/tyro-login","owner":"hasinhayder","description":"Powerful authentication system for Laravel 12 and 13 - Login, Registration, Forget Password, Email Verification, OTP, TOTP, Captcha, Brute Force Lockout, 5 Layouts, Dark \u0026 Light Themes, Email templates, Fully Configurable, Social Login. Comes with Excellent Documentation.","archived":false,"fork":false,"pushed_at":"2026-03-18T08:32:10.000Z","size":10424,"stargazers_count":236,"open_issues_count":0,"forks_count":23,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-03-18T09:29:01.640Z","etag":null,"topics":["authentication","javascript","laravel","login","php","sanctum","social-login","tyro"],"latest_commit_sha":null,"homepage":"https://hasinhayder.github.io/tyro-login/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hasinhayder.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-30T08:00:51.000Z","updated_at":"2026-03-18T08:32:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hasinhayder/tyro-login","commit_stats":null,"previous_names":["hasinhayder/tyro-login"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/hasinhayder/tyro-login","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasinhayder%2Ftyro-login","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasinhayder%2Ftyro-login/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasinhayder%2Ftyro-login/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasinhayder%2Ftyro-login/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hasinhayder","download_url":"https://codeload.github.com/hasinhayder/tyro-login/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hasinhayder%2Ftyro-login/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31491097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","javascript","laravel","login","php","sanctum","social-login","tyro"],"created_at":"2026-04-06T22:02:24.062Z","updated_at":"2026-04-06T22:02:27.515Z","avatar_url":"https://github.com/hasinhayder.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tyro Login\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://packagist.org/packages/hasinhayder/tyro-login\"\u003e\u003cimg src=\"https://img.shields.io/packagist/v/hasinhayder/tyro-login.svg?style=flat-square\" alt=\"Latest Version on Packagist\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/hasinhayder/tyro-login\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/hasinhayder/tyro-login.svg?style=flat-square\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/hasinhayder/tyro-login/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/packagist/l/hasinhayder/tyro-login.svg?style=flat-square\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://hasinhayder.github.io/tyro/tyro-login/\"\u003eWebsite\u003c/a\u003e |\n\u003ca href=\"https://hasinhayder.github.io/tyro/tyro-login/doc.html\"\u003eDocumentation\u003c/a\u003e |\n\u003ca href=\"https://github.com/hasinhayder/tyro-login\"\u003eGitHub\u003c/a\u003e\n\u003c/p\u003e\n\n**Beautiful, customizable authentication views for Laravel 12 and 13** – Tyro Login provides professional, ready-to-use login and registration pages with multiple layout options and seamless integration with the [Tyro](https://github.com/hasinhayder/tyro) package.\n\n## Features\n\n-   **Multiple Layouts** - 5 beautiful layouts: centered, split-left, split-right, fullscreen, and card\n-   **Beautiful Design** - Modern, professional UI out of the box\n-   **Social Login** - OAuth authentication with Google, Facebook, GitHub, Twitter/X, LinkedIn, Bitbucket, GitLab, and Slack\n-   **Enhanced Security** - Industry-standard security features\n    -   Encrypted OAuth token storage at rest (using Laravel's encryption)\n    -   Cryptographically secure OTP generation (Better Randomness)\n    -   Session regeneration to prevent fixation attacks (on successful login and logout)\n    -   CSRF-protected logout (only accept POST calls)\n    -   Privacy-compliant debug logging (email addresses masked)\n-   **Highly Configurable** - Customize colors, logos, redirects, and more\n-   **Lockout Protection** - Rate limiting with configurable attempts and duration\n-   **Math Captcha** - Simple addition/subtraction captcha for login and registration\n-   **Login OTP** - Two-factor authentication via email OTP codes\n-   **Email Verification** - Optional email verification for new registrations\n-   **Password Reset** - Built-in forgot password and reset functionality\n-   **Beautiful Emails** - Sleek, minimal HTML email templates for OTP, password reset, verification, and welcome emails\n-   **Tyro Integration** - Automatic role assignment for new users if Tyro is installed\n-   **Invitation/Referral System** - User-based referral links for tracking signups\n-   **Dark/Light Theme** - Automatic theme detection with manual toggle\n-   **Fully Responsive** - Works perfectly on all devices\n-   **Zero Build Step** - No npm or webpack required, just install and use\n-   **Debug Mode** - Privacy-safe debug logging for development\n\n## Requirements\n\n-   PHP 8.2 or higher\n-   Laravel 12.0 or higher\n\n## Installation\n\nInstall the package via Composer:\n\n```bash\ncomposer require hasinhayder/tyro-login\n```\n\nRun the installation command:\n\n```bash\nphp artisan tyro-login:install\n```\n\nFor social login support, use:\n\n```bash\nphp artisan tyro-login:install --with-social\n```\n\nThat's it! Visit `/login` to see your new authentication pages.\n\n**Note:** If you're updating to version 2.3.0 or later, run the migrations to set up the invitation/referral system:\n\n```bash\nphp artisan migrate\n```\n\n## Configuration\n\nAfter installation, you can customize the package by editing `config/tyro-login.php`:\n\n### Layout Options\n\n```php\n// Available layouts: 'centered', 'split-left', 'split-right', 'fullscreen', 'card'\n'layout' =\u003e env('TYRO_LOGIN_LAYOUT', 'centered'),\n\n// Background image for split and fullscreen layouts\n'background_image' =\u003e env('TYRO_LOGIN_BACKGROUND_IMAGE', 'https://...'),\n```\n\n### Branding\n\n```php\n'branding' =\u003e [\n    'app_name' =\u003e env('TYRO_LOGIN_APP_NAME', 'Laravel'),\n    'logo' =\u003e env('TYRO_LOGIN_LOGO', null), // URL to your logo\n    'logo_height' =\u003e env('TYRO_LOGIN_LOGO_HEIGHT', '48px'),\n],\n```\n\n### Redirects\n\n```php\n'redirects' =\u003e [\n    'after_login' =\u003e env('TYRO_LOGIN_REDIRECT_AFTER_LOGIN', '/'),\n    'after_logout' =\u003e env('TYRO_LOGIN_REDIRECT_AFTER_LOGOUT', '/login'),\n    'after_register' =\u003e env('TYRO_LOGIN_REDIRECT_AFTER_REGISTER', '/'),\n    'after_email_verification' =\u003e env('TYRO_LOGIN_REDIRECT_AFTER_EMAIL_VERIFICATION', '/login'),\n],\n```\n\n### Registration Settings\n\n```php\n'registration' =\u003e [\n    'enabled' =\u003e env('TYRO_LOGIN_REGISTRATION_ENABLED', true),\n    'auto_login' =\u003e env('TYRO_LOGIN_REGISTRATION_AUTO_LOGIN', true),\n    'require_email_verification' =\u003e env('TYRO_LOGIN_REQUIRE_EMAIL_VERIFICATION', false),\n],\n```\n\n### Email Verification\n\nWhen email verification is enabled, users won't be logged in automatically after registration. Instead, they'll be redirected to a verification notice page and a verification link will be generated.\n\n```php\n'registration' =\u003e [\n    'require_email_verification' =\u003e env('TYRO_LOGIN_REQUIRE_EMAIL_VERIFICATION', true),\n],\n\n'verification' =\u003e [\n    'expire' =\u003e env('TYRO_LOGIN_VERIFICATION_EXPIRE', 60), // Token expires in 60 minutes\n],\n\n'redirects' =\u003e [\n    'after_email_verification' =\u003e env('TYRO_LOGIN_REDIRECT_AFTER_EMAIL_VERIFICATION', '/login'),\n],\n```\n\n**How it works:**\n\n1. User registers - Redirected to verification notice page\n2. Verification URL is logged to Laravel logs and error_log (for development)\n3. User clicks the link - Email is verified and user is redirected to login page\n4. Users can request a new verification email from the notice page\n5. If user tries to login with unverified email, they see \"Email Not Verified\" page\n\n**For Development:** The verification URL is printed to your Laravel logs and error_log, so you can easily test without setting up email.\n\n### Password Reset\n\nTyro Login includes a complete password reset flow with beautiful, consistent UI.\n\n```php\n'password_reset' =\u003e [\n    'expire' =\u003e env('TYRO_LOGIN_PASSWORD_RESET_EXPIRE', 60), // Token expires in 60 minutes\n],\n```\n\n**How it works:**\n\n1. User clicks \"Forgot Password?\" on login page\n2. User enters email - Reset link is generated\n3. Reset URL is logged to Laravel logs and error_log (for development)\n4. User clicks the link - Shown password reset form\n5. User enters new password - Password updated and user is logged in\n\n**For Development:** The reset URL is printed to your Laravel logs and error_log, so you can easily test without setting up email.\n\n### Tyro Integration\n\nIf you have [hasinhayder/tyro](https://github.com/hasinhayder/tyro) installed, Tyro Login can automatically assign a default role to new users:\n\n```php\n'tyro' =\u003e [\n    'assign_default_role' =\u003e env('TYRO_LOGIN_ASSIGN_DEFAULT_ROLE', true),\n    'default_role_slug' =\u003e env('TYRO_LOGIN_DEFAULT_ROLE_SLUG', 'user'),\n],\n```\n\n### Math Captcha\n\nAdd a simple math captcha to your login and/or registration forms to prevent automated submissions:\n\n```php\n'captcha' =\u003e [\n    'enabled_login' =\u003e env('TYRO_LOGIN_CAPTCHA_LOGIN', false),\n    'enabled_register' =\u003e env('TYRO_LOGIN_CAPTCHA_REGISTER', false),\n    'label' =\u003e 'Security Check',\n    'placeholder' =\u003e 'Enter the answer',\n    'error_message' =\u003e 'Incorrect answer. Please try again.',\n    'min_number' =\u003e 1,\n    'max_number' =\u003e 10,\n],\n```\n\n### Login OTP Verification\n\nAdd two-factor authentication via email OTP. After entering valid credentials, users receive a one-time code:\n\n```php\n'otp' =\u003e [\n    'enabled' =\u003e env('TYRO_LOGIN_OTP_ENABLED', false),\n    'length' =\u003e 4,           // 4-8 digits\n    'expire' =\u003e 5,           // minutes\n    'max_resend' =\u003e 3,\n    'resend_cooldown' =\u003e 60, // seconds\n],\n```\n\n**Features:**\n\n-   Beautiful OTP input with individual digit boxes\n-   Configurable code length (4-8 digits)\n-   Resend functionality with cooldown\n-   Cache-based storage (no database required)\n\n### Time-Based Two-Factor Authentication (TOTP)\n\nSecure your application with Time-Based One-Time Password (TOTP) two-factor authentication, compatible with apps like Google Authenticator, Authy, and Microsoft Authenticator.\n\n#### Installation\n\n1.  **Run Migrations:**\n    This adds `two_factor_secret`, `two_factor_recovery_codes`, and `two_factor_confirmed_at` columns to your `users` table.\n\n    ```bash\n    php artisan migrate\n    ```\n\n2.  **Add Trait to User Model:**\n    Add the `HasTwoFactorAuth` trait to your User model for automatic attribute casting and encryption/decryption (optional). If this trait is not used, Tyro Login will still encrypt sensitive data using Laravel's built-in encryption.\n\n    ```php\n    use HasinHayder\\TyroLogin\\Traits\\HasTwoFactorAuth;\n\n    class User extends Authenticatable\n    {\n        use HasTwoFactorAuth;\n        \n        protected function casts(): array\n        {\n            return [\n                'password' =\u003e 'hashed',\n                'two_factor_confirmed_at' =\u003e 'datetime',\n            ];\n        }\n        \n        // ...\n        \n        protected static function booted()\n        {\n            static::created(function ($user) {\n                // Initialize the trait's casts\n                $user-\u003einitializeHasTwoFactorAuth();\n            });\n        }\n        \n        // OR simply rely on the trait's initialize method if using Laravel 10/11 standard boot\n    }\n    ```\n    *Note: The trait uses a custom cast `EncryptedOrPlaintext` to ensure secrets are stored securely.*\n\n#### Configuration\n\nEnable and configure 2FA in `config/tyro-login.php`:\n\n```php\n'two_factor' =\u003e [\n    // Enable/disable 2FA globally\n    'enabled' =\u003e env('TYRO_LOGIN_2FA_ENABLED', false),\n\n    // Page titles and subtitles\n    'setup_title' =\u003e env('TYRO_LOGIN_2FA_SETUP_TITLE', 'Two Factor Authentication'),\n    'setup_subtitle' =\u003e env('TYRO_LOGIN_2FA_SETUP_SUBTITLE', 'Scan the QR code with your authenticator app.'),\n    'challenge_title' =\u003e env('TYRO_LOGIN_2FA_CHALLENGE_TITLE', 'Two Factor Authentication'),\n    'challenge_subtitle' =\u003e env('TYRO_LOGIN_2FA_CHALLENGE_SUBTITLE', 'Enter the code from your authenticator app.'),\n    \n    // Allow users to skip setup (if false, setup is mandatory)\n    'allow_skip' =\u003e env('TYRO_LOGIN_2FA_ALLOW_SKIP', false),\n],\n```\n\n**How it works:**\n\n1.  **Mandatory Setup:** If enabled and `allow_skip` is false, new users (and existing users without 2FA) are redirected to the setup wizard immediately after login/registration.\n2.  **Secure Setup:** Users must verify a code from their authenticator app to enable 2FA.\n3.  **Recovery Codes:** Upon successful setup, users are shown a set of recovery codes that can be used if they lose access to their device.\n4.  **Challenge Screen:** On subsequent logins, users must provide a TOTP code or a recovery code.\n5.  **Security:** Secrets are encrypted in the database. Users are not fully authenticated until they pass the 2FA challenge.\n\n### Debug Mode\n\nEnable debug logging for development:\n\n```php\n'debug' =\u003e env('TYRO_LOGIN_DEBUG', false),\n```\n\nWhen enabled, OTP codes, verification URLs, and password reset URLs are logged to `storage/logs/laravel.log` in masked form.\n\n### Email Configuration\n\nTyro Login sends sleek, minimal HTML emails with a clean design. Each email type can be individually enabled or disabled:\n\n```php\n'emails' =\u003e [\n    // OTP verification email\n    'otp' =\u003e [\n        'enabled' =\u003e env('TYRO_LOGIN_EMAIL_OTP', true),\n        'subject' =\u003e env('TYRO_LOGIN_EMAIL_OTP_SUBJECT', 'Your Verification Code'),\n    ],\n\n    // Password reset email\n    'password_reset' =\u003e [\n        'enabled' =\u003e env('TYRO_LOGIN_EMAIL_PASSWORD_RESET', true),\n        'subject' =\u003e env('TYRO_LOGIN_EMAIL_PASSWORD_RESET_SUBJECT', 'Reset Your Password'),\n    ],\n\n    // Email verification email\n    'verify_email' =\u003e [\n        'enabled' =\u003e env('TYRO_LOGIN_EMAIL_VERIFY', true),\n        'subject' =\u003e env('TYRO_LOGIN_EMAIL_VERIFY_SUBJECT', 'Verify Your Email Address'),\n    ],\n\n    // Welcome email after registration\n    'welcome' =\u003e [\n        'enabled' =\u003e env('TYRO_LOGIN_EMAIL_WELCOME', true),\n        'subject' =\u003e env('TYRO_LOGIN_EMAIL_WELCOME_SUBJECT', null), // Uses default with app name\n    ],\n],\n```\n\n**Available Emails:**\n\n-   **OTP Email** - Sent when OTP verification is enabled\n-   **Password Reset Email** - Sent when user requests password reset\n-   **Email Verification Email** - Sent when email verification is required\n-   **Welcome Email** - Sent after successful registration (when verification is not required)\n\n**Customizing Email Templates:**\n\nPublish email templates to customize them:\n\n```bash\nphp artisan tyro-login:publish --emails\n```\n\nTemplates will be published to `resources/views/vendor/tyro-login/emails/`.\n\nAvailable template variables:\n\n-   `{{ $name }}` - User's name\n-   `{{ $appName }}` - Application name\n-   `{{ $otp }}` - OTP code (for OTP email)\n-   `{{ $resetUrl }}` - Password reset URL (for password reset email)\n-   `{{ $verificationUrl }}` - Verification URL (for verification email)\n-   `{{ $loginUrl }}` - Login URL (for welcome email)\n-   `{{ $expiresIn }}` - Expiration time in minutes\n\n### Lockout Protection\n\nWhen enabled, users will be locked out after too many failed login attempts. The lockout state is stored in cache (no database required), and the cache is automatically cleared when the lockout expires.\n\n```php\n'lockout' =\u003e [\n    'enabled' =\u003e env('TYRO_LOGIN_LOCKOUT_ENABLED', true),\n    'max_attempts' =\u003e env('TYRO_LOGIN_LOCKOUT_MAX_ATTEMPTS', 5),\n    'duration_minutes' =\u003e env('TYRO_LOGIN_LOCKOUT_DURATION', 15),\n    'message' =\u003e 'Too many failed login attempts. Please try again in :minutes minutes.',\n    'title' =\u003e 'Account Temporarily Locked',\n    'subtitle' =\u003e 'For your security, we\\'ve temporarily locked your account.',\n],\n```\n\n**Features:**\n\n-   No database required - uses cache\n-   Configurable number of attempts before lockout\n-   Configurable lockout duration\n-   Customizable lockout page message and title\n-   Automatic cache cleanup when lockout expires\n-   Real-time countdown timer on lockout page\n\n### Social Login (OAuth)\n\nTyro Login supports OAuth authentication using Laravel Socialite. Users can sign in with their social media accounts.\n\n**Supported Providers:**\n\n-   Google\n-   Facebook\n-   GitHub\n-   Twitter/X\n-   LinkedIn\n-   Bitbucket\n-   GitLab\n-   Slack\n\n#### Installation\n\nInstall with social login support:\n\n```bash\nphp artisan tyro-login:install --with-social\n```\n\nOr add social login to an existing installation:\n\n```bash\ncomposer require laravel/socialite\nphp artisan vendor:publish --tag=tyro-login-migrations\nphp artisan migrate\n```\n\n#### Configuration\n\n1. **Enable Social Login Globally:**\n\n```env\nTYRO_LOGIN_SOCIAL_ENABLED=true\n```\n\n2. **Enable Desired Providers:**\n\n```env\nTYRO_LOGIN_SOCIAL_GOOGLE=true\nTYRO_LOGIN_SOCIAL_GITHUB=true\nTYRO_LOGIN_SOCIAL_FACEBOOK=true\n```\n\n3. **Configure Provider Credentials:**\n\nAdd credentials to `config/services.php`:\n\n```php\n'google' =\u003e [\n    'client_id' =\u003e env('GOOGLE_CLIENT_ID'),\n    'client_secret' =\u003e env('GOOGLE_CLIENT_SECRET'),\n    'redirect' =\u003e env('GOOGLE_REDIRECT_URI'),\n],\n\n'github' =\u003e [\n    'client_id' =\u003e env('GITHUB_CLIENT_ID'),\n    'client_secret' =\u003e env('GITHUB_CLIENT_SECRET'),\n    'redirect' =\u003e env('GITHUB_REDIRECT_URI'),\n],\n\n'facebook' =\u003e [\n    'client_id' =\u003e env('FACEBOOK_CLIENT_ID'),\n    'client_secret' =\u003e env('FACEBOOK_CLIENT_SECRET'),\n    'redirect' =\u003e env('FACEBOOK_REDIRECT_URI'),\n],\n\n// For Twitter/X (OAuth 2.0)\n'twitter' =\u003e [\n    'client_id' =\u003e env('TWITTER_CLIENT_ID'),\n    'client_secret' =\u003e env('TWITTER_CLIENT_SECRET'),\n    'redirect' =\u003e env('TWITTER_REDIRECT_URI'),\n],\n\n// For LinkedIn (OpenID Connect)\n'linkedin-openid' =\u003e [\n    'client_id' =\u003e env('LINKEDIN_CLIENT_ID'),\n    'client_secret' =\u003e env('LINKEDIN_CLIENT_SECRET'),\n    'redirect' =\u003e env('LINKEDIN_REDIRECT_URI'),\n],\n\n// For Slack (OpenID Connect)\n'slack-openid' =\u003e [\n    'client_id' =\u003e env('SLACK_CLIENT_ID'),\n    'client_secret' =\u003e env('SLACK_CLIENT_SECRET'),\n    'redirect' =\u003e env('SLACK_REDIRECT_URI'),\n],\n```\n\n4. **Add Environment Variables:**\n\n```env\n# Google\nGOOGLE_CLIENT_ID=your-client-id\nGOOGLE_CLIENT_SECRET=your-client-secret\nGOOGLE_REDIRECT_URI=\"${APP_URL}/auth/google/callback\"\n\n# GitHub\nGITHUB_CLIENT_ID=your-client-id\nGITHUB_CLIENT_SECRET=your-client-secret\nGITHUB_REDIRECT_URI=\"${APP_URL}/auth/github/callback\"\n\n# Facebook\nFACEBOOK_CLIENT_ID=your-client-id\nFACEBOOK_CLIENT_SECRET=your-client-secret\nFACEBOOK_REDIRECT_URI=\"${APP_URL}/auth/facebook/callback\"\n\n# Slack\nSLACK_CLIENT_ID=your-client-id\nSLACK_CLIENT_SECRET=your-client-secret\nSLACK_REDIRECT_URI=\"${APP_URL}/auth/slack/callback\"\n```\n\n#### Social Login Behavior\n\n```php\n'social' =\u003e [\n    'enabled' =\u003e env('TYRO_LOGIN_SOCIAL_ENABLED', false),\n\n    // Link social accounts to existing users (matched by email)\n    'link_existing_accounts' =\u003e env('TYRO_LOGIN_SOCIAL_LINK_EXISTING', true),\n\n    // Automatically create new users from social login\n    'auto_register' =\u003e env('TYRO_LOGIN_SOCIAL_AUTO_REGISTER', true),\n\n    // Automatically verify user email after social login/register\n    // Social providers confirm email ownership, so we can trust the email\n    'auto_verify_email' =\u003e env('TYRO_LOGIN_SOCIAL_AUTO_VERIFY_EMAIL', true),\n\n    // Text shown above social buttons\n    'divider_text' =\u003e env('TYRO_LOGIN_SOCIAL_DIVIDER', 'Or continue with'),\n],\n```\n\n**How it works:**\n\n1. User clicks a social login button on login/register page\n2. User is redirected to the OAuth provider for authentication\n3. After approval, user is redirected back to your app\n4. If user has linked social account → Log them in\n5. If user email exists and linking is enabled → Link social account and log in\n6. If user doesn't exist and auto-register is enabled → Create new user and log in\n\n**Automatic Email Verification:**\n\nWhen users authenticate via social login, their email is automatically marked as verified (if `auto_verify_email` is enabled). This is because OAuth providers confirm email ownership during the authentication process, so we can trust the email address provided.\n\n**Social Accounts Table:**\n\nA migration creates the `social_accounts` table to store:\n\n-   `user_id` - Link to your users table\n-   `provider` - The OAuth provider (google, github, etc.)\n-   `provider_user_id` - User ID from the provider\n-   `provider_email` - Email from the provider\n-   `provider_avatar` - Avatar URL from the provider\n-   `access_token` / `refresh_token` - OAuth tokens (encrypted)\n-   `token_expires_at` - Token expiration time\n\n#### Customizing Provider Labels and Icons\n\n```php\n'social' =\u003e [\n    'providers' =\u003e [\n        'google' =\u003e [\n            'enabled' =\u003e true,\n            'label' =\u003e 'Google',  // Button text\n            'icon' =\u003e 'google',   // Icon identifier\n        ],\n        'github' =\u003e [\n            'enabled' =\u003e true,\n            'label' =\u003e 'GitHub',\n            'icon' =\u003e 'github',\n        ],\n    ],\n],\n```\n\n## Invitation/Referral System\n\nTyro Login includes a built-in invitation/referral system that allows users to invite others to sign up. Each user can create one unique invitation link that tracks all signups made through it.\n\n### Note \nFor versions older than 2.3.0, run `composer update` to fetch the latest files for the invitation system, then execute `php artisan migrate` to create the necessary database tables.\n\n### Features\n\n-   **One Link Per User** - Each user can have exactly one invitation link\n-   **Automatic Tracking** - Referral signups are automatically tracked during registration\n-   **Silent Invalid Links** - Invalid or non-existing invitation hashes are silently ignored (no errors)\n-   **Prevent Self-Referrals** - Users cannot use their own invitation link\n-   **Prevent Duplicates** - Each user can only be referred once\n-   **Database Backed** - Uses two lightweight tables for persistence\n\n### Database Tables\n\n-   `invitation_links` - Stores unique invitation links for users\n-   `invitation_referrals` - Tracks signups through invitation links\n\n### CLI Commands\n\nManage invitation links using the console command:\n\n```bash\n# Create a new invitation link for a user\nphp artisan tyro-login:invite-links --create\n# or simply\nphp artisan tyro-login:invite-links\n\n# List all invitation links with referral counts\nphp artisan tyro-login:invite-links --list\n\n# Remove a user's invitation link\n# (warns if there are referral signups)\nphp artisan tyro-login:invite-links --remove\n\n# Remove all invitation links\n# (requires confirmation)\nphp artisan tyro-login:invite-links --flush\n```\n\n### Integration in Your Application\n\nThe registration controller automatically tracks referrals. Users can access invitation links via a query parameter:\n\n```\nhttps://your-app.com/register?invite={hash}\n```\n\n**Important:** You don't need to do anything special - Tyro Login handles referral tracking automatically during user registration.\n\n### Using the Helper Class\n\nAccess invitation data programmatically:\n\n```php\nuse HasinHayder\\TyroLogin\\Helpers\\InvitationHelper;\n\n// Get a user's invitation link\n$invitationLink = InvitationHelper::getInvitationLinkForUser($userId);\nif ($invitationLink) {\n    echo $invitationLink-\u003eurl; // Full URL: /register?invite={hash}\n}\n\n// Get referral count for a user\n$count = InvitationHelper::getReferralCount($userId);\n\n// Get all users referred by a specific user\n$referredUsers = InvitationHelper::getReferredUsers($userId);\n\n// Validate and track a referral manually\nInvitationHelper::trackReferral($invitationHash, $newUserId);\n```\n\n### Models\n\nAccess invitation data through Eloquent models:\n\n```php\nuse HasinHayder\\TyroLogin\\Models\\InvitationLink;\nuse HasinHayder\\TyroLogin\\Models\\InvitationReferral;\n\n// Get invitation link with relationships\n$link = InvitationLink::with('user', 'referrals')-\u003efind($id);\n\n// Get referral with relationships\n$referral = InvitationReferral::with('invitationLink', 'referredUser')-\u003efind($id);\n```\n\n## Layout Examples\n\nTyro Login provides 5 stunning layout options to match your application's branding:\n\n### 1. Centered Layout (Default)\n\nForm appears in the center of the page with a gradient background.\n\n```env\nTYRO_LOGIN_LAYOUT=centered\n```\n\n### 2. Split-Left Layout\n\nTwo-column layout with a background image on the left and the form on the right.\n\n```env\nTYRO_LOGIN_LAYOUT=split-left\nTYRO_LOGIN_BACKGROUND_IMAGE=https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=1920\u0026q=80\n```\n\n### 3. Split-Right Layout\n\nTwo-column layout with the form on the left and a background image on the right.\n\n```env\nTYRO_LOGIN_LAYOUT=split-right\nTYRO_LOGIN_BACKGROUND_IMAGE=https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=1920\u0026q=80\n```\n\n### 4. Fullscreen Layout\n\nFull-screen background image with a glassmorphism form overlay featuring frosted glass effect and backdrop blur.\n\n```env\nTYRO_LOGIN_LAYOUT=fullscreen\nTYRO_LOGIN_BACKGROUND_IMAGE=https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=1920\u0026q=80\n```\n\n### 5. Card Layout\n\nFloating card design with subtle radial gradient background patterns and smooth hover animations.\n\n```env\nTYRO_LOGIN_LAYOUT=card\n```\n\n**All layouts support:**\n\n-   Dark and light themes\n-   Fully responsive design\n-   Customizable branding\n-   All authentication features (OTP, captcha, email verification, etc.)\n\n## Customization\n\n### Publishing Views\n\nTo customize the views, publish them to your application:\n\n```bash\nphp artisan tyro-login:publish --views\n```\n\nViews will be published to `resources/views/vendor/tyro-login/`.\n\n### Publishing Email Templates\n\nTo customize the email templates:\n\n```bash\nphp artisan tyro-login:publish --emails\n```\n\nEmail templates will be published to `resources/views/vendor/tyro-login/emails/`.\n\n### Publishing Everything\n\n```bash\nphp artisan tyro-login:publish\n```\n\nThis publishes config, views, email templates, and assets.\n\n### Theme Customization (shadcn Variables)\n\nTyro Login uses [shadcn/ui](https://ui.shadcn.com) CSS variables for theming, making it easy to customize colors and integrate with shadcn-based projects.\n\n#### Publishing Theme Files\n\nPublish the theme variables to customize the look and feel:\n\n```bash\n# Publish only theme variables (recommended for color customization)\nphp artisan tyro-login:publish-style --theme-only\n\n# Or publish complete styles (theme + component styles)\nphp artisan tyro-login:publish-style\n```\n\nTheme files will be published to `resources/views/vendor/tyro-login/partials/`.\n\n#### Visual Theme Editing with tweakcn (free)\n\nThe easiest way to customize your theme is using [tweakcn.com](https://tweakcn.com):\n\n1. Visit [tweakcn.com](https://tweakcn.com)\n2. Use the visual editor to create your perfect color palette\n3. Copy the generated CSS variables\n4. Publish your theme: `php artisan tyro-login:publish-style --theme-only`\n5. Paste the variables into `resources/views/vendor/tyro-login/partials/shadcn-theme.blade.php`\n\n#### Theme File Structure\n\nAfter publishing, your theme structure will be:\n\n```\nresources/views/vendor/tyro-login/partials/\n├── shadcn-theme.blade.php  # Theme variables (edit this!)\n└── styles.blade.php        # Component styles (includes theme)\n```\n\nThe `shadcn-theme.blade.php` file contains only CSS variables, making it safe to edit without breaking component styles.\n\n## Artisan Commands\n\nTyro Login provides several artisan commands:\n\n| Command                                             | Description                                           |\n| --------------------------------------------------- | ----------------------------------------------------- |\n| `php artisan tyro-login:install`                    | Install the package and publish configuration         |\n| `php artisan tyro-login:install --with-social`      | Install with social login (Laravel Socialite) support |\n| `php artisan tyro-login:publish`                    | Publish config, views, email templates, and assets    |\n| `php artisan tyro-login:publish --emails`           | Publish only email templates                          |\n| `php artisan tyro-login:publish-style`              | Publish styles (theme + components)                   |\n| `php artisan tyro-login:publish-style --theme-only` | Publish only theme variables                          |\n| `php artisan tyro-login:verify-user`                | Mark a user's email as verified                       |\n| `php artisan tyro-login:unverify-user`              | Remove email verification from a user                 |\n| `php artisan tyro-login:version`                    | Display the current Tyro Login version                |\n| `php artisan tyro-login:doc`                        | Open the documentation in your browser                |\n| `php artisan tyro-login:star`                       | Open GitHub repository to star the project            |\n\n### User Verification Commands\n\nTyro Login provides commands to manually verify or unverify user email addresses.\n\n**Verify a single user by email:**\n\n```bash\nphp artisan tyro-login:verify-user john@example.com\n```\n\n**Verify a single user by ID:**\n\n```bash\nphp artisan tyro-login:verify-user 123\n```\n\n**Verify all unverified users:**\n\n```bash\nphp artisan tyro-login:verify-user --all\n```\n\n**Unverify a single user:**\n\n```bash\nphp artisan tyro-login:unverify-user john@example.com\n```\n\n**Unverify all verified users:**\n\n```bash\nphp artisan tyro-login:unverify-user --all\n```\n\n**Reset 2FA for a user:**\n\nCurrently locked out users or those who lost their device/codes can have their 2FA reset by an admin:\n\n```bash\nphp artisan tyro-login:reset-2fa user@example.com\n# OR\nphp artisan tyro-login:reset-2fa 1\n```\n\nThese commands are useful for:\n\n-   Manually verifying users during development or testing\n-   Bulk verification of imported users\n-   Resetting verification status for testing email flows\n\n## Routes\n\nTyro Login registers the following routes:\n\n| Method   | URI                         | Name                                   | Description                |\n| -------- | --------------------------- | -------------------------------------- | -------------------------- |\n| GET      | `/login`                    | `tyro-login.login`                     | Show login form            |\n| POST     | `/login`                    | `tyro-login.login.submit`              | Handle login               |\n| GET      | `/register`                 | `tyro-login.register`                  | Show registration form     |\n| POST     | `/register`                 | `tyro-login.register.submit`           | Handle registration        |\n| GET/POST | `/logout`                   | `tyro-login.logout`                    | Handle logout              |\n| GET      | `/lockout`                  | `tyro-login.lockout`                   | Show lockout page          |\n| GET      | `/email/verify`             | `tyro-login.verification.notice`       | Show verification notice   |\n| GET      | `/email/not-verified`       | `tyro-login.verification.not-verified` | Show unverified email page |\n| GET      | `/email/verify/{token}`     | `tyro-login.verification.verify`       | Verify email               |\n| POST     | `/email/resend`             | `tyro-login.verification.resend`       | Resend verification email  |\n| GET      | `/forgot-password`          | `tyro-login.password.request`          | Show forgot password form  |\n| POST     | `/forgot-password`          | `tyro-login.password.email`            | Send reset link            |\n| GET      | `/reset-password/{token}`   | `tyro-login.password.reset`            | Show reset form            |\n| POST     | `/reset-password`           | `tyro-login.password.update`           | Reset password             |\n| GET      | `/otp/verify`               | `tyro-login.otp.verify`                | Show OTP form              |\n| POST     | `/otp/verify`               | `tyro-login.otp.submit`                | Verify OTP                 |\n| POST     | `/otp/resend`               | `tyro-login.otp.resend`                | Resend OTP                 |\n| GET      | `/otp/cancel`               | `tyro-login.otp.cancel`                | Cancel OTP verification    |\n| GET      | `/auth/{provider}/redirect` | `tyro-login.social.redirect`           | Redirect to OAuth provider |\n| GET      | `/auth/{provider}/callback` | `tyro-login.social.callback`           | Handle OAuth callback      |\n\n### Customizing Route Prefix\n\n```php\n'routes' =\u003e [\n    'prefix' =\u003e env('TYRO_LOGIN_ROUTE_PREFIX', 'auth'),\n    // Routes will be: /auth/login, /auth/register, etc.\n],\n```\n\n## Security Features\n\nTyro Login implements industry-standard security practices:\n\n-   **Encrypted Data Storage**\n    -   OAuth access and refresh tokens encrypted at rest using Laravel's encryption\n    -   Custom `EncryptedOrPlaintext` cast for seamless migration\n    -   Protects against database compromise\n-   **Cryptographically Secure Random**\n    -   OTP codes generated using `random_int()` (cryptographically secure)\n    -   Eliminates predictable patterns and statistical analysis attacks\n-   **Session Security**\n    -   Session regeneration after logout in OTP flow prevents fixation attacks\n    -   Session regeneration on successful login prevents session fixation\n    -   Secure session handling throughout authentication flows\n-   **CSRF Protection**\n    -   All forms include CSRF tokens\n    -   Logout requires POST request with CSRF token\n    -   Protection against cross-site request forgery attacks\n-   **Lockout Protection**\n    -   Temporarily lock accounts after failed attempts (cache-based, no database)\n    -   Configurable attempts and duration\n    -   Automatic cache cleanup when lockout expires\n-   **Email Verification**\n    -   Optional email verification for new registrations\n    -   Secure signed URLs with expiration\n    -   Automatic verification via social login\n-   **Secure Password Reset**\n    -   Time-limited, signed URLs for password reset\n    -   Tokens stored in cache with expiration\n    -   Automatic token cleanup\n-   **Password Security**\n    -   Laravel's bcrypt/argon2 hashing\n    -   Configurable minimum password length\n    -   Password confirmation requirement\n-   **Privacy-Safe Debug Logging**\n    -   Email addresses masked in logs (e.g., `use***@example.com`)\n    -   No security tokens or sensitive URLs logged\n    -   GDPR/CCPA compliant logging\n    -   Structured logging format\n-   **Input Validation**\n    -   Server-side validation with proper error messages\n    -   Protection against malicious input\n    -   Email format validation\n\n## Integration with Tyro\n\nTyro Login integrates seamlessly with the [Tyro](https://github.com/hasinhayder/tyro) package:\n\n1. When a new user registers, Tyro Login can automatically assign a default role\n2. Configure the default role slug in your config\n3. Ensure your User model uses the `HasTyroRoles` trait\n\n```php\n// In your User model\nuse HasinHayder\\Tyro\\Concerns\\HasTyroRoles;\n\nclass User extends Authenticatable\n{\n    use HasTyroRoles;\n}\n```\n\n## Changelog\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Security\n\nIf you discover any security-related issues, please email hasin@hasin.me instead of using the issue tracker.\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE) for more information.\n\n## Credits\n\n-   [Hasin Hayder](https://github.com/hasinhayder)\n\n---\n\n\u003cp align=\"center\"\u003e\nMade with love for the Laravel community by Hasin Hayder\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhasinhayder%2Ftyro-login","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhasinhayder%2Ftyro-login","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhasinhayder%2Ftyro-login/lists"}