# Auth Client Library Angular client library for integrating with the Elixir-based auth service. Provides authentication, authorization, and user management capabilities. ## Features - **Authentication**: Login, register, logout with JWT tokens - **Token Management**: Automatic token refresh and storage - **OAuth Integration**: Social authentication with multiple providers - **Two-Factor Authentication**: TOTP and backup codes support - **Route Guards**: Protect routes based on authentication and scopes - **HTTP Interceptor**: Automatic token injection and refresh - **TypeScript Support**: Fully typed interfaces and models ## Installation ```bash npm install auth-client ``` ## Setup ### 1. Import the HTTP Client Module ```typescript import { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; @NgModule({ imports: [ HttpClientModule, // ... other imports ], }) export class AppModule {} ``` ### 2. Configure the Auth Service ```typescript import { AuthService } from 'auth-client'; export class AppComponent { constructor(private authService: AuthService) { // Configure the base URL for your auth service this.authService.configure('http://localhost:4000'); } } ``` ### 3. Add HTTP Interceptor (Optional) ```typescript import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthInterceptor } from 'auth-client'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ] }) export class AppModule {} ``` ## Usage ### Authentication #### Login ```typescript import { AuthService } from 'auth-client'; constructor(private authService: AuthService) {} login() { this.authService.login({ email: 'user@example.com', password: 'password123' }).subscribe({ next: (response) => { console.log('Login successful:', response.user); }, error: (error) => { console.error('Login failed:', error); } }); } ``` #### Register ```typescript register() { this.authService.register({ email: 'user@example.com', password: 'password123', first_name: 'John', last_name: 'Doe' }).subscribe({ next: (response) => { console.log('Registration successful:', response.user); }, error: (error) => { console.error('Registration failed:', error); } }); } ``` #### Logout ```typescript logout() { this.authService.logout().subscribe({ next: () => { console.log('Logout successful'); }, error: (error) => { console.error('Logout failed:', error); } }); } ``` ### Authentication State ```typescript import { AuthService } from 'auth-client'; constructor(private authService: AuthService) { // Subscribe to authentication state this.authService.isAuthenticated$.subscribe(isAuth => { console.log('Is authenticated:', isAuth); }); // Subscribe to current user this.authService.currentUser$.subscribe(user => { console.log('Current user:', user); }); // Check if authenticated synchronously const isAuth = this.authService.isAuthenticated(); } ``` ### Route Guards #### Protect Authenticated Routes ```typescript import { AuthGuard } from 'auth-client'; const routes: Routes = [ { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }, { path: 'admin', component: AdminComponent, canActivate: [AuthGuard], data: { requiredScopes: ['admin'], // Require admin scope requireAllScopes: true, // Must have all scopes (default: false) unauthorizedRedirect: '/access-denied' } } ]; ``` #### Protect Guest Routes ```typescript import { GuestGuard } from 'auth-client'; const routes: Routes = [ { path: 'login', component: LoginComponent, canActivate: [GuestGuard], // Redirect to home if already authenticated data: { authenticatedRedirect: '/dashboard' } } ]; ``` ### OAuth Integration #### Get Available Providers ```typescript import { OAuthService } from 'auth-client'; constructor(private oauthService: OAuthService) {} getProviders() { this.oauthService.getProviders().subscribe(providers => { console.log('Available providers:', providers); }); } ``` #### Initiate OAuth Flow ```typescript // Redirect flow loginWithGoogle() { this.oauthService.initiateOAuthFlow('google', 'http://localhost:4200/oauth/callback'); } // Popup flow async loginWithGooglePopup() { try { const result = await this.oauthService.initiateOAuthPopup('google'); console.log('OAuth successful:', result); } catch (error) { console.error('OAuth failed:', error); } } ``` #### Handle OAuth Callback ```typescript // In your callback component ngOnInit() { this.oauthService.completeOAuthFlow('google').subscribe({ next: (result) => { console.log('OAuth login successful:', result); this.router.navigate(['/dashboard']); }, error: (error) => { console.error('OAuth login failed:', error); this.router.navigate(['/login']); } }); } ``` ### Two-Factor Authentication #### Setup 2FA ```typescript setup2FA() { this.authService.setup2FA().subscribe({ next: (response) => { // Display QR code and backup codes console.log('QR Code:', response.qr_code); console.log('Backup codes:', response.backup_codes); }, error: (error) => { console.error('2FA setup failed:', error); } }); } ``` #### Verify 2FA Setup ```typescript verify2FA(token: string) { this.authService.verify2FASetup({ token }).subscribe({ next: () => { console.log('2FA enabled successfully'); }, error: (error) => { console.error('2FA verification failed:', error); } }); } ``` ### User Management #### Update Profile ```typescript updateProfile() { this.authService.updateProfile({ first_name: 'Jane', last_name: 'Smith' }).subscribe({ next: (user) => { console.log('Profile updated:', user); }, error: (error) => { console.error('Profile update failed:', error); } }); } ``` #### Change Password ```typescript changePassword() { this.authService.changePassword({ current_password: 'oldpassword', new_password: 'newpassword', new_password_confirmation: 'newpassword' }).subscribe({ next: () => { console.log('Password changed successfully'); }, error: (error) => { console.error('Password change failed:', error); } }); } ``` ### Token Management #### Manual Token Operations ```typescript import { TokenService } from 'auth-client'; constructor(private tokenService: TokenService) {} checkToken() { // Check if token exists and is valid const isValid = this.tokenService.isTokenValid(); // Get user information from token const userId = this.tokenService.getUserId(); const email = this.tokenService.getUserEmail(); const scopes = this.tokenService.getUserScopes(); // Check scopes const hasAdminScope = this.tokenService.hasScope('admin'); const hasAnyScope = this.tokenService.hasAnyScope(['read', 'write']); const hasAllScopes = this.tokenService.hasAllScopes(['read', 'write']); } ``` ## API Reference ### Models All TypeScript interfaces are available for import: ```typescript import { User, LoginRequest, LoginResponse, RegisterRequest, TokenPair, ApiError, // ... and more } from 'auth-client'; ``` ### Services - **AuthService**: Main authentication service - **TokenService**: Token management and validation - **OAuthService**: OAuth provider integration - **AuthHttpService**: Low-level HTTP client ### Guards - **AuthGuard**: Protect authenticated routes - **GuestGuard**: Protect guest-only routes ### Interceptors - **AuthInterceptor**: Automatic token injection and refresh ## Configuration ### Environment Variables You can configure the auth service URL through your environment: ```typescript // environment.ts export const environment = { authServiceUrl: 'http://localhost:4000' }; // app.component.ts constructor(private authService: AuthService) { this.authService.configure(environment.authServiceUrl); } ``` ### Token Storage By default, tokens are stored in localStorage. The library handles: - Automatic token refresh before expiration - Cross-tab synchronization - Token validation and cleanup ## Error Handling All services return Observable streams with proper error handling: ```typescript this.authService.login(credentials).subscribe({ next: (response) => { // Handle success }, error: (apiError: ApiError) => { console.error('Error:', apiError.error); // Handle specific errors if (apiError.requires_2fa) { // Redirect to 2FA input } if (apiError.details) { // Handle validation errors console.error('Validation errors:', apiError.details); } } }); ``` ## Building To build the library, run: ```bash ng build auth-client ``` This command will compile your project, and the build artifacts will be placed in the `dist/` directory. ## Publishing the Library Once the project is built, you can publish your library by following these steps: 1. Navigate to the `dist` directory: ```bash cd dist/auth-client ``` 2. Run the `npm publish` command to publish your library to the npm registry: ```bash npm publish ``` ## Running unit tests To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command: ```bash ng test auth-client ``` ## Contributing This library is designed to work with the Elixir auth service. Please ensure API compatibility when making changes. ## License MIT License