Files
ColaFlow/colaflow-api/test-auth-simple.ps1
Yaojia Wang 9e2edb2965 feat(backend): Implement Refresh Token mechanism (Day 5 Phase 1)
Implemented secure refresh token rotation with the following features:
- RefreshToken domain entity with IsExpired(), IsRevoked(), IsActive(), Revoke() methods
- IRefreshTokenService with token generation, rotation, and revocation
- RefreshTokenService with SHA-256 hashing and token family tracking
- RefreshTokenRepository for database operations
- Database migration for refresh_tokens table with proper indexes
- Updated LoginCommandHandler and RegisterTenantCommandHandler to return refresh tokens
- Added POST /api/auth/refresh endpoint (token rotation)
- Added POST /api/auth/logout endpoint (revoke single token)
- Added POST /api/auth/logout-all endpoint (revoke all user tokens)
- Updated JWT access token expiration to 15 minutes (from 60)
- Refresh token expiration set to 7 days
- Security features: token reuse detection, IP address tracking, user-agent logging

Changes:
- Domain: RefreshToken.cs, IRefreshTokenRepository.cs
- Application: IRefreshTokenService.cs, updated LoginResponseDto and RegisterTenantResult
- Infrastructure: RefreshTokenService.cs, RefreshTokenRepository.cs, RefreshTokenConfiguration.cs
- API: AuthController.cs (3 new endpoints), RefreshTokenRequest.cs, LogoutRequest.cs
- Configuration: appsettings.Development.json (updated JWT settings)
- DI: DependencyInjection.cs (registered new services)
- Migration: AddRefreshTokens migration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 14:44:36 +01:00

135 lines
3.7 KiB
PowerShell

# Day 4 Authentication Flow Test Script
$baseUrl = "http://localhost:5167/api"
Write-Host "===================================="
Write-Host "Day 4: Authentication Flow Test"
Write-Host "===================================="
Write-Host ""
# Test 1: Register Tenant
Write-Host "Test 1: Register Tenant"
$registerBody = @{
tenantName = "Test Corp"
tenantSlug = "test-corp-" + (Get-Random -Maximum 10000)
subscriptionPlan = "Professional"
adminEmail = "admin@testcorp.com"
adminPassword = "Admin@1234"
adminFullName = "Test Admin"
} | ConvertTo-Json
try {
$registerResponse = Invoke-RestMethod -Uri "$baseUrl/tenants/register" `
-Method Post `
-ContentType "application/json" `
-Body $registerBody
Write-Host "[OK] Tenant registered successfully"
Write-Host " Tenant Slug: $($registerResponse.tenant.slug)"
Write-Host " Admin Email: $($registerResponse.user.email)"
Write-Host " Token Length: $($registerResponse.accessToken.Length) characters"
$token = $registerResponse.accessToken
$tenantSlug = $registerResponse.tenant.slug
$email = $registerResponse.user.email
} catch {
Write-Host "[FAIL] Registration failed: $_"
exit 1
}
Write-Host ""
# Test 2: Login
Write-Host "Test 2: Login with Password Verification"
$loginBody = @{
tenantSlug = $tenantSlug
email = $email
password = "Admin@1234"
} | ConvertTo-Json
try {
$loginResponse = Invoke-RestMethod -Uri "$baseUrl/auth/login" `
-Method Post `
-ContentType "application/json" `
-Body $loginBody
Write-Host "[OK] Login successful"
Write-Host " User ID: $($loginResponse.user.id)"
Write-Host " Tenant ID: $($loginResponse.tenant.id)"
$loginToken = $loginResponse.accessToken
} catch {
Write-Host "[FAIL] Login failed: $_"
exit 1
}
Write-Host ""
# Test 3: Access protected endpoint without token
Write-Host "Test 3: Access Protected Endpoint WITHOUT Token"
try {
$response = Invoke-RestMethod -Uri "$baseUrl/auth/me" `
-Method Get `
-ErrorAction Stop
Write-Host "[FAIL] Should have been rejected!"
} catch {
if ($_.Exception.Response.StatusCode -eq 401) {
Write-Host "[OK] Correctly rejected (401 Unauthorized)"
} else {
Write-Host "[FAIL] Unexpected error: $($_.Exception.Response.StatusCode)"
}
}
Write-Host ""
# Test 4: Access protected endpoint with token
Write-Host "Test 4: Access Protected Endpoint WITH Token"
try {
$headers = @{
"Authorization" = "Bearer $loginToken"
}
$meResponse = Invoke-RestMethod -Uri "$baseUrl/auth/me" `
-Method Get `
-Headers $headers
Write-Host "[OK] Successfully accessed protected endpoint"
Write-Host " User ID: $($meResponse.userId)"
Write-Host " Email: $($meResponse.email)"
Write-Host " Full Name: $($meResponse.fullName)"
} catch {
Write-Host "[FAIL] Failed to access: $_"
exit 1
}
Write-Host ""
# Test 5: Login with wrong password
Write-Host "Test 5: Login with Wrong Password"
$wrongPasswordBody = @{
tenantSlug = $tenantSlug
email = $email
password = "WrongPassword123"
} | ConvertTo-Json
try {
$response = Invoke-RestMethod -Uri "$baseUrl/auth/login" `
-Method Post `
-ContentType "application/json" `
-Body $wrongPasswordBody `
-ErrorAction Stop
Write-Host "[FAIL] Should have been rejected!"
} catch {
if ($_.Exception.Response.StatusCode -eq 401) {
Write-Host "[OK] Correctly rejected wrong password"
} else {
Write-Host "[FAIL] Unexpected error: $($_.Exception.Response.StatusCode)"
}
}
Write-Host ""
Write-Host "===================================="
Write-Host "All Tests Completed!"
Write-Host "===================================="