diff --git a/ui-ngx/src/app/core/auth/auth.actions.ts b/ui-ngx/src/app/core/auth/auth.actions.ts index 9e5640a97d..a6bf97c527 100644 --- a/ui-ngx/src/app/core/auth/auth.actions.ts +++ b/ui-ngx/src/app/core/auth/auth.actions.ts @@ -15,7 +15,7 @@ /// import { Action } from '@ngrx/store'; -import { User } from '@shared/models/user.model'; +import { AuthUser, User } from '@shared/models/user.model'; import { AuthPayload } from '@core/auth/auth.models'; import { UserSettings } from '@shared/models/user-settings.models'; @@ -24,6 +24,7 @@ export enum AuthActionTypes { UNAUTHENTICATED = '[Auth] Unauthenticated', LOAD_USER = '[Auth] Load User', UPDATE_USER_DETAILS = '[Auth] Update User Details', + UPDATE_AUTH_USER = '[Auth] Update Auth User', UPDATE_LAST_PUBLIC_DASHBOARD_ID = '[Auth] Update Last Public Dashboard Id', UPDATE_HAS_REPOSITORY = '[Auth] Change Has Repository', UPDATE_OPENED_MENU_SECTION = '[Preferences] Update Opened Menu Section', @@ -53,6 +54,12 @@ export class ActionAuthUpdateUserDetails implements Action { constructor(readonly payload: { userDetails: User }) {} } +export class ActionAuthUpdateAuthUser implements Action { + readonly type = AuthActionTypes.UPDATE_AUTH_USER; + + constructor(readonly payload: Partial) {} +} + export class ActionAuthUpdateLastPublicDashboardId implements Action { readonly type = AuthActionTypes.UPDATE_LAST_PUBLIC_DASHBOARD_ID; @@ -85,4 +92,5 @@ export class ActionPreferencesDeleteUserSettings implements Action { export type AuthActions = ActionAuthAuthenticated | ActionAuthUnauthenticated | ActionAuthLoadUser | ActionAuthUpdateUserDetails | ActionAuthUpdateLastPublicDashboardId | ActionAuthUpdateHasRepository | - ActionPreferencesUpdateOpenedMenuSection | ActionPreferencesPutUserSettings | ActionPreferencesDeleteUserSettings; + ActionPreferencesUpdateOpenedMenuSection | ActionPreferencesPutUserSettings | ActionPreferencesDeleteUserSettings | + ActionAuthUpdateAuthUser; diff --git a/ui-ngx/src/app/core/auth/auth.reducer.ts b/ui-ngx/src/app/core/auth/auth.reducer.ts index 4bcf71104b..c0ce66e990 100644 --- a/ui-ngx/src/app/core/auth/auth.reducer.ts +++ b/ui-ngx/src/app/core/auth/auth.reducer.ts @@ -58,6 +58,10 @@ export const authReducer = ( case AuthActionTypes.UPDATE_USER_DETAILS: return { ...state, ...action.payload}; + case AuthActionTypes.UPDATE_AUTH_USER: + const authUser = {...state.authUser, ...action.payload}; + return { ...state, ...{ authUser }}; + case AuthActionTypes.UPDATE_LAST_PUBLIC_DASHBOARD_ID: return { ...state, ...action.payload}; diff --git a/ui-ngx/src/app/core/auth/auth.service.ts b/ui-ngx/src/app/core/auth/auth.service.ts index 8a838b4130..e969c8129a 100644 --- a/ui-ngx/src/app/core/auth/auth.service.ts +++ b/ui-ngx/src/app/core/auth/auth.service.ts @@ -27,7 +27,12 @@ import { defaultHttpOptions, defaultHttpOptionsFromConfig, RequestConfig } from import { UserService } from '../http/user.service'; import { Store } from '@ngrx/store'; import { AppState } from '../core.state'; -import { ActionAuthAuthenticated, ActionAuthLoadUser, ActionAuthUnauthenticated } from './auth.actions'; +import { + ActionAuthAuthenticated, + ActionAuthLoadUser, + ActionAuthUnauthenticated, + ActionAuthUpdateAuthUser +} from './auth.actions'; import { getCurrentAuthState, getCurrentAuthUser } from './auth.selectors'; import { Authority } from '@shared/models/authority.enum'; import { ActionSettingsChangeLanguage } from '@app/core/settings/settings.actions'; @@ -480,6 +485,7 @@ export class AuthService { } else { this.updateAndValidateTokens(loginResponse.token, loginResponse.refreshToken, true); } + this.updatedAuthUserFromToken(loginResponse.token); this.refreshTokenSubject.next(loginResponse); this.refreshTokenSubject.complete(); this.refreshTokenSubject = null; @@ -493,6 +499,18 @@ export class AuthService { return response; } + private updatedAuthUserFromToken(token: string) { + const authUser = getCurrentAuthUser(this.store); + const tokenData = this.jwtHelper.decodeToken(token); + if (['sub', 'firstName', 'lastName'].some(value => authUser[value] !== tokenData[value])) { + this.store.dispatch(new ActionAuthUpdateAuthUser({ + sub: tokenData.sub, + firstName: tokenData.firstName, + lastName: tokenData.lastName, + })); + } + } + private validateJwtToken(doRefresh): Observable { const subject = new ReplaySubject(); if (!AuthService.isTokenValid('jwt_token')) { diff --git a/ui-ngx/src/app/modules/home/pages/profile/profile.component.ts b/ui-ngx/src/app/modules/home/pages/profile/profile.component.ts index 0633e696dd..cf6b3d34cb 100644 --- a/ui-ngx/src/app/modules/home/pages/profile/profile.component.ts +++ b/ui-ngx/src/app/modules/home/pages/profile/profile.component.ts @@ -30,6 +30,7 @@ import { ActionSettingsChangeLanguage } from '@core/settings/settings.actions'; import { ActivatedRoute } from '@angular/router'; import { isDefinedAndNotNull } from '@core/utils'; import { getCurrentAuthUser } from '@core/auth/auth.selectors'; +import { AuthService } from '@core/auth/auth.service'; @Component({ selector: 'tb-profile', @@ -47,6 +48,7 @@ export class ProfileComponent extends PageComponent implements OnInit, HasConfir constructor(protected store: Store, private route: ActivatedRoute, private userService: UserService, + private authService: AuthService, private translate: TranslateService, public fb: UntypedFormBuilder) { super(store); @@ -94,6 +96,7 @@ export class ProfileComponent extends PageComponent implements OnInit, HasConfir lastName: user.lastName, } })); this.store.dispatch(new ActionSettingsChangeLanguage({ userLang: user.additionalInfo.lang })); + this.authService.refreshJwtToken(false); } ); }