From 6f7aa68c897c99746637447798b4dc8a193ddddb Mon Sep 17 00:00:00 2001
From: Yogi_Wang <yawang@vmware.com>
Date: Fri, 5 Jun 2020 14:14:27 +0800
Subject: [PATCH] [fix][unauthorized] Support show relogin when unauthorized 
 in popup modal 1.support show relogin when unauthorized  in popup modali
 2.change change member role error handle 3.change helm chart service error
 handle Signed-off-by: Yogi_Wang <yawang@vmware.com>

---
 .../account-settings-modal.component.spec.ts   |  2 ++
 .../forgot-password.component.spec.ts          |  2 ++
 .../password-setting.component.spec.ts         |  4 +++-
 .../reset-password.component.spec.ts           |  2 ++
 .../account/sign-up/sign-up.component.spec.ts  |  4 +++-
 .../harbor-shell.component.spec.ts             |  2 ++
 .../app/global-message/message.component.html  |  2 +-
 .../app/global-message/message.component.scss  |  2 +-
 .../app/global-message/message.component.ts    |  2 +-
 .../create-project.component.spec.ts           |  2 ++
 .../project/helm-chart/helm-chart.service.ts   |  2 +-
 .../add-member/add-member.component.spec.ts    |  2 ++
 .../member/add-member/add-member.component.ts  | 18 +++---------------
 .../src/app/project/member/member.component.ts |  2 +-
 .../add-rule/add-rule.component.spec.ts        | 12 ++++++++++--
 .../add-rule/add-rule.component.spec.ts        |  3 +++
 .../add-webhook-form.component.spec.ts         |  2 ++
 .../project/webhook/webhook.component.spec.ts  |  3 +++
 .../inline-alert.component.spec.ts             |  6 +++++-
 .../inline-alert/inline-alert.component.ts     |  8 ++++++--
 .../message-handler/message-handler.service.ts | 13 +++++++++++++
 .../edit-project-quotas.component.spec.ts      |  2 ++
 .../inline-alert/inline-alert.component.ts     |  7 +++++--
 .../push-image/push-image.component.spec.ts    |  4 +++-
 .../replication/replication.component.spec.ts  |  3 ++-
 .../lib/utils/error-handler/error-handler.ts   |  5 +++++
 26 files changed, 85 insertions(+), 31 deletions(-)

