common-ui/src/lib/auth/auth.module.ts
2022-07-27 13:25:51 +03:00

80 lines
3.0 KiB
TypeScript

import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { KeycloakAngularModule, KeycloakOptions, KeycloakService } from 'keycloak-angular';
import { DefaultUserService } from './default-user.service';
import { IIqserUser } from './types/user.response';
import { BaseUserService } from './base-user.service';
import { BASE_HREF, ModuleWithOptions } from '../utils';
import { AuthModuleOptions } from './types/auth-module-options';
import { IqserUser } from './user.model';
import { RoleGuard } from './role.guard';
import { AuthGuard } from './auth.guard';
import { BaseConfigService } from '../services';
function getKeycloakOptions(baseUrl: string, configService: BaseConfigService): KeycloakOptions {
let url: string = configService.values.OAUTH_URL;
url = url.replace(/\/$/, ''); // remove trailing slash
const realm = url.substring(url.lastIndexOf('/') + 1, url.length);
url = url.substring(0, url.lastIndexOf('/realms'));
return {
config: {
url: url,
realm: realm,
clientId: configService.values.OAUTH_CLIENT_ID,
},
initOptions: {
checkLoginIframe: false,
onLoad: 'check-sso',
silentCheckSsoRedirectUri: window.location.origin + baseUrl + '/assets/oauth/silent-refresh.html',
flow: 'standard',
},
enableBearerInterceptor: true,
};
}
function configureAutomaticRedirectToLoginScreen(keyCloakService: KeycloakService) {
keyCloakService.getKeycloakInstance().onAuthRefreshError = async () => {
await keyCloakService.logout();
};
}
export function keycloakInitializer(
keycloakService: KeycloakService,
configService: BaseConfigService,
baseUrl: string,
): () => Promise<void> {
const x = keycloakService.init(getKeycloakOptions(baseUrl, configService));
return () => x.then(() => configureAutomaticRedirectToLoginScreen(keycloakService));
}
@NgModule({
imports: [CommonModule, HttpClientModule, KeycloakAngularModule],
providers: [
AuthGuard,
{
provide: APP_INITIALIZER,
useFactory: keycloakInitializer,
multi: true,
deps: [KeycloakService, BaseConfigService, BASE_HREF],
},
],
})
export class AuthModule extends ModuleWithOptions {
static forRoot<
Interface extends IIqserUser,
Class extends IqserUser & Interface,
UserService extends BaseUserService<Interface, Class>,
RolesGuard extends RoleGuard = RoleGuard,
>(options: AuthModuleOptions<Interface, Class, UserService, RolesGuard>): ModuleWithProviders<AuthModule> {
const userService = this._getService(BaseUserService, DefaultUserService, options.existingUserService);
const roleGuard = this._getService(RoleGuard, RoleGuard, options.existingRoleGuard);
return {
ngModule: AuthModule,
providers: [userService, roleGuard],
};
}
}