Commit 41bb91f2 authored by Steven Zou's avatar Steven Zou
Browse files

applied unique message handler and fix signin issue when code is 401

parent 6a61d8bd
......@@ -3,10 +3,8 @@ import { NgForm } from '@angular/forms';
import { SessionUser } from '../../shared/session-user';
import { SessionService } from '../../shared/session.service';
import { MessageService } from '../../global-message/message.service';
import { AlertType, httpStatusCode } from '../../shared/shared.const';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: "account-settings-modal",
......@@ -38,7 +36,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
constructor(
private session: SessionService,
private msgService: MessageService) { }
private msgHandler: MessageHandlerService) { }
ngOnInit(): void {
//Value copy
......@@ -112,10 +110,10 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
}
public get isValid(): boolean {
return this.accountForm &&
this.accountForm.valid &&
this.error === null &&
this.validationStateMap["account_settings_email"]; //backend check is valid as well
return this.accountForm &&
this.accountForm.valid &&
this.error === null &&
this.validationStateMap["account_settings_email"]; //backend check is valid as well
}
public get showProgress(): boolean {
......@@ -182,14 +180,15 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
.then(() => {
this.isOnCalling = false;
this.opened = false;
this.msgService.announceMessage(200, "PROFILE.SAVE_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("PROFILE.SAVE_SUCCESS");
})
.catch(error => {
this.isOnCalling = false;
this.error = error;
if (accessErrorHandler(error, this.msgService)) {
if (this.msgHandler.isAppLevel(error)) {
this.opened = false;
} else {
this.msgHandler.handleError(error);
}else{
this.inlineAlert.showInlineError(error);
}
});
......
......@@ -4,10 +4,9 @@ import { NgForm } from '@angular/forms';
import { PasswordSettingService } from './password-setting.service';
import { SessionService } from '../../shared/session.service';
import { AlertType, httpStatusCode } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { errorHandler, isEmptyForm, accessErrorHandler } from '../../shared/shared.utils';
import { isEmptyForm } from '../../shared/shared.utils';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: 'password-setting',
......@@ -36,7 +35,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
constructor(
private passwordService: PasswordSettingService,
private session: SessionService,
private msgService: MessageService) { }
private msgHandler: MessageHandlerService) { }
//If form is valid
public get isValid(): boolean {
......@@ -66,10 +65,10 @@ export class PasswordSettingComponent implements AfterViewChecked {
let cont = this.pwdForm.controls[key];
if (cont) {
this.validationStateMap[key] = cont.valid;
if(key === "reNewPassword" && cont.valid){
if (key === "reNewPassword" && cont.valid) {
let compareCont = this.pwdForm.controls["newPassword"];
if(compareCont){
this.validationStateMap[key]= cont.value === compareCont.value;
if (compareCont) {
this.validationStateMap[key] = cont.value === compareCont.value;
}
}
}
......@@ -145,16 +144,23 @@ export class PasswordSettingComponent implements AfterViewChecked {
})
.then(() => {
this.onCalling = false;
this.opened = false;
this.msgService.announceMessage(200, "CHANGE_PWD.SAVE_SUCCESS", AlertType.SUCCESS);
this.opened = false
this.msgHandler.showSuccess("CHANGE_PWD.SAVE_SUCCESS");
})
.catch(error => {
this.onCalling = false;
this.error = error;
if(accessErrorHandler(error, this.msgService)){
if (this.msgHandler.isAppLevel(error)) {
this.opened = false;
}else{
this.inlineAlert.showInlineError(error);
this.msgHandler.handleError(error);
} else {
//Special case for 400
let msg = '' + error._body;
if (msg && msg.includes('old_password_is_not_correct')) {
this.inlineAlert.showInlineError("INCONRRECT_OLD_PWD");
} else {
this.inlineAlert.showInlineError(error);
}
}
});
}
......
......@@ -4,16 +4,14 @@ import { NgForm } from '@angular/forms';
import { PasswordSettingService } from './password-setting.service';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { AlertType } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: 'reset-password',
templateUrl: "reset-password.component.html",
styleUrls: ['password.component.css', '../../common.css']
})
export class ResetPasswordComponent implements OnInit{
export class ResetPasswordComponent implements OnInit {
opened: boolean = true;
private onGoing: boolean = false;
private password: string = "";
......@@ -28,7 +26,7 @@ export class ResetPasswordComponent implements OnInit{
constructor(
private pwdService: PasswordSettingService,
private route: ActivatedRoute,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private router: Router) { }
ngOnInit(): void {
......@@ -44,9 +42,9 @@ export class ResetPasswordComponent implements OnInit{
}
public getValidationState(key: string): boolean {
return this.validationState &&
this.validationState[key] &&
key === 'reNewPassword'?this.samePassword():true;
return this.validationState &&
this.validationState[key] &&
key === 'reNewPassword' ? this.samePassword() : true;
}
public open(): void {
......@@ -61,7 +59,7 @@ export class ResetPasswordComponent implements OnInit{
public send(): void {
//If already reset password ok, navigator to sign-in
if(this.resetOk){
if (this.resetOk) {
this.router.navigate(['sign-in']);
return;
}
......@@ -77,24 +75,24 @@ export class ResetPasswordComponent implements OnInit{
this.onGoing = true;
this.pwdService.resetPassword(this.resetUuid, this.password)
.then(() => {
this.onGoing = false;
this.resetOk = true;
this.inlineAlert.showInlineSuccess({message:'RESET_PWD.RESET_OK'});
})
.catch(error => {
this.onGoing = false;
if(accessErrorHandler(error, this.msgService)){
this.close();
}else{
this.inlineAlert.showInlineError(errorHandler(error));
}
});
.then(() => {
this.onGoing = false;
this.resetOk = true;
this.inlineAlert.showInlineSuccess({ message: 'RESET_PWD.RESET_OK' });
})
.catch(error => {
this.onGoing = false;
if (this.msgHandler.isAppLevel(error)) {
this.close();
} else {
this.inlineAlert.showInlineError(error);
}
});
}
public handleValidation(key: string, flag: boolean): void {
if (flag) {
if(!this.validationState[key]){
if (!this.validationState[key]) {
this.validationState[key] = true;
}
} else {
......
......@@ -6,7 +6,6 @@ import { User } from '../../user/user';
import { SessionService } from '../../shared/session.service';
import { UserService } from '../../user/user.service';
import { errorHandler } from '../../shared/shared.utils';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { Modal } from 'clarity-angular';
......
......@@ -2,14 +2,12 @@ import { Component, Output, EventEmitter, OnInit, OnDestroy } from '@angular/cor
import { GlobalSearchService } from './global-search.service';
import { SearchResults } from './search-results';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { AlertType, ListMode } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { SearchTriggerService } from './search-trigger.service';
import { Subscription } from 'rxjs/Subscription';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: "search-result",
templateUrl: "search-result.component.html",
......@@ -38,7 +36,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
constructor(
private search: GlobalSearchService,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private searchTrigger: SearchTriggerService) { }
ngOnInit() {
......@@ -73,10 +71,6 @@ export class SearchResultComponent implements OnInit, OnDestroy {
return res//Empty object
}
public get listMode(): string {
return ListMode.READONLY;
}
public get state(): boolean {
return this.stateIndicator;
}
......@@ -134,9 +128,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
})
.catch(error => {
this.onGoing = false;
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.DANGER);
}
this.msgHandler.handleError(error);
});
}
}
\ No newline at end of file
......@@ -9,11 +9,10 @@ import { SessionUser } from '../../shared/session-user';
import { SessionService } from '../../shared/session.service';
import { CookieService } from 'angular2-cookie/core';
import { supportedLangs, enLang, languageNames, CommonRoutes, AlertType } from '../../shared/shared.const';
import { errorHandler } from '../../shared/shared.utils';
import { supportedLangs, enLang, languageNames, CommonRoutes } from '../../shared/shared.const';
import { AppConfigService } from '../../app-config.service';
import { SearchTriggerService } from '../global-search/search-trigger.service';
import { MessageService } from '../../global-message/message.service';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: 'navigator',
......@@ -35,7 +34,7 @@ export class NavigatorComponent implements OnInit {
private translate: TranslateService,
private cookie: CookieService,
private appConfigService: AppConfigService,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private searchTrigger: SearchTriggerService) { }
ngOnInit(): void {
......@@ -71,10 +70,10 @@ export class NavigatorComponent implements OnInit {
}
public get canDownloadCert(): boolean {
return this.session.getCurrentUser() &&
this.session.getCurrentUser().has_admin_role>0 &&
this.appConfigService.getConfig() &&
this.appConfigService.getConfig().has_ca_root;
return this.session.getCurrentUser() &&
this.session.getCurrentUser().has_admin_role > 0 &&
this.appConfigService.getConfig() &&
this.appConfigService.getConfig().has_ca_root;
}
matchLang(lang: string): boolean {
......@@ -113,7 +112,7 @@ export class NavigatorComponent implements OnInit {
this.router.navigate([CommonRoutes.EMBEDDED_SIGN_IN]);
})
.catch(error => {
this.msgService.announceMessage(error.status | 500, errorHandler(error), AlertType.WARNING);
this.msgHandler.handleError(error);
});
//Confirm search result panel is close
this.searchTrigger.closeSearch(true);
......
......@@ -4,9 +4,7 @@ import { NgForm } from '@angular/forms';
import { ConfigurationService } from './config.service';
import { Configuration } from './config';
import { MessageService } from '../global-message/message.service';
import { AlertType, ConfirmationTargets, ConfirmationState } from '../shared/shared.const';
import { errorHandler, accessErrorHandler } from '../shared/shared.utils';
import { ConfirmationTargets, ConfirmationState } from '../shared/shared.const';;
import { StringValueItem } from './config';
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
import { Subscription } from 'rxjs/Subscription';
......@@ -17,6 +15,7 @@ import { ConfigurationEmailComponent } from './email/config-email.component';
import { AppConfigService } from '../app-config.service';
import { SessionService } from '../shared/session.service';
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
const fakePass = "fakepassword";
const TabLinkContentMap = {
......@@ -45,7 +44,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
@ViewChild(ConfigurationAuthComponent) authConfig: ConfigurationAuthComponent;
constructor(
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private configService: ConfigurationService,
private confirmService: ConfirmationDialogService,
private appConfigService: AppConfigService,
......@@ -204,13 +203,11 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
//Reload bootstrap option
this.appConfigService.load().catch(error => console.error("Failed to reload bootstrap option with error: ", error));
this.msgService.announceMessage(response.status, "CONFIG.SAVE_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("CONFIG.SAVE_SUCCESS");
})
.catch(error => {
this.onGoing = false;
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.DANGER);
}
this.msgHandler.handleError(error);
});
} else {
//Inprop situation, should not come here
......@@ -262,11 +259,15 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
this.configService.testMailServer(mailSettings)
.then(response => {
this.testingOnGoing = false;
this.msgService.announceMessage(200, "CONFIG.TEST_MAIL_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("CONFIG.TEST_MAIL_SUCCESS");
})
.catch(error => {
this.testingOnGoing = false;
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.WARNING);
let err = error._body;
if(!err){
err = "UNKNOWN";
}
this.msgHandler.showError("CONFIG.TEST_MAIL_FAILED", {'param': err});
});
}
......@@ -279,7 +280,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
}
let allChanges = this.getChanges();
for(let prop in allChanges){
for (let prop in allChanges) {
if (prop.startsWith("ldap_")) {
ldapSettings[prop] = allChanges[prop];
}
......@@ -291,11 +292,15 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
this.configService.testLDAPServer(ldapSettings)
.then(respone => {
this.testingOnGoing = false;
this.msgService.announceMessage(200, "CONFIG.TEST_LDAP_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("CONFIG.TEST_LDAP_SUCCESS");
})
.catch(error => {
this.testingOnGoing = false;
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.WARNING);
let err = error._body;
if(!err){
err = "UNKNOWN";
}
this.msgHandler.showError("CONFIG.TEST_LDAP_FAILED", err);
});
}
......@@ -342,9 +347,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
})
.catch(error => {
this.onGoing = false;
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.DANGER);
}
this.msgHandler.handleError(error);
});
}
......
......@@ -17,7 +17,7 @@ export class InlineAlertComponent {
@Output() confirmEvt = new EventEmitter<boolean>();
constructor(private translate: TranslateService){}
constructor(private translate: TranslateService) { }
public get errorMessage(): string {
return this.displayedText;
......@@ -26,6 +26,9 @@ export class InlineAlertComponent {
//Show error message inline
public showInlineError(error: any): void {
this.displayedText = errorHandler(error);
if (this.displayedText) {
this.translate.get(this.displayedText).subscribe((res: string) => this.displayedText = res);
}
this.inlineAlertType = 'alert-danger';
this.showCancelAction = false;
......@@ -37,7 +40,7 @@ export class InlineAlertComponent {
//Show confirmation info with action button
public showInlineConfirmation(warning: any): void {
this.displayedText = "";
if(warning && warning.message){
if (warning && warning.message) {
this.translate.get(warning.message).subscribe((res: string) => this.displayedText = res);
}
this.inlineAlertType = 'alert-warning';
......@@ -50,7 +53,7 @@ export class InlineAlertComponent {
//Show inline sccess info
public showInlineSuccess(info: any): void {
this.displayedText = "";
if(info && info.message){
if (info && info.message) {
this.translate.get(info.message).subscribe((res: string) => this.displayedText = res);
}
this.inlineAlertType = 'alert-success';
......
......@@ -3,11 +3,17 @@ import { Subject } from 'rxjs/Subject';
import { MessageService } from '../../global-message/message.service';
import { AlertType, httpStatusCode } from '../../shared/shared.const';
import { errorHandler } from '../../shared/shared.utils';
import { TranslateService } from '@ngx-translate/core';
import { SessionService } from '../../shared/session.service';
@Injectable()
export class MessageHandlerService {
constructor(private msgService: MessageService) { }
constructor(
private msgService: MessageService,
private translate: TranslateService,
private session: SessionService) { }
//Handle the error and map it to the suitable message
//base on the status code of error.
......@@ -16,42 +22,31 @@ export class MessageHandlerService {
if (!error) {
return;
}
console.log(JSON.stringify(error));
let msg = errorHandler(error);
if (!(error.statusCode || error.status)) {
//treat as string message
let msg = '' + error;
this.msgService.announceMessage(500, msg, AlertType.DANGER);
} else {
let msg = 'UNKNOWN_ERROR';
switch (error.statusCode || error.status) {
case 400:
msg = "BAD_REQUEST_ERROR";
break;
case 401:
msg = "UNAUTHORIZED_ERROR";
this.msgService.announceAppLevelMessage(error.statusCode, msg, AlertType.DANGER);
return;
case 403:
msg = "FORBIDDEN_ERROR";
break;
case 404:
msg = "NOT_FOUND_ERROR";
break;
case 412:
case 409:
msg = "CONFLICT_ERROR";
break;
case 500:
msg = "SERVER_ERROR";
break;
default:
break;
let code = error.statusCode | error.status;
if (code === httpStatusCode.Unauthorized) {
this.msgService.announceAppLevelMessage(code, msg, AlertType.DANGER);
//Session is invalida now, clare session cache
this.session.clear();
} else {
this.msgService.announceMessage(code, msg, AlertType.DANGER);
}
this.msgService.announceMessage(error.statusCode, msg, AlertType.DANGER);
}
}
public showError(message: string, params: any): void {
if (!params) {
params = {};
}
this.translate.get(message, params).subscribe((res: string) => {
this.msgService.announceMessage(500, res, AlertType.DANGER);
});
}
public showSuccess(message: string): void {
if (message && message.trim() != "") {
this.msgService.announceMessage(200, message, AlertType.SUCCESS);
......
......@@ -46,6 +46,12 @@ export class SessionService {
return Promise.reject(error.message || error);
}
//Clear session
clear(): void {
this.currentUser = null;
this.projectMembers = [];
}
//Submit signin form to backend (NOT restful service)
signIn(signInCredential: SignInCredential): Promise<any> {
//Build the form package
......
......@@ -8,19 +8,33 @@ import { MessageService } from '../global-message/message.service';
* @returns {string}
*/
export const errorHandler = function (error: any): string {
if (error) {
if (error.message) {
return error.message;
} else if (error._body) {
return error._body;
} else if (error.statusText) {
return error.statusText;
} else {
return error;
}
if (!error) {
return "UNKNOWN_ERROR";
}
console.log(JSON.stringify(error));
return "UNKNOWN_ERROR";
if (!(error.statusCode || error.status)) {
//treat as string message
return '' + error;
} else {
switch (error.statusCode || error.status) {
case 400:
return "BAD_REQUEST_ERROR";
case 401:
return "UNAUTHORIZED_ERROR";
case 403:
return "FORBIDDEN_ERROR";
case 404:
return "NOT_FOUND_ERROR";
case 412:
case 409:
return "CONFLICT_ERROR";
case 500:
return "SERVER_ERROR";
default:
return "UNKNOWN_ERROR";
}
}