Bläddra i källkod

auto logout by localstorage monitoring and remote websocket notifications

tags/2.037
Patrick Sun 4 år sedan
förälder
incheckning
f31d14d1cb
4 ändrade filer med 74 tillägg och 22 borttagningar
  1. +11
    -5
      src/app/app.component.ts
  2. +11
    -1
      src/app/auth/auth.component.ts
  3. +1
    -6
      src/app/service/auth.service.ts
  4. +51
    -10
      src/app/service/session.service.ts

+ 11
- 5
src/app/app.component.ts Visa fil

@@ -61,11 +61,17 @@ export class AppComponent implements OnInit , OnDestroy {
}

onWSLogin(e: WsLoginEventModel): void {
if ( e.Mid === this.ss.loggedIn.machineId && e.Sid === this.ss.loggedIn.session ){
if ( e.Uid !== this.ss.loggedIn.User.Id && e.Uid !== '') {
this.ss.logout();
}
if ( e.T === 'logout' ) { // regardless where are they, logout means logout
if ( this.ss.isCurrentUser(e.Uid) ) {
this.ss.logoutAndClearLocalStorage();
}
}else{ // some one logged in from another browser tab
if ( e.Mid === this.ss.loggedIn.machineId) { // same browser
if ( !this.ss.isCurrentUser(e.Uid) ) {
this.ss.logoutWithoutPersistingStorage();
}
}
}
}

}


+ 11
- 1
src/app/auth/auth.component.ts Visa fil

@@ -25,7 +25,11 @@ export class AuthComponent implements OnInit, OnDestroy{
private router: Router, private notificationService: NotificationService) { }

ngOnInit(): void {
this.authService.logout();
if ( this.ss.loggedIn.login ){
this.ss.logout();
}

// this.ss.logoutAndClearLocalStorage();
this.loginSub = this.ss.loginSuccess.subscribe(
responseData => {
// console.log(responseData);
@@ -52,6 +56,12 @@ export class AuthComponent implements OnInit, OnDestroy{
case 'admin':
this.router.navigate(['/dashboard']);
break;
case 'manager':
this.router.navigate(['/dashboard']);
break;
case 'accountant':
this.router.navigate(['/dashboard']);
break;
case 'broker':
this.router.navigate(['/broker-loan-list']);
break;

+ 1
- 6
src/app/service/auth.service.ts Visa fil

@@ -46,11 +46,6 @@ export class AuthService {
return true;
}

saveSessionInfo(): void {
localStorage.setItem(this.config.storageKey, JSON.stringify(this.ss.loggedIn));
localStorage.setItem('mid', this.ss.loggedIn.machineId);
}

login(email: string, password: string): void {

this.http.post<ApiV1LoginResponse>(this.config.apiUrl + 'login', {u: email, p: password}).subscribe(
@@ -72,7 +67,7 @@ export class AuthService {
this.ss.loggedIn.User = PeopleModel.EmptyNew();
}

this.saveSessionInfo();
this.ss.saveSessionInfo();
this.ss.loginSuccess.emit(responseData);
},
error => {

+ 51
- 10
src/app/service/session.service.ts Visa fil

@@ -5,14 +5,34 @@ import {PeopleModel} from '../models/people.model';
import {HttpClient} from '@angular/common/http';
import {Router} from '@angular/router';
import {NotificationService} from '@progress/kendo-angular-notification';
import {debounce} from 'ts-debounce';

@Injectable()
export class SessionService {
public loggedIn = ApiV1LoginResponse.EmptyNew();
loginSuccess = new EventEmitter <ApiV1LoginResponse>();

debouncedLocalStorageMonitor = debounce( this.localStorageChange, 1000); // to avoid to frequent local storage changes

constructor(private config: AppConfig, private http: HttpClient, private router: Router, private ns: NotificationService){ }
constructor(private config: AppConfig, private http: HttpClient, private router: Router, private ns: NotificationService){
const self = this;
window.addEventListener('storage', event => {
if (event.storageArea === localStorage && event.key === this.config.storageKey) {
// It's local storage
self.debouncedLocalStorageMonitor(event).then( r => {});
}
}, false);
}

private localStorageChange(event: StorageEvent): void {
console.log(event);
const sfm: ApiV1LoginResponse = JSON.parse(localStorage.getItem(this.config.storageKey));
if ( sfm && sfm.session && sfm.User && sfm.User.Id && this.loggedIn.User.Id) {
if ( sfm.session === this.loggedIn.session && sfm.User.Id !== this.loggedIn.User.Id){
this.logoutWithoutPersistingStorage(); // silently logout without touching any storage
}
}
}

public saveSessionInfo(): void {
localStorage.setItem(this.config.storageKey, JSON.stringify(this.loggedIn));
@@ -32,7 +52,7 @@ export class SessionService {
}

public isCurrentUser(id: string): boolean {
return this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id;
return id !== '' && this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id;
}

public UpdatePeopleInfo(people: PeopleModel): void{
@@ -47,24 +67,45 @@ export class SessionService {
return;
}
this.loggedIn = ApiV1LoginResponse.EmptyNew();
localStorage.removeItem(this.config.storageKey);
this.loginSuccess.emit(this.loggedIn);
this.router.navigate(['/login']).then(r => {
this.show();
} );
this.router.navigate(['/login']);
localStorage.removeItem(this.config.storageKey);
this.http.post(`${this.config.apiUrl}logout`, '').subscribe(
resp => {
console.log('successfully logout from server');
this.show();
},
event => {
console.log('error logout from server', event);
this.show('logout from server (with warnings)');
}
);
}

public show(): void {
logoutWithoutPersistingStorage(): void {
if ( !this.loggedIn.login ){
return;
}
this.loggedIn = ApiV1LoginResponse.EmptyNew();
this.loginSuccess.emit(this.loggedIn);
this.router.navigate(['/login']).then(r => {
this.show();
} );
}

logoutAndClearLocalStorage(): void {
if ( !this.loggedIn.login ){
return;
}
localStorage.removeItem(this.config.storageKey);
this.loggedIn = ApiV1LoginResponse.EmptyNew();
this.loginSuccess.emit(this.loggedIn);
this.router.navigate(['/login']).then(r => {
this.show();
} );
}

public show( msg: string = 'Successfully logged out'): void {
this.ns.show({
content: 'Successfully logged out',
content: msg,
cssClass: 'button-notification',
animation: { type: 'slide', duration: 400 },
position: { horizontal: 'center', vertical: 'top' },

Laddar…
Avbryt
Spara