diff --git a/projects/ucap-webmessenger-app/src/app/services/app.service.ts b/projects/ucap-webmessenger-app/src/app/services/app.service.ts index c6ea4e04..62f03f52 100644 --- a/projects/ucap-webmessenger-app/src/app/services/app.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/app.service.ts @@ -1,8 +1,36 @@ import { Injectable } from '@angular/core'; +import { filter, tap } from 'rxjs/operators'; + +import { Store } from '@ngrx/store'; + +import { ProtocolService } from '@ucap-webmessenger/protocol'; +import { + SVC_TYPE_LOGOUT, + SSVC_TYPE_LOGOUT_RES +} from '@ucap-webmessenger/protocol-authentication'; + +import * as AuthenticationStore from '../store/account/authentication'; + @Injectable() export class AppService { - constructor() {} + constructor( + private protocolService: ProtocolService, + private store: Store + ) { + this.protocolService.serverMessage + .pipe( + filter( + res => + res.serviceType === SVC_TYPE_LOGOUT && + res.subServiceType === SSVC_TYPE_LOGOUT_RES + ), + tap(res => { + this.store.dispatch(AuthenticationStore.logout()); + }) + ) + .subscribe(); + } public postInit(): Promise { return new Promise((resolve, reject) => { diff --git a/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts b/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts index a8079f9c..ee825ca2 100644 --- a/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts +++ b/projects/ucap-webmessenger-app/src/app/services/authentication.service.ts @@ -6,9 +6,9 @@ import { SessionStorageService, LocalStorageService } from '@ucap-webmessenger/web-storage'; -import { LoginInfo, KEY_LOGIN_INFO } from '../types'; import { EnviromentUtilService } from '@ucap-webmessenger/util'; import { DeviceType } from '@ucap-webmessenger/core'; +import { LoginInfo, KEY_LOGIN_INFO } from '../types'; @Injectable({ providedIn: 'root' @@ -56,5 +56,7 @@ export class AuthenticationService { } } - logout() {} + logout() { + this.sessionStorageService.remove(KEY_LOGIN_INFO); + } } diff --git a/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts b/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts index 700222a8..4cb92332 100644 --- a/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/account/authentication/effects.ts @@ -4,31 +4,32 @@ import { Router } from '@angular/router'; import { Actions, ofType, createEffect } from '@ngrx/effects'; import { of } from 'rxjs'; -import { - catchError, - exhaustMap, - map, - tap, - switchMap, - take -} from 'rxjs/operators'; +import { catchError, exhaustMap, map, tap, take } from 'rxjs/operators'; import { PiService, Login2Response, ResponseStatus } from '@ucap-webmessenger/pi'; +import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; +import { + DialogService, + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult +} from '@ucap-webmessenger/ui'; import { login, loginSuccess, loginFailure, loginRedirect, - logout + logout, + logoutConfirmation, + logoutConfirmationDismiss } from './actions'; import { LoginInfo } from '../../../types'; import { AuthenticationService } from '../../../services/authentication.service'; -import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; @Injectable() export class Effects { @@ -72,7 +73,7 @@ export class Effects { take(1), map((update: boolean) => { if (!update) { - this.authentication.login( + this.authenticationService.login( params.loginInfo, params.rememberMe ); @@ -90,7 +91,7 @@ export class Effects { loginRedirect$ = createEffect( () => this.actions$.pipe( - ofType(loginRedirect, logout), + ofType(loginRedirect), tap(authed => { this.router.navigate(['/account/login']); }) @@ -98,11 +99,45 @@ export class Effects { { dispatch: false } ); + logout$ = createEffect(() => + this.actions$.pipe( + ofType(logout), + map(action => action), + map(() => { + this.authenticationService.logout(); + return loginRedirect(); + }) + ) + ); + + logoutConfirmation$ = createEffect(() => + this.actions$.pipe( + ofType(logoutConfirmation), + exhaustMap(async () => { + const result = await this.dialogService.open< + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult + >(ConfirmDialogComponent, { + width: '220px', + data: { + title: 'Logout', + message: 'Logout ?' + } + }); + + return result.choice; + }), + map(result => (result ? logout() : logoutConfirmationDismiss())) + ) + ); + constructor( private actions$: Actions, + private router: Router, private piService: PiService, - private authentication: AuthenticationService, - @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, - private router: Router + private authenticationService: AuthenticationService, + private dialogService: DialogService, + @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService ) {} } diff --git a/projects/ucap-webmessenger-protocol-authentication/src/lib/models/logout.ts b/projects/ucap-webmessenger-protocol-authentication/src/lib/models/logout.ts new file mode 100644 index 00000000..e44e9edf --- /dev/null +++ b/projects/ucap-webmessenger-protocol-authentication/src/lib/models/logout.ts @@ -0,0 +1,7 @@ +import { ProtocolRequest, ProtocolResponse } from '@ucap-webmessenger/protocol'; + +// tslint:disable-next-line: no-empty-interface +export interface LogoutRequest extends ProtocolRequest {} + +// tslint:disable-next-line: no-empty-interface +export interface LogoutResponse extends ProtocolResponse {} diff --git a/projects/ucap-webmessenger-protocol-authentication/src/lib/services/authentication-protocol.service.ts b/projects/ucap-webmessenger-protocol-authentication/src/lib/services/authentication-protocol.service.ts index bcf5a237..dea6c3ec 100644 --- a/projects/ucap-webmessenger-protocol-authentication/src/lib/services/authentication-protocol.service.ts +++ b/projects/ucap-webmessenger-protocol-authentication/src/lib/services/authentication-protocol.service.ts @@ -12,9 +12,11 @@ import { LoginRequest, LoginResponse } from '../models/login'; import { SVC_TYPE_LOGIN, SSVC_TYPE_LOGIN_REQ, - SSVC_TYPE_LOGIN_RES + SVC_TYPE_LOGOUT, + SSVC_TYPE_LOGOUT_REQ } from '../types/service'; import { RoleCode } from '../types/role-code'; +import { LogoutRequest, LogoutResponse } from '../models/logout'; @Injectable({ providedIn: 'root' @@ -95,4 +97,14 @@ export class AuthenticationProtocolService { }) ); } + + public logout(req: LogoutRequest): Observable { + return this.protocolService + .call(SVC_TYPE_LOGOUT, SSVC_TYPE_LOGOUT_REQ) + .pipe( + map(res => { + return {} as LogoutResponse; + }) + ); + } } diff --git a/projects/ucap-webmessenger-protocol-authentication/src/lib/types/service.ts b/projects/ucap-webmessenger-protocol-authentication/src/lib/types/service.ts index 6f876941..8e12e779 100644 --- a/projects/ucap-webmessenger-protocol-authentication/src/lib/types/service.ts +++ b/projects/ucap-webmessenger-protocol-authentication/src/lib/types/service.ts @@ -2,7 +2,7 @@ export const SVC_TYPE_LOGIN = 1; export const SSVC_TYPE_LOGIN_REQ = 1; // 로그인 요청 export const SSVC_TYPE_LOGIN_RES = 2; // 로그인 성공 export const SSVC_TYPE_FMC_INFO_REQ = 101; // FMC 정보요청 -export const SSVC_TYPE_FMC_INFO = 100; // FMC 정보 +export const SSVC_TYPE_FMC_INFO_RES = 100; // FMC 정보 export const SVC_TYPE_LOGOUT = 2; export const SSVC_TYPE_LOGOUT_REQ = 1; // 로그아웃 요청 diff --git a/projects/ucap-webmessenger-protocol-authentication/src/public-api.ts b/projects/ucap-webmessenger-protocol-authentication/src/public-api.ts index 7ba9b75e..d4f62e76 100644 --- a/projects/ucap-webmessenger-protocol-authentication/src/public-api.ts +++ b/projects/ucap-webmessenger-protocol-authentication/src/public-api.ts @@ -4,6 +4,7 @@ export * from './lib/models/fmc'; export * from './lib/models/login'; +export * from './lib/models/logout'; export * from './lib/services/authentication-protocol.service'; diff --git a/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts b/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts index 8662dd13..616bd65a 100644 --- a/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts +++ b/projects/ucap-webmessenger-protocol/src/lib/services/protocol.service.ts @@ -21,8 +21,15 @@ import { import { PacketBodyValue } from '../types/packet-body-value.type'; import { SSVC_TYPE_ERROR_RES, ServerErrorCode } from '../types/service'; +export interface ServerMessage { + serviceType: number; + subServiceType: number; + senderSeq: number; + bodyList: any[]; +} + interface RequestState { - subject: Subject; + subject: Subject; request: { serviceType: number; subServiceType: number; @@ -30,13 +37,6 @@ interface RequestState { }; } -export interface ServerResponse { - serviceType: number; - subServiceType: number; - senderSeq: number; - bodyList: any[]; -} - @Injectable({ providedIn: 'root' }) @@ -48,10 +48,16 @@ export class ProtocolService { private socket$: Observable>; private messages$: Observable; private messagesSubscription: Subscription | null = null; + private serverMessageSubject: Subject | null = null; + private serverMessage$: Observable | null = null; constructor(@Inject(_MODULE_CONFIG) private moduleConfig: ModuleConfig) { this.pendingRequests = new Map(); this.input$ = new QueueingSubject(); + this.serverMessageSubject = new Subject(); + this.serverMessage$ = this.serverMessageSubject + .asObservable() + .pipe(share()); } public connect(serverIp: string | null = null): Promise { @@ -86,8 +92,8 @@ export class ProtocolService { this.pendingRequests.delete(res.requestId); } - if (SSVC_TYPE_ERROR_RES === res.response.subServiceType) { - const errorCode: ServerErrorCode = res.response + if (SSVC_TYPE_ERROR_RES === res.message.subServiceType) { + const errorCode: ServerErrorCode = res.message .bodyList[0] as ServerErrorCode; if (requestState) { @@ -97,8 +103,11 @@ export class ProtocolService { } if (requestState) { - requestState.subject.next(res.response); + requestState.subject.next(res.message); + return; } + + this.serverMessageSubject.next(res.message); }, (error: Error) => { const { message } = error; @@ -122,11 +131,15 @@ export class ProtocolService { this.messagesSubscription.unsubscribe(); } + public get serverMessage(): Observable { + return this.serverMessage$; + } + public call( serviceType: number | null, subServiceType: number | null, ...bodyList: PacketBody[] - ): Observable { + ): Observable { return this.sendInternal(true, serviceType, subServiceType, bodyList); } @@ -143,9 +156,9 @@ export class ProtocolService { serviceType: number, subServiceType: number, bodyList: PacketBody[] - ): Observable | undefined { + ): Observable | undefined { let packet: string; - let responseSubject: Subject | null = null; + let responseSubject: Subject | null = null; if (hasResponse) { const requestId = this.requestId; @@ -155,7 +168,7 @@ export class ProtocolService { { type: PacketBodyValue.RequestId, value: requestId } ]); - responseSubject = new Subject(); + responseSubject = new Subject(); this.pendingRequests.set(requestId, { subject: responseSubject, request: { serviceType, subServiceType, bodyList } @@ -182,7 +195,7 @@ export class ProtocolService { private decodePacket( arg: string[] - ): { requestId: number; response: ServerResponse } | null { + ): { requestId: number; message: ServerMessage } | null { const cmdArg = arg[0].split(PacketBodyValueDivider); if (2 > cmdArg.length) { // OnError(3); @@ -247,7 +260,7 @@ export class ProtocolService { return { requestId, - response: { + message: { serviceType, subServiceType, senderSeq,