diff --git a/src/portal/src/app/account/account-settings/account-settings-modal.component.spec.ts b/src/portal/src/app/account/account-settings/account-settings-modal.component.spec.ts
index 662c46c50..e7540fbe8 100644
--- a/src/portal/src/app/account/account-settings/account-settings-modal.component.spec.ts
+++ b/src/portal/src/app/account/account-settings/account-settings-modal.component.spec.ts
@@ -17,6 +17,7 @@ import { clone } from '../../../lib/utils/utils';
 import { ConfirmationDialogComponent } from '../../shared/confirmation-dialog/confirmation-dialog.component';
 import { ConfirmationDialogService } from '../../shared/confirmation-dialog/confirmation-dialog.service';
 import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 describe('AccountSettingsModalComponent', () => {
     let component: AccountSettingsModalComponent;
@@ -78,6 +79,7 @@ describe('AccountSettingsModalComponent', () => {
             providers: [
                 ChangeDetectorRef,
                 TranslateService,
+                ErrorHandler,
                 { provide: SessionService, useValue: fakeSessionService },
                 { provide: MessageHandlerService, useValue: fakeMessageHandlerService },
                 { provide: SearchTriggerService, useValue: fakeSearchTriggerService },
diff --git a/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts b/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts
index 1c4483f17..3cfb7a71a 100644
--- a/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts
+++ b/src/portal/src/app/account/password-setting/forgot-password/forgot-password.component.spec.ts
@@ -8,6 +8,7 @@ import { PasswordSettingService } from '../password-setting.service';
 import { InlineAlertComponent } from '../../../shared/inline-alert/inline-alert.component';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { of } from 'rxjs';
+import { ErrorHandler } from '../../../../lib/utils/error-handler';
 
 describe('ForgotPasswordComponent', () => {
     let component: ForgotPasswordComponent;
@@ -28,6 +29,7 @@ describe('ForgotPasswordComponent', () => {
             schemas: [CUSTOM_ELEMENTS_SCHEMA],
             providers: [
                 TranslateService,
+                ErrorHandler,
                 { provide: PasswordSettingService, useValue: fakePasswordSettingService }
             ]
         }).compileComponents();
diff --git a/src/portal/src/app/account/password-setting/password-setting.component.spec.ts b/src/portal/src/app/account/password-setting/password-setting.component.spec.ts
index 1347d3cf3..a3617265f 100644
--- a/src/portal/src/app/account/password-setting/password-setting.component.spec.ts
+++ b/src/portal/src/app/account/password-setting/password-setting.component.spec.ts
@@ -10,6 +10,7 @@ import { FormsModule } from '@angular/forms';
 import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { of } from 'rxjs';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 describe('PasswordSettingComponent', () => {
     let component: PasswordSettingComponent;
@@ -37,7 +38,8 @@ describe('PasswordSettingComponent', () => {
                 TranslateService,
                 { provide: PasswordSettingService, useValue: fakePasswordSettingService },
                 { provide: SessionService, useValue: fakeSessionService },
-                { provide: MessageHandlerService, useValue: fakeMessageHandlerService }
+                { provide: MessageHandlerService, useValue: fakeMessageHandlerService },
+                ErrorHandler
             ],
             schemas: [CUSTOM_ELEMENTS_SCHEMA],
         }).compileComponents();
diff --git a/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts b/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts
index db510a4f0..e0e1f1c9c 100644
--- a/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts
+++ b/src/portal/src/app/account/password-setting/reset-password/reset-password.component.spec.ts
@@ -9,6 +9,7 @@ import { MessageHandlerService } from '../../../shared/message-handler/message-h
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { ClarityModule } from '@clr/angular';
 import { InlineAlertComponent } from '../../../shared/inline-alert/inline-alert.component';
+import { ErrorHandler } from '../../../../lib/utils/error-handler';
 
 describe('ResetPasswordComponent', () => {
     let component: ResetPasswordComponent;
@@ -30,6 +31,7 @@ describe('ResetPasswordComponent', () => {
                 TranslateService,
                 { provide: PasswordSettingService, useValue: fakePasswordSettingService },
                 { provide: MessageHandlerService, useValue: fakeMessageHandlerService },
+                ErrorHandler
             ],
             schemas: [CUSTOM_ELEMENTS_SCHEMA]
         }).compileComponents();
diff --git a/src/portal/src/app/account/sign-up/sign-up.component.spec.ts b/src/portal/src/app/account/sign-up/sign-up.component.spec.ts
index 27d621ea6..db96e9ba9 100644
--- a/src/portal/src/app/account/sign-up/sign-up.component.spec.ts
+++ b/src/portal/src/app/account/sign-up/sign-up.component.spec.ts
@@ -10,6 +10,7 @@ import { FormsModule } from '@angular/forms';
 import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { of } from 'rxjs';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 describe('SignUpComponent', () => {
     let component: SignUpComponent;
@@ -47,7 +48,8 @@ describe('SignUpComponent', () => {
             providers: [
                 TranslateService,
                 { provide: SessionService, useValue: fakeSessionService },
-                { provide: UserService, useValue: fakeUserService }
+                { provide: UserService, useValue: fakeUserService },
+                ErrorHandler
             ],
             schemas: [CUSTOM_ELEMENTS_SCHEMA]
         }).compileComponents();
diff --git a/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts b/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts
index 1ecf7669f..5e56dc452 100644
--- a/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts
+++ b/src/portal/src/app/base/harbor-shell/harbor-shell.component.spec.ts
@@ -20,6 +20,7 @@ import { PasswordSettingService } from '../../account/password-setting/password-
 import { SkinableConfig } from '../../services/skinable-config.service';
 import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
 import { AppConfigService } from "../../services/app-config.service";
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 describe('HarborShellComponent', () => {
     let component: HarborShellComponent;
@@ -86,6 +87,7 @@ describe('HarborShellComponent', () => {
                 { provide: AccountSettingsModalService, useValue: mockAccountSettingsModalService },
                 { provide: PasswordSettingService, useValue: mockPasswordSettingService },
                 { provide: SkinableConfig, useValue: mockSkinableConfig },
+                ErrorHandler
             ],
             schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
         }).compileComponents();
diff --git a/src/portal/src/app/global-message/message.component.html b/src/portal/src/app/global-message/message.component.html
index c3ecb1b1a..ba653063e 100644
--- a/src/portal/src/app/global-message/message.component.html
+++ b/src/portal/src/app/global-message/message.component.html
@@ -1,5 +1,5 @@
 <div [class.alert-app-level]="!isAppLevel" [hidden]="!globalMessageOpened">
-    <clr-alert  [clrAlertType]="globalMessage.type" [clrAlertAppLevel]="isAppLevel" [(clrAlertClosed)]="!globalMessageOpened" (clrAlertClosedChange)="onClose()">
+    <clr-alert  [clrAlertType]="globalMessage.type" [clrAlertClosable]="!needAuth" [clrAlertAppLevel]="isAppLevel" [(clrAlertClosed)]="!globalMessageOpened" (clrAlertClosedChange)="onClose()">
         <div class="alert-item">
             <span class="alert-text">{{message}}</span>
             <div class="alert-actions alert-style" *ngIf="needAuth">
diff --git a/src/portal/src/app/global-message/message.component.scss b/src/portal/src/app/global-message/message.component.scss
index e32f377ac..ba0761b10 100644
--- a/src/portal/src/app/global-message/message.component.scss
+++ b/src/portal/src/app/global-message/message.component.scss
@@ -5,5 +5,5 @@
     position: absolute;
     width: 100%;
     height: 100%;
-    z-index: 10000;
+    z-index: 1000;
 }
\ No newline at end of file
diff --git a/src/portal/src/app/global-message/message.component.ts b/src/portal/src/app/global-message/message.component.ts
index 80aa03a04..419912d00 100644
--- a/src/portal/src/app/global-message/message.component.ts
+++ b/src/portal/src/app/global-message/message.component.ts
@@ -126,7 +126,7 @@ export class MessageComponent implements OnInit, OnDestroy {
   }
 
   signIn(): void {
-    this.router.navigateByUrl(CommonRoutes.EMBEDDED_SIGN_IN);
+    this.router.navigate([ CommonRoutes.EMBEDDED_SIGN_IN ], {queryParams: {redirect_url: this.router.url}});
   }
 
   onClose() {
diff --git a/src/portal/src/app/project/create-project/create-project.component.spec.ts b/src/portal/src/app/project/create-project/create-project.component.spec.ts
index 63340be91..5b2d288f6 100644
--- a/src/portal/src/app/project/create-project/create-project.component.spec.ts
+++ b/src/portal/src/app/project/create-project/create-project.component.spec.ts
@@ -10,6 +10,7 @@ import { ProjectService } from "../../../lib/services";
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { of } from 'rxjs';
 import { delay } from 'rxjs/operators';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 describe('CreateProjectComponent', () => {
     let component: CreateProjectComponent;
@@ -47,6 +48,7 @@ describe('CreateProjectComponent', () => {
                 TranslateService,
                 {provide: ProjectService, useValue: mockProjectService},
                 {provide: MessageHandlerService, useValue: mockMessageHandlerService},
+                ErrorHandler
             ]
         }).compileComponents();
     }));
diff --git a/src/portal/src/app/project/helm-chart/helm-chart.service.ts b/src/portal/src/app/project/helm-chart/helm-chart.service.ts
index 122460ba7..5f4a85fcc 100644
--- a/src/portal/src/app/project/helm-chart/helm-chart.service.ts
+++ b/src/portal/src/app/project/helm-chart/helm-chart.service.ts
@@ -105,7 +105,7 @@ export class HelmChartDefaultService extends HelmChartService {
 
 
   private handleErrorObservable(error: HttpErrorResponse) {
-    return observableThrowError(error.error || error);
+    return observableThrowError(error);
   }
 
   public getHelmCharts(
diff --git a/src/portal/src/app/project/member/add-member/add-member.component.spec.ts b/src/portal/src/app/project/member/add-member/add-member.component.spec.ts
index 75944e657..7949eadcb 100644
--- a/src/portal/src/app/project/member/add-member/add-member.component.spec.ts
+++ b/src/portal/src/app/project/member/add-member/add-member.component.spec.ts
@@ -12,6 +12,7 @@ import { UserService } from '../../../user/user.service';
 import { of } from 'rxjs';
 import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
 import { ActivatedRoute } from '@angular/router';
+import { ErrorHandler } from '../../../../lib/utils/error-handler';
 
 describe('AddMemberComponent', () => {
     let component: AddMemberComponent;
@@ -54,6 +55,7 @@ describe('AddMemberComponent', () => {
                 { provide: MemberService, useValue: mockMemberService },
                 { provide: UserService, useValue: mockUserService },
                 { provide: MessageHandlerService, useValue: mockMessageHandlerService },
+                ErrorHandler,
                 {
                     provide: ActivatedRoute, useValue: {
                         RouterparamMap: of({ get: (key) => 'value' }),
diff --git a/src/portal/src/app/project/member/add-member/add-member.component.ts b/src/portal/src/app/project/member/add-member/add-member.component.ts
index 84b6fda2e..cdcbba10e 100644
--- a/src/portal/src/app/project/member/add-member/add-member.component.ts
+++ b/src/portal/src/app/project/member/add-member/add-member.component.ts
@@ -37,8 +37,7 @@ import {User} from "../../../user/user";
 import {Project} from "../../project";
 import { Member } from '../member';
 import { MemberService } from '../member.service';
-import { HttpResponseBase } from '@angular/common/http';
-import { errorHandler } from "../../../../lib/utils/shared/shared.utils";
+import { ErrorHandler } from '../../../../lib/utils/error-handler';
 
 
 @Component({
@@ -80,6 +79,7 @@ export class AddMemberComponent implements AfterViewChecked, OnInit, OnDestroy {
 
   constructor(private memberService: MemberService,
     private userService: UserService,
+    private errorHandle: ErrorHandler,
     private messageHandlerService: MessageHandlerService,
     private translateService: TranslateService,
     private route: ActivatedRoute,
@@ -158,22 +158,10 @@ export class AddMemberComponent implements AfterViewChecked, OnInit, OnDestroy {
       () => {
         this.messageHandlerService.showSuccess('MEMBER.ADDED_SUCCESS');
         this.added.emit(true);
-        // this.addMemberOpened = false;
       },
       error => {
-        if (error instanceof HttpResponseBase) {
-          if (this.messageHandlerService.isAppLevel(error)) {
-            this.messageHandlerService.handleError(error);
-            // this.addMemberOpened = false;
-          } else {
-          let errorMessageKey: string = errorHandler(error);
-            this.translateService
-              .get(errorMessageKey)
-              .subscribe(errorMessage => this.messageHandlerService.handleError(errorMessage));
-          }
-        }
+        this.errorHandle.error(error);
       });
-      // this.addMemberOpened = false;
   }
 
   selectedName(username: string) {
diff --git a/src/portal/src/app/project/member/member.component.ts b/src/portal/src/app/project/member/member.component.ts
index 393d6d4e6..22671a287 100644
--- a/src/portal/src/app/project/member/member.component.ts
+++ b/src/portal/src/app/project/member/member.component.ts
@@ -202,7 +202,7 @@ export class MemberComponent implements OnInit, OnDestroy {
         .changeMemberRole(projectId, member.id, roleId)
         .pipe(map(() => this.batchChangeRoleInfos[member.id] = 'done')
           , catchError(error => {
-            this.messageHandlerService.handleError(error + ": " + member.entity_name);
+            this.messageHandlerService.handleError(error);
             return observableThrowError(error);
           }));
     };
diff --git a/src/portal/src/app/project/tag-feature-integration/immutable-tag/add-rule/add-rule.component.spec.ts b/src/portal/src/app/project/tag-feature-integration/immutable-tag/add-rule/add-rule.component.spec.ts
index 1a6061580..047dd4e88 100644
--- a/src/portal/src/app/project/tag-feature-integration/immutable-tag/add-rule/add-rule.component.spec.ts
+++ b/src/portal/src/app/project/tag-feature-integration/immutable-tag/add-rule/add-rule.component.spec.ts
@@ -9,6 +9,8 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { NoopAnimationsModule } from "@angular/platform-browser/animations";
 import { InlineAlertComponent } from "../../../../shared/inline-alert/inline-alert.component";
 import { ImmutableRetentionRule } from "../../tag-retention/retention";
+import { ErrorHandler } from '../../../../../lib/utils/error-handler';
+
 describe('AddRuleComponent', () => {
   let component: AddRuleComponent;
   let fixture: ComponentFixture<AddRuleComponent>;
@@ -36,7 +38,9 @@ describe('AddRuleComponent', () => {
       ]
     }
   };
-
+  const mockErrorHandler = {
+    handleErrorPopupUnauthorized: () => {}
+  }
   beforeEach(async(() => {
     TestBed.configureTestingModule({
       declarations: [AddRuleComponent, InlineAlertComponent],
@@ -51,7 +55,11 @@ describe('AddRuleComponent', () => {
         TranslateModule.forRoot()
       ],
       providers: [
-        ImmutableTagService
+        ImmutableTagService,
+        ErrorHandler,
+        {
+          provide: ErrorHandler, useValue: mockErrorHandler
+        }
       ]
     })
       .compileComponents();
diff --git a/src/portal/src/app/project/tag-feature-integration/tag-retention/add-rule/add-rule.component.spec.ts b/src/portal/src/app/project/tag-feature-integration/tag-retention/add-rule/add-rule.component.spec.ts
index b6886ebb7..4fd8cf32c 100644
--- a/src/portal/src/app/project/tag-feature-integration/tag-retention/add-rule/add-rule.component.spec.ts
+++ b/src/portal/src/app/project/tag-feature-integration/tag-retention/add-rule/add-rule.component.spec.ts
@@ -11,10 +11,12 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { TagRetentionService } from "../tag-retention.service";
 import { InlineAlertComponent } from "../../../../shared/inline-alert/inline-alert.component";
 import { delay } from 'rxjs/operators';
+import { ErrorHandler } from '../../../../../lib/utils/error-handler';
 describe('AddRuleComponent', () => {
     let component: AddRuleComponent;
     let fixture: ComponentFixture<AddRuleComponent>;
     const mockTagRetentionService = { };
+
     beforeEach(async(() => {
         TestBed.configureTestingModule({
             schemas: [
@@ -32,6 +34,7 @@ describe('AddRuleComponent', () => {
             declarations: [AddRuleComponent, InlineAlertComponent],
             providers: [
                 TranslateService,
+                ErrorHandler,
                 { provide: TagRetentionService, useValue: mockTagRetentionService },
             ]
         })
diff --git a/src/portal/src/app/project/webhook/add-webhook-form/add-webhook-form.component.spec.ts b/src/portal/src/app/project/webhook/add-webhook-form/add-webhook-form.component.spec.ts
index a900ed190..97fca6e03 100644
--- a/src/portal/src/app/project/webhook/add-webhook-form/add-webhook-form.component.spec.ts
+++ b/src/portal/src/app/project/webhook/add-webhook-form/add-webhook-form.component.spec.ts
@@ -11,6 +11,7 @@ import { MessageHandlerService } from "../../../shared/message-handler/message-h
 import { of } from 'rxjs';
 import { Webhook } from "../webhook";
 import { InlineAlertComponent } from "../../../shared/inline-alert/inline-alert.component";
+import { ErrorHandler } from '../../../../lib/utils/error-handler';
 
 describe('AddWebhookFormComponent', () => {
     let component: AddWebhookFormComponent;
@@ -91,6 +92,7 @@ describe('AddWebhookFormComponent', () => {
                 TranslateService,
                 { provide: WebhookService, useValue: mockWebhookService },
                 { provide: MessageHandlerService, useValue: mockMessageHandlerService },
+                ErrorHandler
 
 
             ]
diff --git a/src/portal/src/app/project/webhook/webhook.component.spec.ts b/src/portal/src/app/project/webhook/webhook.component.spec.ts
index a86db5cd8..745cf4f09 100644
--- a/src/portal/src/app/project/webhook/webhook.component.spec.ts
+++ b/src/portal/src/app/project/webhook/webhook.component.spec.ts
@@ -18,6 +18,8 @@ import { InlineAlertComponent } from "../../shared/inline-alert/inline-alert.com
 import { AddWebhookComponent } from "./add-webhook/add-webhook.component";
 import { ConfirmationDialogComponent } from "../../../lib/components/confirmation-dialog";
 import { UserPermissionService } from '../../../lib/services';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
+
 describe('WebhookComponent', () => {
     let component: WebhookComponent;
     let fixture: ComponentFixture<WebhookComponent>;
@@ -121,6 +123,7 @@ describe('WebhookComponent', () => {
             ],
             providers: [
                 TranslateService,
+                ErrorHandler,
                 { provide: WebhookService, useValue: mockWebhookService },
                 { provide: MessageHandlerService, useValue: mockMessageHandlerService },
                 { provide: ActivatedRoute, useValue: mockActivatedRoute },
diff --git a/src/portal/src/app/shared/inline-alert/inline-alert.component.spec.ts b/src/portal/src/app/shared/inline-alert/inline-alert.component.spec.ts
index 17351cd37..918cad737 100644
--- a/src/portal/src/app/shared/inline-alert/inline-alert.component.spec.ts
+++ b/src/portal/src/app/shared/inline-alert/inline-alert.component.spec.ts
@@ -8,6 +8,9 @@ import { FormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 import { of } from 'rxjs';
 import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { MessageHandlerService } from '../message-handler/message-handler.service';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
+
 describe('InlineAlertComponent', () => {
     let component: InlineAlertComponent;
     let fixture: ComponentFixture<InlineAlertComponent>;
@@ -28,7 +31,8 @@ describe('InlineAlertComponent', () => {
             ],
             declarations: [InlineAlertComponent],
             providers: [
-                TranslateService
+                TranslateService,
+                ErrorHandler
             ]
         })
             .compileComponents();
diff --git a/src/portal/src/app/shared/inline-alert/inline-alert.component.ts b/src/portal/src/app/shared/inline-alert/inline-alert.component.ts
index 29f0daf2a..f441fb866 100644
--- a/src/portal/src/app/shared/inline-alert/inline-alert.component.ts
+++ b/src/portal/src/app/shared/inline-alert/inline-alert.component.ts
@@ -15,6 +15,8 @@ import { Component, Output, EventEmitter } from '@angular/core';
 import { TranslateService } from '@ngx-translate/core';
 import { Subscription } from "rxjs";
 import { errorHandler } from "../../../lib/utils/shared/shared.utils";
+import { MessageHandlerService } from '../message-handler/message-handler.service';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 @Component({
     selector: 'inline-alert',
@@ -35,7 +37,9 @@ export class InlineAlertComponent {
     @Output() confirmEvt = new EventEmitter<boolean>();
     @Output() closeEvt = new EventEmitter<boolean>();
 
-    constructor(private translate: TranslateService) { }
+    constructor(private translate: TranslateService,
+        private errHandler: ErrorHandler,
+        ) { }
 
     public get errorMessage(): string {
         return this.displayedText;
@@ -47,7 +51,7 @@ export class InlineAlertComponent {
         if (this.displayedText) {
             this.translate.get(this.displayedText).subscribe((res: string) => this.displayedText = res);
         }
-
+        this.errHandler.handleErrorPopupUnauthorized(error);
         this.inlineAlertType = 'danger';
         this.showCancelAction = false;
         this.inlineAlertClosable = true;
diff --git a/src/portal/src/app/shared/message-handler/message-handler.service.ts b/src/portal/src/app/shared/message-handler/message-handler.service.ts
index a21f3431a..ed72c7102 100644
--- a/src/portal/src/app/shared/message-handler/message-handler.service.ts
+++ b/src/portal/src/app/shared/message-handler/message-handler.service.ts
@@ -51,6 +51,19 @@ export class MessageHandlerService implements ErrorHandler {
             }
         }
     }
+    public handleErrorPopupUnauthorized(error: any | string): void {
+
+        if (!(error.statusCode || error.status)) {
+            return;
+        }
+        let msg = errorHandler(error);
+        let code = error.statusCode || error.status;
+        if (code === httpStatusCode.Unauthorized) {
+            this.msgService.announceAppLevelMessage(code, msg, AlertType.DANGER);
+            // Session is invalid now, clare session cache
+            this.session.clear();
+        }
+    }
 
     public handleReadOnly(): void {
         this.msgService.announceAppLevelMessage(503, 'REPO_READ_ONLY', AlertType.WARNING);
diff --git a/src/portal/src/lib/components/config/project-quotas/edit-project-quotas/edit-project-quotas.component.spec.ts b/src/portal/src/lib/components/config/project-quotas/edit-project-quotas/edit-project-quotas.component.spec.ts
index 2e1eccf37..134401570 100644
--- a/src/portal/src/lib/components/config/project-quotas/edit-project-quotas/edit-project-quotas.component.spec.ts
+++ b/src/portal/src/lib/components/config/project-quotas/edit-project-quotas/edit-project-quotas.component.spec.ts
@@ -5,6 +5,7 @@ import { EditQuotaQuotaInterface } from '../../../../services';
 import { HarborLibraryModule } from '../../../../harbor-library.module';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { CURRENT_BASE_HREF } from "../../../../utils/utils";
+import { ErrorHandler } from '../../../../utils/error-handler';
 
 describe('EditProjectQuotasComponent', () => {
   let component: EditProjectQuotasComponent;
@@ -27,6 +28,7 @@ describe('EditProjectQuotasComponent', () => {
       ],
       providers: [
         { provide: SERVICE_CONFIG, useValue: config },
+        ErrorHandler
       ]
     })
     .compileComponents();
diff --git a/src/portal/src/lib/components/inline-alert/inline-alert.component.ts b/src/portal/src/lib/components/inline-alert/inline-alert.component.ts
index 6491e6c31..f95ab1174 100644
--- a/src/portal/src/lib/components/inline-alert/inline-alert.component.ts
+++ b/src/portal/src/lib/components/inline-alert/inline-alert.component.ts
@@ -15,8 +15,8 @@ import { Component, Output, EventEmitter } from "@angular/core";
 import { TranslateService } from "@ngx-translate/core";
 
 import { errorHandler } from "../../utils/shared/shared.utils";
-// tslint:disable-next-line:no-unused-variable
 import { Observable,  Subscription } from "rxjs";
+import { ErrorHandler } from "../../../lib/utils/error-handler";
 
 @Component({
   selector: "hbr-inline-alert",
@@ -36,7 +36,9 @@ export class InlineAlertComponent {
 
   @Output() confirmEvt = new EventEmitter<boolean>();
 
-  constructor(private translate: TranslateService) {}
+  constructor(private translate: TranslateService,
+    private errHandler: ErrorHandler,
+    ) {}
 
   public get errorMessage(): string {
     return this.displayedText;
@@ -50,6 +52,7 @@ export class InlineAlertComponent {
         .get(this.displayedText)
         .subscribe((res: string) => (this.displayedText = res));
     }
+    this.errHandler.handleErrorPopupUnauthorized(error);
 
     this.inlineAlertType = "danger";
     this.showCancelAction = false;
diff --git a/src/portal/src/lib/components/push-image/push-image.component.spec.ts b/src/portal/src/lib/components/push-image/push-image.component.spec.ts
index caa2e3871..b4cf734b7 100644
--- a/src/portal/src/lib/components/push-image/push-image.component.spec.ts
+++ b/src/portal/src/lib/components/push-image/push-image.component.spec.ts
@@ -6,6 +6,7 @@ import { InlineAlertComponent } from '../inline-alert/inline-alert.component';
 
 import { SERVICE_CONFIG, IServiceConfig } from '../../entities/service.config';
 import { SharedModule } from '../../utils/shared/shared.module';
+import { ErrorHandler } from '../../../lib/utils/error-handler';
 
 describe('PushImageButtonComponent (inline template)', () => {
   let component: PushImageButtonComponent;
@@ -19,7 +20,8 @@ describe('PushImageButtonComponent (inline template)', () => {
       ],
       declarations: [InlineAlertComponent, CopyInputComponent, PushImageButtonComponent],
       providers: [
-        { provide: SERVICE_CONFIG, useValue: {} }
+        { provide: SERVICE_CONFIG, useValue: {} },
+        ErrorHandler
       ]
     });
 
diff --git a/src/portal/src/lib/components/replication/replication.component.spec.ts b/src/portal/src/lib/components/replication/replication.component.spec.ts
index ac2e1a2bc..faa1104f4 100644
--- a/src/portal/src/lib/components/replication/replication.component.spec.ts
+++ b/src/portal/src/lib/components/replication/replication.component.spec.ts
@@ -1,6 +1,6 @@
 import { ComponentFixture, TestBed, async } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
-import { DebugElement } from '@angular/core';
+import { DebugElement, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
 import { NoopAnimationsModule } from "@angular/platform-browser/animations";
 
 import { SharedModule } from '../../utils/shared/shared.module';
@@ -155,6 +155,7 @@ describe('Replication Component (inline template)', () => {
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
+      schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
       imports: [
         SharedModule,
         NoopAnimationsModule,
diff --git a/src/portal/src/lib/utils/error-handler/error-handler.ts b/src/portal/src/lib/utils/error-handler/error-handler.ts
index cd13fdefd..41c0343c9 100644
--- a/src/portal/src/lib/utils/error-handler/error-handler.ts
+++ b/src/portal/src/lib/utils/error-handler/error-handler.ts
@@ -47,6 +47,8 @@ export abstract class ErrorHandler {
    * @memberOf ErrorHandler
    */
   abstract log(log: any): void;
+
+  abstract handleErrorPopupUnauthorized(error: any): void;
 }
 
 @Injectable()
@@ -67,4 +69,7 @@ export class DefaultErrorHandler extends ErrorHandler {
   public log(log: any): void {
     console.log("[Default log handler]: ", log);
   }
+  public handleErrorPopupUnauthorized(error: any): void {
+    console.log("[Default log handler]: ", error);
+  }
 }