npm package: @progress-chef/platform-standalone-auth-service
Description: Standalone authentication service for Chef Platform MFEs
Latest version: 0.0.2

# @progress-chef/platform-standalone-auth-service

Standalone authentication service for Chef Platform Angular Microfrontends (MFEs).

## Purpose

This service enables Angular MFEs to run in standalone mode with automatic authentication, eliminating the dependency on Shell and Login MFEs during development and testing.

## Features

- ✅ Automatic authentication on application startup
- ✅ Token refresh and session management
- ✅ 401 error detection and re-authentication flow
- ✅ Conditional injection based on environment configuration
- ✅ Reusable across multiple MFEs

## Installation

```bash
yarn add @progress-chef/platform-standalone-auth-service
```

## Usage

### 1. Environment Configuration

Add these variables to your `environment.ts` and `environment.development.ts`:

```typescript
export const environment = {
  production: false,
  
  // Standalone mode configuration
  STANDALONE_MODE: true,  // Enable standalone mode
  STANDALONE_EMAIL: 'your.email@progress.com',
  STANDALONE_PASSWORD: 'yourpassword',
  STANDALONE_ORG_ID: 'your-org-id',
  STANDALONE_ROLE_ID: 'your-role-id',
  USER_ACCOUNTS_BASE_URL: '/user-accounts-api/v1',
  
  // Other environment variables...
};
```

For production, set `STANDALONE_MODE: false` to disable standalone authentication.

### 2. Module Configuration

Update your `app.module.ts`:

```typescript
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { 
  StandaloneAuthModule, 
  StandaloneAuthInitializerService,
  StandaloneAuthInterceptor 
} from '@progress-chef/platform-standalone-auth-service';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
    // Your components
  ],
  imports: [
    // Other imports
    StandaloneAuthModule,  // Import the module
  ],
  providers: [
    // Other providers
    {
      provide: HTTP_INTERCEPTORS,
      useClass: StandaloneAuthInterceptor,
      multi: true,
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(
    private readonly standaloneAuthService: StandaloneAuthInitializerService,
    private readonly standaloneAuthInterceptor: StandaloneAuthInterceptor
  ) {
    // Configure the services with your environment
    this.standaloneAuthService.setEnvironment(environment);
    this.standaloneAuthInterceptor.setConfig({ 
      STANDALONE_MODE: environment.STANDALONE_MODE 
    });
  }
}
```

### 3. Component Integration (Optional)

If you want to show/hide UI elements based on authentication state:

```typescript
import { Component, OnInit, Injector } from '@angular/core';
import { 
  StandaloneAuthStateService, 
  StandaloneAuthInitializerService 
} from '@progress-chef/platform-standalone-auth-service';
import { environment } from '../../environments/environment';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html'
})
export class MainComponent implements OnInit {
  showNavigation = true;
  showAuthError = false;
  isStandaloneMode = environment.STANDALONE_MODE;
  
  private standaloneAuthStateService?: StandaloneAuthStateService;
  private standaloneAuthInitializerService?: StandaloneAuthInitializerService;

  constructor(private readonly injector: Injector) {
    // Conditional injection based on standalone mode
    if (this.isStandaloneMode) {
      this.standaloneAuthStateService = this.injector.get(StandaloneAuthStateService);
      this.standaloneAuthInitializerService = this.injector.get(StandaloneAuthInitializerService);
    }
  }

  ngOnInit(): void {
    if (this.isStandaloneMode && this.standaloneAuthStateService) {
      // Subscribe to authentication state
      this.standaloneAuthStateService.isAuthenticationValid().subscribe(isValid => {
        this.showNavigation = isValid;
        this.showAuthError = !isValid;
      });
    }
  }

  onLoginClick(): void {
    if (this.standaloneAuthInitializerService) {
      this.standaloneAuthInitializerService.reAuthenticate().subscribe(success => {
        console.log('Re-authentication completed:', success);
        // Note: On success, the page will automatically reload to refresh all components
      });
    }
  }
}
```

Template example:

```html
<!-- Navigation shown when authenticated -->
<div *ngIf="showNavigation">
  <button routerLink="/jobs">Jobs</button>
  <button routerLink="/templates">Templates</button>
</div>

<!-- Login button shown when authentication fails -->
<div *ngIf="showAuthError">
  <p>Authentication expired. Please login again.</p>
  <button (click)="onLoginClick()">Login</button>
</div>
```

## How It Works

1. **APP_INITIALIZER**: The `StandaloneAuthModule` registers an `APP_INITIALIZER` that blocks application bootstrap until authentication completes
2. **Auto-Login**: On startup, the service reads credentials from environment variables and performs automatic login
3. **Session Management**: Token refresh is handled automatically using `AuthOrchestrationService.startSessionRefresh()`
4. **401 Detection**: The `StandaloneAuthInterceptor` catches 401 errors and marks authentication as invalid
5. **Re-Authentication**: When auth becomes invalid, UI shows a login button that triggers `reAuthenticate()` method
6. **Page Reload**: After successful re-authentication, the page automatically reloads to reinitialize all components with fresh auth state

## API Reference

### StandaloneAuthStateService

- `isAuthenticationValid(): Observable<boolean>` - Observable for authentication state
- `isReAuthenticating(): Observable<boolean>` - Observable for re-authentication status
- `markAuthenticationInvalid(): void` - Mark authentication as invalid (called by interceptor)
- `markAuthenticationValid(): void` - Mark authentication as valid
- `getCurrentAuthState(): boolean` - Get current authentication state synchronously

### StandaloneAuthInitializerService

- `setEnvironment(env: StandaloneAuthEnvironment): void` - Configure environment settings
- `initialize(): Observable<boolean>` - Initialize authentication (called by APP_INITIALIZER)
- `reAuthenticate(): Observable<boolean>` - Re-authenticate after 401 error. **Note**: On success, triggers automatic page reload (`window.location.reload()`) to reinitialize all components with fresh authentication state

### StandaloneAuthInterceptor

- `setConfig(config: StandaloneAuthInterceptorConfig): void` - Configure interceptor with environment

## Development

### Building the Package

```bash
ng build platform-standalone-auth-service
```

### Publishing

```bash
cd dist/platform-standalone-auth-service
npm publish
```

## License

Proprietary - Progress Software Corporation