npm package: @mediacologne/ng-auth
Description: # Installation
Latest version: 14.0.0

# @mediacologne/ng-auth

# Installation

## Install the NPM Module

```bash
$ npm install @mediacologne/ng-auth
```

## Using the Library

Nach der Installation muss die Library durch das Importieren des `AuthModule` verfügbar gemacht werden.

```typescript
// Import your library
import { DataModule } from '@mediacologne/ng-auth';

@NgModule({
  imports: [
    AuthModule.forRoot(<IAuthConfig>{
        backend: {
            transport: {
                baseUrl: 'http://backend-url.local:8080/api/v1/login/',
            },
        },
        storage: {
            userInformationName: 'userStorage',
            dataInformationName: 'userData',
            tokenName: 'authToken',
        },
        token: {
            renewalInterval: 3,
            tokenRenewal: true,
            expiration: {
                enabled: true,
                timeout: 5000,
                customModalComponent: null,
                modalConfig: {
                    title: 'Sitzung abgelaufen'
                }
            }
        }
    })
  ]
})
export class AuthModule { }
```

# Documentation

## Module Import
Beim Importieren des Module muss eine `IAuthConfig` Configuration mitgegeben werden, welche für die Nutzung der Library notwendig ist.

**Backend**  ``
Dies dient der Definition der URL zum Backend
* `backend.transport.baseUrl: string` URL zum LoginController (kann auch relativ sein, stammt in der Regel aus dem environment`)
* `backend.propertyPath: string[]` **Optional** hier kann der PropertyPath für das MC.JwtAuth Flow Package geändert werden
* `backend.transport.passwordEncryption: boolean` **Optional** definiert, ob das Passwort beim Login verschlüsselzt übertragen werden soll (default=true)

**Storage**  
Hier werden die Bezeichner für die Keys im LocalStorage definiert.
* `storage.userInformationName: string` dies ist der localStorage Key-Bezeichner zur Ablage der *UserInformation*
* `storage.dataInformationName: string` dies ist der localStorage Key-Bezeichner zur Ablage der *DataInformationName*
* `storage.tokenName: string` dies ist der localStorage Key-Bezeichner zur Ablage des *JWT Tokens*

**Token**  
Dies beinhaltet alle auf das JWT Token bezogenen Werte.
* `token.renewalInterval: number` definiert, wie oft der Token beim Backend erneuert wird.
* `token.tokenRenewal: boolean` definiert, ob überhaupt eine regelmäßige Erneuerung des Tokens durchgeführt wird
* `token.expiration.enabled: boolean` gibt an, ob das Token nach einer gewissen Inaktivität des Users ablaufen soll
* `token.expiration.timeout: number` definiert die Inaktivitätsdauer ab wann das Token abläuft
* `token.expiration.customModalComponent: Component` hier kann eine eigene ExpirationModalComponent angegeben werden (weitere Details unten!)
* `token.expiration.modalConfig: ExpirationModalConfig` dies sind Konfigurationswerte welche dem `ExpirationModal` übergeben werden (sowohl dem Default als auch Custom)


## Expiration

Wird die *Expiration* aktiviert (`token.expiration.enabled = true`) läuft das Token automatisch nach einer gewissen Inaktivität(sdauer) des Users ab.
Die Dauer wird mittels `token.expiration.timeout` spezifiziert. Sobald die Expiration eintritt, wird der User ausgeloggt, dies umfasst sowohl den Wechsel des `authStates`
als auch den `localStorage`.
Sobald die `Expiration` eintritt, wird das `DefaultSessionExpiredModalComponent` geöffnet und bietet dem User die Möglichkeit,
sich erneut einzuloggen und mit der Arbeit (an gleicher Stelle) fortzufahren.


#### Das `CustomModalComponent`

Es ist Möglich, eine eigene Componente aus der Anwendung als `CustomSessionExpiredModalComponent` zu verwenden. Diese wird dann bei `token.expiration.customModalComponent` definiert.
Voraussetzung für das `CustomModalComponent` ist die Implementierung des Interfaces `ExpirationModal`.
In den meisten Fällen wird es nicht notwendig sein, die interne Logik des Re-Authentifizierung innerhalb des `CustomModalComponent` selbst zu programmieren,
weshalb von der abstrakten `AbstractSessionExpirationModal` abgeleitet werden kann. In diesem Fall muss die `CustomModalComponent` lediglich nur noch das Template bereitstellen.
Als Referenzimplementierung kann hier das `DefaultSessionExpiredModalComponent` dienen, welches automatisch verwendet wird sofern kein `CustomModalComponent` bereitgestellt wird.

##### Hinweis

Bitte beachten, dass das `CustomModalComponent` in die `entryComponents` des `(Base|App)Module`s eingetragen muss.

##### HTML Template

* das HTML Formular muss beim submit an die `authenticate()` Methode submitten
* die Inputs müssen via Two-way Binding an `username` und `password` gebunden werden.
```html
<form #form="ngForm" (submit)="authenticate()">
    <input type="email" class="form-control" name="username" [(ngModel)]="username" placeholder="Benutzername">
    <input type="password" class="form-control" name="password" [(ngModel)]="password" placeholder="Password">
</form>
```


## `UserInformation` und `DataInformation`

Im Backend (PHP) existiert die `getTokenPayload()` Methode (LoginController) welche für die Befüllung der *JWT Token Payload* zuständig ist.  
Hier werden die `UserInformation` und `DataInformation` getrennt voneinander behandelt.

```php
/**
 * @return array
 */
public function getTokenPayload($loggedInUser)
{
    return [
        "user" => array_merge(
            [
                "userId" => $this->persistenceManager->getIdentifierByObject($loggedInUser),
            ]),
        "data" => [
            "roles" => array_keys($loggedInUser->getAccount()->getRoles())
        ]
    ];
}
``` 

## Pwned-Service integration

If you don't want to use the `PwnedService` you have to provide `USE_PWNED_SERVICE` with boolean value of `false`


## OAuth Integration

If your application should support OAuth integration with MediaSuite as identity provider, you have just a few config lines to make it work.
The next paragraphs will guide you through the necessary steps.


#### Module configuration

Add this configuration part to your `forRoot` method while importing AuthModule.  
Of course you have to replace `client_id` and `redirect_uri` with the appropiate values from the hydra server.
**If you have not allready configured an OAuth Client in Hydra, please stop here and ask someone for help!**
```typescript
authentication: {
    oauth: {
        enabled: true,
        urlParams: {
            client_id: '<YOUR CLIENT ID>',
            redirect_uri: '<REDIRECT URI>',
        }
    }
}
```
**Hint: If you want to have as much magic as possible, you should configure a `redirect_url` specially for oauth and then register that route in your Router with the `OauthCallbackHandlerComponent` Component. We'll explain this later.**


#### OAuth Button

You can add a button for *login via mediaSuite* with the `<mediasuite-login-button mode="redirect|modal"></mediasuite-login-button>` component markup.
*Please use this button in your application without much customization to make it a consistent style across all applications*

**[mode] input:**  
The OAuth login button comes in two different `modes`, which will be explained now:
* **1) `redirect`**  
  The redirect mode is based, as its name suggests, on browser redirects. It redirects the browser window through the authorization flow and ends at the given `redirect_uri` with an `authorization_code` as querystring parameter.

* **2) `modal`**  
  The modal mode is a modal based mechanism, where the authorization flow happens inside a modal iframe with an overlay over your application. It ends with a modal close and a authorization postMessage event.


#### OAuth auto-authorization

The OAuth authorization flow ends (in both modes) with a redirection to the configured `redirect_uri` and an authorization_code as querystring. To get **as much magic as possible** out of `@mediacologne/ng-data` and Flow's `MC.JwtAuth` you have to:
* Register your `redirect_uri` in your RouterModule and call the `OauthCallbackHandlerComponent` component from this library.
* Example:
    ```typescript
    import {OauthCallbackHandlerComponent} from '@mediacologne/ng-auth-module';
    
    RouterModule.forRoot([
      {path: 'oauth', component: OauthCallbackHandlerComponent},
    ],
    ````
* Thats it **;-)**

**Explanation**
1) After the authorization flow ends, the `redirect_uri` from hydra is opened (best practise to get a consist architecture is to set it to `/oauth`).
   Then the `OauthCallbackHandlerComponent` is opened and detects, if its loaded inside an iframe (it tries to detect the `mode` 'modal' or 'redirect').

2) The transmitted `authorization_code` will be sent to the `MC.JwtAuth` backend.
   This is done directly through the `OAuthService` or through a small detour (because it has to break the iframe and get into the application context back, via PostMessage).

3) tbw;