ssntpl / neev
Enterprise-grade user authentication, team management, and multi-tenancy for Laravel SaaS applications.
Fund package maintenance!
ssntpl
Installs: 5
Dependents: 0
Suggesters: 0
Security: 0
Stars: 2
Watchers: 0
Forks: 0
Open Issues: 3
pkg:composer/ssntpl/neev
Requires
- php: ^8.3
- bacon/bacon-qr-code: ^3.0
- geoip2/geoip2: ^3.3
- laravel/framework: ^11.0|^12.0
- laravel/socialite: ^5.23
- spomky-labs/otphp: ^11.3
- ssntpl/laravel-acl: ^0.2
- web-auth/webauthn-lib: ^5.2
Requires (Dev)
- larastan/larastan: ^2.0|^3.0
- laravel/pint: ^1.0
- mockery/mockery: ^1.6
- orchestra/testbench: ^9.0|^10.0
- phpunit/phpunit: ^10.5|^11.0
This package is auto-updated.
Last update: 2026-02-27 11:54:42 UTC
README
Neev is a comprehensive Laravel package that provides enterprise-grade user authentication, team management, and security features. It's designed as a complete starter kit for SaaS applications, eliminating the need to build complex user management systems from scratch.
Table of Contents
- Features
- Quick Start
- Authentication Methods
- API Reference
- Web Routes
- Multi-Factor Authentication
- Team Management
- Multi-Tenancy
- Security Features
- Configuration
- Console Commands
- Database Schema
- Detailed Documentation
Features
Authentication Methods
- Password-based login with strong password policies
- Magic link authentication (passwordless login via email)
- Passkey/WebAuthn support (biometric authentication, hardware keys)
- OAuth/Social login (Google, GitHub, Microsoft, Apple)
- Tenant SSO (Microsoft Entra ID, Google Workspace, Okta)
Multi-Factor Authentication
- TOTP authenticator apps (Google Authenticator, Authy, 1Password)
- Email OTP (6-digit codes via email)
- Recovery codes (single-use backup codes)
Team Management
- Create and manage teams/organizations
- Invite members via email
- Role-based access control
- Domain-based auto-joining (federation)
- Team switching for multi-team users
Security Features
- Brute force protection with progressive delays
- Account lockout after failed attempts
- Password history to prevent reuse
- Password expiry policies
- Login attempt tracking with GeoIP
- Session management
- Suspicious login detection
Multi-Tenancy
- Subdomain-based tenant isolation
- Custom domain support with DNS verification
- Per-tenant authentication configuration
- Per-tenant SSO integration
Quick Start
1. Install via Composer
composer require ssntpl/neev
2. Run the Installation Command
php artisan neev:install
3. Configure Environment
NEEV_DASHBOARD_URL="${APP_URL}/dashboard" MAXMIND_LICENSE_KEY="your-maxmind-key"
4. Run Migrations
php artisan migrate
5. Update Your User Model
use Ssntpl\Neev\Traits\HasTeams; use Ssntpl\Neev\Traits\HasMultiAuth; use Ssntpl\Neev\Traits\HasAccessToken; class User extends Authenticatable { use HasTeams, HasMultiAuth, HasAccessToken; }
Authentication Methods
Password Authentication
# Register curl -X POST https://yourapp.com/neev/register \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "email": "john@example.com", "password": "SecurePass123!", "password_confirmation": "SecurePass123!" }' # Login curl -X POST https://yourapp.com/neev/login \ -H "Content-Type: application/json" \ -d '{ "email": "john@example.com", "password": "SecurePass123!" }'
Response:
{
"status": "Success",
"token": "1|abc123def456...",
"email_verified": true,
"preferred_mfa": null
}
Magic Link (Passwordless)
# Send login link curl -X POST https://yourapp.com/neev/sendLoginLink \ -d '{"email": "john@example.com"}' # Login via link curl -X GET "https://yourapp.com/neev/loginUsingLink?id=1&signature=..."
Passkey / WebAuthn
# Get registration options curl -X GET https://yourapp.com/neev/passkeys/register/options \ -H "Authorization: Bearer {token}" # Register passkey curl -X POST https://yourapp.com/neev/passkeys/register \ -H "Authorization: Bearer {token}" \ -d '{"attestation": "{...}", "name": "My MacBook"}' # Login with passkey curl -X POST https://yourapp.com/neev/passkeys/login \ -d '{"email": "john@example.com", "assertion": "{...}"}'
OAuth / Social Login
Enable in configuration:
// config/neev.php 'oauth' => ['google', 'github', 'microsoft', 'apple'],
Redirect URLs:
GET /oauth/{provider}- Redirect to providerGET /oauth/{provider}/callback- Handle callback
API Reference
All API routes are prefixed with /neev. Include the Bearer token for authenticated endpoints.
Authentication Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /neev/register |
Register new user | No |
| POST | /neev/login |
Login with credentials | No |
| POST | /neev/sendLoginLink |
Send magic link | No |
| GET | /neev/loginUsingLink |
Login via magic link | No |
| POST | /neev/logout |
Logout current session | Yes |
| POST | /neev/logoutAll |
Logout all sessions | Yes |
| POST | /neev/forgotPassword |
Reset password with OTP | No |
Email Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /neev/email/send |
Send verification email | Yes |
| GET | /neev/email/verify |
Verify email address | Yes |
| POST | /neev/email/update |
Update email address | Yes |
| POST | /neev/email/otp/send |
Send email OTP | No |
| POST | /neev/email/otp/verify |
Verify email OTP | No |
| POST | /neev/emails |
Add email address | Yes |
| DELETE | /neev/emails |
Delete email address | Yes |
| PUT | /neev/emails |
Set primary email | Yes |
MFA Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /neev/mfa/add |
Enable MFA method | Yes |
| DELETE | /neev/mfa/delete |
Disable MFA method | Yes |
| POST | /neev/mfa/otp/verify |
Verify MFA code | MFA Token |
| POST | /neev/recoveryCodes |
Generate recovery codes | Yes |
Passkey Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /neev/passkeys/register/options |
Get registration options | Yes |
| POST | /neev/passkeys/register |
Register passkey | Yes |
| POST | /neev/passkeys/login/options |
Get login options | No |
| POST | /neev/passkeys/login |
Login with passkey | No |
| PUT | /neev/passkeys |
Update passkey name | Yes |
| DELETE | /neev/passkeys |
Delete passkey | Yes |
User Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /neev/users |
Get current user | Yes |
| PUT | /neev/users |
Update user profile | Yes |
| DELETE | /neev/users |
Delete user account | Yes |
| PUT | /neev/changePassword |
Change password | Yes |
| GET | /neev/sessions |
Get active sessions | Yes |
| GET | /neev/loginAttempts |
Get login history | Yes |
API Token Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /neev/apiTokens |
List API tokens | Yes |
| POST | /neev/apiTokens |
Create API token | Yes |
| PUT | /neev/apiTokens |
Update API token | Yes |
| DELETE | /neev/apiTokens |
Delete API token | Yes |
| DELETE | /neev/apiTokens/deleteAll |
Delete all API tokens | Yes |
Team Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /neev/teams |
List user's teams | Yes |
| GET | /neev/teams/{id} |
Get team details | Yes |
| POST | /neev/teams |
Create team | Yes |
| PUT | /neev/teams |
Update team | Yes |
| DELETE | /neev/teams |
Delete team | Yes |
| POST | /neev/changeTeamOwner |
Transfer ownership | Yes |
| POST | /neev/teams/inviteUser |
Invite member | Yes |
| PUT | /neev/teams/inviteUser |
Accept/reject invitation | Yes |
| PUT | /neev/teams/leave |
Leave team | Yes |
| POST | /neev/teams/request |
Request to join | Yes |
| PUT | /neev/teams/request |
Accept/reject request | Yes |
| PUT | /neev/role/change |
Change member role | Yes |
Domain Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /neev/domains |
List team domains | Yes |
| POST | /neev/domains |
Add domain | Yes |
| PUT | /neev/domains |
Update/verify domain | Yes |
| DELETE | /neev/domains |
Delete domain | Yes |
| GET | /neev/domains/rules |
Get domain rules | Yes |
| PUT | /neev/domains/rules |
Update domain rules | Yes |
| PUT | /neev/domains/primary |
Set primary domain | Yes |
Tenant Domain Endpoints
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /neev/tenant-domains |
List tenant domains | Yes |
| POST | /neev/tenant-domains |
Add custom domain | Yes |
| GET | /neev/tenant-domains/{id} |
Get domain details | Yes |
| DELETE | /neev/tenant-domains/{id} |
Delete domain | Yes |
| POST | /neev/tenant-domains/{id}/verify |
Verify domain | Yes |
| POST | /neev/tenant-domains/{id}/primary |
Set as primary | Yes |
Web Routes
Public Routes
| Method | Route | Name | Description |
|---|---|---|---|
| GET | /register |
register |
Registration form |
| POST | /register |
- | Process registration |
| GET | /login |
login |
Login form |
| PUT | /login |
login.password |
Show password form |
| POST | /login |
- | Process login |
| POST | /login/link |
login.link.send |
Send magic link |
| GET | /login/{id} |
login.link |
Login via magic link |
| GET | /forgot-password |
password.request |
Forgot password form |
| POST | /forgot-password |
password.email |
Send reset link |
| GET | /update-password/{id}/{hash} |
reset.request |
Reset password form |
| POST | /update-password |
user-password.update |
Process reset |
| GET | /otp/mfa/{method} |
otp.mfa.create |
MFA verification |
| POST | /otp/mfa |
otp.mfa.store |
Verify MFA code |
| GET | /oauth/{service} |
oauth.redirect |
OAuth redirect |
| GET | /oauth/{service}/callback |
oauth.callback |
OAuth callback |
| GET | /sso/redirect |
sso.redirect |
Tenant SSO redirect |
| GET | /sso/callback |
sso.callback |
Tenant SSO callback |
Authenticated Routes (neev:web middleware)
| Method | Route | Name | Description |
|---|---|---|---|
| GET | /email/verify |
verification.notice |
Verification pending |
| GET | /email/send |
email.verification.send |
Resend verification |
| GET | /email/change |
email.change |
Change email form |
| PUT | /email/change |
email.update |
Process email change |
| POST | /logout |
logout |
Logout |
Account Routes (/account prefix)
| Method | Route | Name | Description |
|---|---|---|---|
| GET | /account/profile |
account.profile |
Profile page |
| GET | /account/emails |
account.emails |
Email management |
| GET | /account/security |
account.security |
Security settings |
| GET | /account/tokens |
account.tokens |
API tokens |
| GET | /account/teams |
account.teams |
Teams list |
| GET | /account/sessions |
account.sessions |
Active sessions |
| GET | /account/loginAttempts |
account.loginAttempts |
Login history |
| PUT | /account/profileUpdate |
profile.update |
Update profile |
| POST | /account/change-password |
password.change |
Change password |
| POST | /account/multiFactorAuth |
multi.auth |
Add MFA |
| PUT | /account/multiFactorAuth |
multi.preferred |
Set preferred MFA |
| GET | /account/recovery/codes |
recovery.codes |
View recovery codes |
| POST | /account/recovery/codes |
recovery.generate |
Generate new codes |
| POST | /account/passkeys/register/options |
passkeys.register.options |
Passkey options |
| POST | /account/passkeys/register |
passkeys.register |
Register passkey |
| DELETE | /account/passkeys |
passkeys.delete |
Delete passkey |
| POST | /account/logoutSessions |
logout.sessions |
Logout other sessions |
Team Routes (/teams prefix)
| Method | Route | Name | Description |
|---|---|---|---|
| GET | /teams/create |
teams.create |
Create team form |
| POST | /teams/create |
teams.store |
Store new team |
| GET | /teams/{team}/profile |
teams.profile |
Team profile |
| GET | /teams/{team}/members |
teams.members |
Team members |
| GET | /teams/{team}/domain |
teams.domain |
Domain settings |
| GET | /teams/{team}/settings |
teams.settings |
Team settings |
| PUT | /teams/switch |
teams.switch |
Switch team |
| PUT | /teams/update |
teams.update |
Update team |
| DELETE | /teams/delete |
teams.delete |
Delete team |
| PUT | /teams/members/invite |
teams.invite |
Invite member |
| PUT | /teams/members/invite/action |
teams.invite.action |
Accept/reject |
| DELETE | /teams/members/leave |
teams.leave |
Leave team |
| POST | /teams/members/request |
teams.request |
Request to join |
| PUT | /teams/members/request/action |
teams.request.action |
Accept/reject request |
| PUT | /teams/owner/change |
teams.owner.change |
Transfer ownership |
| PUT | /teams/roles/change |
teams.roles.change |
Change role |
Multi-Factor Authentication
Enable Authenticator App
// Returns QR code and secret $result = $user->addMultiFactorAuth('authenticator'); // $result['qr_code'] - SVG QR code // $result['secret'] - TOTP secret
Enable Email OTP
$user->addMultiFactorAuth('email');
Verify MFA
if ($user->verifyMFAOTP('authenticator', '123456')) { // MFA verified }
Recovery Codes
// Generate 8 recovery codes $codes = $user->generateRecoveryCodes(); // Store these securely - shown only once!
API Usage
# Enable MFA curl -X POST https://yourapp.com/neev/mfa/add \ -H "Authorization: Bearer {token}" \ -d '{"auth_method": "authenticator"}' # Verify MFA during login curl -X POST https://yourapp.com/neev/mfa/otp/verify \ -H "Authorization: Bearer {mfa_token}" \ -d '{"auth_method": "authenticator", "otp": "123456"}'
Team Management
Create Team
$team = Team::create([ 'name' => 'My Company', 'user_id' => auth()->id(), 'is_public' => false, ]);
User's Teams
$user->teams; // Teams user belongs to $user->ownedTeams; // Teams user owns $user->teamRequests; // Pending invitations $user->switchTeam($team); // Switch active team
Team Relationships
$team->owner; // Team owner $team->users; // Team members $team->invitedUsers; // Pending invitations $team->joinRequests; // Join requests $team->domains; // Federated domains
API Usage
# Create team curl -X POST https://yourapp.com/neev/teams \ -H "Authorization: Bearer {token}" \ -d '{"name": "My Team", "public": false}' # Invite member curl -X POST https://yourapp.com/neev/teams/inviteUser \ -H "Authorization: Bearer {token}" \ -d '{"team_id": 1, "email": "user@example.com", "role": "member"}' # Accept invitation curl -X PUT https://yourapp.com/neev/teams/inviteUser \ -H "Authorization: Bearer {token}" \ -d '{"team_id": 1, "action": "accept"}'
Multi-Tenancy
Enable Tenant Isolation
// config/neev.php 'team' => true, 'tenant_isolation' => true, 'tenant_isolation_options' => [ 'subdomain_suffix' => env('NEEV_SUBDOMAIN_SUFFIX', '.yourapp.com'), 'allow_custom_domains' => true, 'single_tenant_users' => false, ],
Tenant SSO
// config/neev.php 'tenant_auth' => true, 'tenant_auth_options' => [ 'default_method' => 'password', 'sso_providers' => ['entra', 'google', 'okta'], 'auto_provision' => true, ],
Get Tenant Auth Config
curl -X GET https://acme.yourapp.com/api/tenant/auth
Response:
{
"auth_method": "sso",
"sso_enabled": true,
"sso_provider": "entra",
"sso_redirect_url": "https://acme.yourapp.com/sso/redirect"
}
Middleware Groups
| Middleware | Description |
|---|---|
neev:web |
Web authentication (includes tenant resolution when enabled) |
neev:api |
API authentication (includes tenant resolution when enabled) |
neev:tenant |
Tenant resolution from domain (no auth) |
Middleware Aliases
| Alias | Description |
|---|---|
neev:active-team |
Blocks access when team is inactive/waitlisted |
neev:tenant-member |
Ensures user is a member of the current tenant |
neev:resolve-team |
Resolves team from route parameter |
neev:ensure-sso |
Enforces SSO-only access for the current context |
Security Features
Brute Force Protection
// config/neev.php 'login_soft_attempts' => 5, // Delays start 'login_hard_attempts' => 20, // Lockout 'login_block_minutes' => 1, // Lockout duration
Password Policies
// config/neev.php 'password' => [ 'required', 'confirmed', Password::min(8)->max(72)->letters()->mixedCase()->numbers()->symbols(), PasswordHistory::notReused(5), PasswordUserData::notContain(['name', 'email']), ], 'password_soft_expiry_days' => 30, // Warning 'password_hard_expiry_days' => 90, // Forced change
Login Tracking
Each login attempt records:
- Login method (password, passkey, sso, etc.)
- MFA method used
- IP address and geolocation
- Browser, platform, device
- Success/failure status
GeoIP Setup
# Get MaxMind license key from maxmind.com # Add to .env: MAXMIND_LICENSE_KEY=your-key # Download database php artisan neev:download-geoip
Configuration
Feature Toggles
// config/neev.php 'team' => true, // Team management 'email_verified' => true, // Require verification 'require_company_email' => false, // Waitlist free emails 'domain_federation' => true, // Domain-based joining 'identity_strategy' => 'shared', // 'shared' or 'isolated' 'tenant_isolation' => false, // Multi-tenancy 'tenant_auth' => false, // Per-tenant auth 'support_username' => false, // Username login 'magicauth' => true, // Magic link login
URLs
'dashboard_url' => env('NEEV_DASHBOARD_URL', env('APP_URL').'/dashboard'), 'frontend_url' => env('APP_URL'),
MFA
'multi_factor_auth' => ['authenticator', 'email'], 'recovery_codes' => 8, 'otp_expiry_time' => 15, // minutes
OAuth Providers
'oauth' => [ 'google', 'github', 'microsoft', 'apple', ],
Token Expiry
'url_expiry_time' => 60, // Magic links, reset links 'otp_expiry_time' => 15, // OTP codes
Console Commands
Setup
php artisan neev:install # Interactive setup php artisan neev:download-geoip # Download GeoIP database
Maintenance
php artisan neev:clean-login-attempts # Clean old login records php artisan neev:clean-passwords # Clean password history
Scheduled Tasks
// app/Console/Kernel.php protected function schedule(Schedule $schedule) { $schedule->command('neev:clean-login-attempts')->daily(); $schedule->command('neev:clean-passwords')->weekly(); $schedule->command('neev:download-geoip')->monthly(); }
Database Schema
Core Tables
| Table | Description |
|---|---|
users |
User accounts |
emails |
Multiple emails per user |
passwords |
Password history |
otps |
One-time passwords |
passkeys |
WebAuthn credentials |
multi_factor_auths |
MFA configurations |
recovery_codes |
MFA backup codes |
access_tokens |
API and login tokens |
login_attempts |
Login history |
Team Tables
| Table | Description |
|---|---|
teams |
Teams/organizations |
team_user |
Team-user membership pivot table |
team_invitations |
Pending invitations |
domains |
Email domain federation |
domain_rules |
Domain security rules |
Tenant Tables
| Table | Description |
|---|---|
tenants |
Tenant organizations (isolated identity mode) |
domains |
Custom tenant domains and domain federation |
team_auth_settings |
Per-team auth/SSO config |
tenant_auth_settings |
Per-tenant auth/SSO config (isolated mode) |
Detailed Documentation
For comprehensive documentation, see the docs folder:
| Document | Description |
|---|---|
| Installation | Complete setup guide |
| Configuration | All configuration options |
| Authentication | Auth flows and methods |
| API Reference | Complete API documentation |
| Web Routes | All web route details |
| MFA | Multi-factor authentication |
| Teams | Team management guide |
| Multi-Tenancy | SaaS multi-tenant setup |
| Security | Security features & best practices |
| Architecture | Identity strategy, tenancy & team design |
| Architecture Internals | Interfaces, patterns & coding standards |
Requirements
- PHP 8.3+
- Laravel 11.x or 12.x
- MySQL, PostgreSQL, or SQLite
Contributing
See CONTRIBUTING.md for setup instructions, coding standards, and how to submit pull requests.
Report security vulnerabilities following the process in SECURITY.md.
License
MIT License. See LICENSE for details.
Credits
Created and maintained by Abhishek Sharma at SSNTPL.
Ready to get started? Run composer require ssntpl/neev and php artisan neev:install!