Updated user service to use different endpoint

This commit is contained in:
Erik Tiekstra
2021-09-09 14:41:02 +02:00
parent 6c9ff4423e
commit 8f3d1033a8
9 changed files with 43 additions and 47 deletions

View File

@@ -73,7 +73,7 @@
<ul class="my-account__list">
<li class="my-account__list-item" *ngFor="let role of allRoles">
<digi-icon-check-circle
*ngIf="userHasRole(user.roles, role); else unauthorized"
*ngIf="user.roles.includes(role.type); else unauthorized"
class="msfa__digi-icon my-account__authorization-icon my-account__authorization-icon--authorized"
></digi-icon-check-circle>
<ng-template #unauthorized>

View File

@@ -1,9 +1,9 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Router } from '@angular/router';
import { IconType } from '@msfa-enums/icon-type.enum';
import { Employee } from '@msfa-models/employee.model';
import { Organization } from '@msfa-models/organization.model';
import { Role } from '@msfa-models/role.model';
import { User } from '@msfa-models/user.model';
import { UserService } from '@msfa-services/api/user.service';
import { RoleService } from '@msfa-services/role.service';
import { combineLatest, Observable } from 'rxjs';
@@ -16,7 +16,7 @@ import { filter, map } from 'rxjs/operators';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MyAccountComponent {
user$: Observable<User> = this.userService.user$;
user$: Observable<Employee> = this.userService.user$;
selectedOrganization$: Observable<Organization> = this.userService.selectedOrganization$;
organizations$: Observable<Organization[]> = this.userService.organizations$;
otherOrganizations$: Observable<Organization[]> = combineLatest([
@@ -33,10 +33,6 @@ export class MyAccountComponent {
constructor(private userService: UserService, private roleService: RoleService, private router: Router) {}
userHasRole(userRoles: Role[], currentRole: Role): boolean {
return userRoles.some(role => role.type === currentRole.type);
}
loginWithOrganization(organization: Organization): void {
this.userService.setSelectedOrganization(organization);
}

View File

@@ -2,6 +2,7 @@ import { DigiNgSkeletonBaseModule } from '@af/digi-ng/_skeleton/skeleton-base';
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HideTextModule } from '@msfa-shared/components/hide-text/hide-text.module';
import { IconModule } from '@msfa-shared/components/icon/icon.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { OrganizationPickerFormModule } from '@msfa-shared/components/organization-picker-form/organization-picker-form.module';
@@ -19,6 +20,7 @@ import { MyAccountComponent } from './my-account.component';
DigiNgSkeletonBaseModule,
OrganizationPickerFormModule,
RolesDialogModule,
HideTextModule,
],
})
export class MyAccountModule {}

View File

@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { IconType } from '@msfa-enums/icon-type.enum';
import { Employee } from '@msfa-models/employee.model';
import { Organization } from '@msfa-models/organization.model';
import { User } from '@msfa-models/user.model';
@Component({
selector: 'msfa-navigation',
@@ -10,7 +10,7 @@ import { User } from '@msfa-models/user.model';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NavigationComponent {
@Input() user: User;
@Input() user: Employee;
@Input() selectedOrganization: Organization;
iconType = IconType;
}

View File

@@ -3,14 +3,14 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive';
import { Employee } from '@msfa-models/employee.model';
import { Organization } from '@msfa-models/organization.model';
import { Role } from '@msfa-models/role.model';
import { User } from '@msfa-models/user.model';
import { AuthenticationService } from '@msfa-services/api/authentication.service';
import { UserService } from '@msfa-services/api/user.service';
import { mapPathsToBreadcrumbs } from '@msfa-utils/map-paths-to-breadcrumbs.util';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { filter } from 'rxjs/operators';
@Component({
selector: 'msfa-layout',
@@ -27,11 +27,8 @@ export class LayoutComponent extends UnsubscribeDirective {
private _breadcrumbsItems$ = new BehaviorSubject<NavigationBreadcrumbsItem[]>([this._startBreadcrumb]);
isLoggedIn$: Observable<boolean> = this.authenticationService.isLoggedIn$;
selectedOrganization$: Observable<Organization> = this.userService.selectedOrganization$;
user$: Observable<User> = this.userService.user$;
roles$: Observable<Role[]> = this.user$.pipe(
filter(user => !!user),
map(user => user.roles)
);
user$: Observable<Employee> = this.userService.user$.pipe(filter(user => !!user));
roles$: Observable<Role[]> = this.userService.userRoles$.pipe(filter(roles => !!roles?.length));
get breadcrumbsItems(): NavigationBreadcrumbsItem[] {
return this._breadcrumbsItems$.getValue();

View File

@@ -14,9 +14,9 @@ export class RoleGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
const expectedRole: RoleEnum = route.data.expectedRole as RoleEnum;
return this.userService.user$.pipe(
filter(user => !!user),
map(({ roles }) => {
return this.userService.userRoles$.pipe(
filter(roles => !!roles?.length),
map(roles => {
const userHasRole = roles.some(role => role.type === expectedRole);
if (userHasRole) {

View File

@@ -1,22 +1,6 @@
import { OrganizationResponse } from './api/organization.response.model';
import { UserInfoResponse } from './api/user-info.response.model';
import { mapResponseToOrganization, Organization } from './organization.model';
import { mapResponseToRoles } from './role.model';
import { UserInfo } from './user-info.model';
import { Employee } from './employee.model';
import { Organization } from './organization.model';
export interface User extends UserInfo {
export interface User extends Employee {
organizations: Organization[];
}
export function mapUserApiResponseToUser(userInfo: UserInfoResponse, organizations: OrganizationResponse[]): User {
const { id, firstName, lastName, roles } = userInfo;
return {
id,
firstName,
lastName,
fullName: `${firstName} ${lastName}`,
roles: mapResponseToRoles(roles),
organizations: organizations ? organizations.map(organization => mapResponseToOrganization(organization)) : [],
};
}

View File

@@ -3,11 +3,13 @@ import { Injectable } from '@angular/core';
import { SELECTED_ORGANIZATION_NUMBER_KEY } from '@msfa-constants/local-storage-keys';
import { UnsubscribeDirective } from '@msfa-directives/unsubscribe.directive';
import { environment } from '@msfa-environment';
import { EmployeeResponse } from '@msfa-models/api/employee.response.model';
import { OrganizationResponse } from '@msfa-models/api/organization.response.model';
import { UserInfoResponse } from '@msfa-models/api/user-info.response.model';
import { Employee, mapResponseToEmployee } from '@msfa-models/employee.model';
import { mapResponseToOrganization, Organization } from '@msfa-models/organization.model';
import { Role } from '@msfa-models/role.model';
import { mapResponseToUserInfo, UserInfo } from '@msfa-models/user-info.model';
import { User } from '@msfa-models/user.model';
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
import { filter, map, switchMap } from 'rxjs/operators';
import { AuthenticationService } from './authentication.service';
@@ -16,12 +18,16 @@ import { AuthenticationService } from './authentication.service';
providedIn: 'root',
})
export class UserService extends UnsubscribeDirective {
private _apiBaseUrl = `${environment.api.url}/auth`;
private _apiAuthUrl = `${environment.api.url}/auth`;
private _apiUserUrl = `${environment.api.url}/users/currentUser`;
private _isLoggedIn$: Observable<boolean> = this.authenticationService.isLoggedIn$;
private _organizations$ = new BehaviorSubject<Organization[]>(null);
public organizations$: Observable<Organization[]> = this._organizations$.asObservable();
private _user$ = new BehaviorSubject<User>(null);
public user$: Observable<User> = this._user$.asObservable();
private _user$ = new BehaviorSubject<Employee>(null);
public user$: Observable<Employee> = this._user$.asObservable();
private _userRoles$ = new BehaviorSubject<Role[]>(null);
public userRoles$: Observable<Role[]> = this._userRoles$.asObservable();
private _selectedOrganizationNumber$ = new BehaviorSubject<string>(null);
constructor(private httpClient: HttpClient, private authenticationService: AuthenticationService) {
@@ -39,28 +45,37 @@ export class UserService extends UnsubscribeDirective {
combineLatest([this._isLoggedIn$, this.selectedOrganization$])
.pipe(
filter(([loggedIn, selectedOrganization]) => !!(loggedIn && selectedOrganization)),
switchMap(() => this._fetchUserInfo$())
switchMap(() => combineLatest([this._fetchUserInfo$(), this._fetchCurrentUser$()]))
)
.subscribe(userInfo => {
this._user$.next({ ...userInfo, organizations: this._organizations$.value });
.subscribe(([userInfo, currentUser]) => {
this._userRoles$.next(userInfo.roles);
this._user$.next(currentUser);
})
);
}
private _fetchOrganizations$(): Observable<Organization[]> {
return this.httpClient.get<{ data: OrganizationResponse[] }>(`${this._apiBaseUrl}/organizations`).pipe(
return this.httpClient.get<{ data: OrganizationResponse[] }>(`${this._apiAuthUrl}/organizations`).pipe(
filter(response => !!response?.data),
map(({ data }) => data.map(organization => mapResponseToOrganization(organization)))
);
}
private _fetchUserInfo$(): Observable<UserInfo> {
return this.httpClient.get<{ data: UserInfoResponse }>(`${this._apiBaseUrl}/userinfo`).pipe(
return this.httpClient.get<{ data: UserInfoResponse }>(`${this._apiAuthUrl}/userinfo`).pipe(
filter(response => !!response?.data),
map(({ data }) => mapResponseToUserInfo(data))
);
}
private _fetchCurrentUser$(): Observable<Employee> {
console.log('fetching current user');
return this.httpClient.get<{ data: EmployeeResponse }>(`${this._apiUserUrl}`).pipe(
filter(response => !!response?.data),
map(({ data }) => mapResponseToEmployee(data))
);
}
private get _selectedOrganizationNumber(): string | null {
return localStorage.getItem(SELECTED_ORGANIZATION_NUMBER_KEY);
}

View File

@@ -1,11 +1,13 @@
import { Injectable } from '@angular/core';
import { RoleEnum } from '@msfa-enums/role.enum';
import { environment } from '@msfa-environment';
import { mapResponseToRoles, Role } from '@msfa-models/role.model';
@Injectable({
providedIn: 'root',
})
export class RoleService {
private readonly _apiBaseUrl = `${environment.api.url}/auth/userinfo`;
public get allRoles(): Role[] {
return mapResponseToRoles(Object.keys(RoleEnum) as RoleEnum[]);
}