postLogin is implemented

This commit is contained in:
병준 박 2019-10-04 10:19:55 +09:00
parent 34db1b2d87
commit c1df332f1e
16 changed files with 260 additions and 281 deletions

View File

@ -15,6 +15,7 @@ import { UCapProtocolModule } from '@ucap-webmessenger/protocol';
import { UCapAuthenticationProtocolModule } from '@ucap-webmessenger/protocol-authentication';
import { UCapInnerProtocolModule } from '@ucap-webmessenger/protocol-inner';
import { UCapOptionProtocolModule } from '@ucap-webmessenger/protocol-option';
import { UCapServiceProtocolModule } from '@ucap-webmessenger/protocol-service';
import { UCapSyncProtocolModule } from '@ucap-webmessenger/protocol-sync';
import { UCapUiModule } from '@ucap-webmessenger/ui';
@ -67,6 +68,7 @@ import { GUARDS } from './guards';
UCapAuthenticationProtocolModule.forRoot(),
UCapInnerProtocolModule.forRoot(),
UCapOptionProtocolModule.forRoot(),
UCapServiceProtocolModule.forRoot(),
UCapSyncProtocolModule.forRoot(),
UCapUiModule.forRoot(),

View File

@ -4,15 +4,12 @@ import {
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { Observable, throwError, of, EMPTY, forkJoin } from 'rxjs';
import { Observable, throwError, forkJoin } from 'rxjs';
import {
map,
tap,
mergeMap,
catchError,
take,
exhaustMap,
concatMap,
switchMap,
withLatestFrom
} from 'rxjs/operators';
@ -21,10 +18,7 @@ import { Store, select } from '@ngrx/store';
import { ProtocolService } from '@ucap-webmessenger/protocol';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
PublicApiService,
VersionInfo2Response
} from '@ucap-webmessenger/api-public';
import { PublicApiService } from '@ucap-webmessenger/api-public';
import {
LoginInfo,
@ -40,8 +34,6 @@ import {
} from '@ucap-webmessenger/protocol-authentication';
import * as AuthenticationStore from '@app/store/account/authentication';
import { ConnResponse } from 'projects/ucap-webmessenger-protocol-inner/src/lib/models/conn';
import { PiService } from '@ucap-webmessenger/pi';
import { NGXLogger } from 'ngx-logger';
import { QueryProtocolService } from '@ucap-webmessenger/protocol-query';
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';
@ -58,7 +50,6 @@ export class AppMessengerResolver implements Resolve<void> {
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private publicApiService: PublicApiService,
private piService: PiService,
private protocolService: ProtocolService,
private queryProtocolService: QueryProtocolService,
private optionProtocolService: OptionProtocolService,
@ -72,8 +63,6 @@ export class AppMessengerResolver implements Resolve<void> {
routerStateSnapshot: RouterStateSnapshot
): void | Observable<void> | Promise<void> {
return new Promise<void>((resolve, reject) => {
let versionInfo2Res: VersionInfo2Response;
let connRres: ConnResponse;
let loginRes: LoginResponse;
const loginInfo = this.sessionStorageService.get<LoginInfo>(
@ -92,13 +81,14 @@ export class AppMessengerResolver implements Resolve<void> {
})
.pipe(
take(1),
tap(res => {
this.store.dispatch(VersionInfoStore.versionInfo2Success({ res }));
}),
switchMap(res => {
versionInfo2Res = res;
return this.protocolService.connect(versionInfo2Res.serverIp);
return this.protocolService.connect(res.serverIp);
}),
switchMap(() => this.innerProtocolService.conn({})),
switchMap(res => {
connRres = res;
return this.authenticationProtocolService.login({
loginId: loginInfo.loginId,
loginPw: loginInfo.loginPw,
@ -119,19 +109,22 @@ export class AppMessengerResolver implements Resolve<void> {
productName: 'EZMessenger'
});
}),
switchMap(res =>
forkJoin([
switchMap(res => {
loginRes = res;
return forkJoin([
this.queryProtocolService.auth({
deviceType: environmentsInfo.deviceType
}),
this.optionProtocolService.regView({})
])
),
]);
}),
map(([authRes, regViewRes]) => {
this.store.dispatch(
OptionStore.regViewSuccess({ res: regViewRes })
);
this.store.dispatch(QueryStore.authSuccess({ res: authRes }));
this.store.dispatch(AuthenticationStore.postLogin({ loginRes }));
}),
withLatestFrom(
this.store.pipe(
@ -162,7 +155,7 @@ export class AppMessengerResolver implements Resolve<void> {
() => {
this.store.dispatch(
AuthenticationStore.loginSuccess({
loginInfo: loginRes
loginRes
})
);
resolve();

View File

@ -3,7 +3,11 @@ import { createAction, props } from '@ngrx/store';
import { Login2Response } from '@ucap-webmessenger/pi';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { LoginInfo } from '../../../types';
import { LoginInfo } from '@app/types';
import {
UserPasswordSetRequest,
UserPasswordSetResponse
} from '@ucap-webmessenger/protocol-service';
export const webLogin = createAction(
'[Account::Authentication] Web Login',
@ -30,7 +34,7 @@ export const webLoginFailure = createAction(
export const loginSuccess = createAction(
'[Account::Authentication] Login Success',
props<{
loginInfo: LoginResponse;
loginRes: LoginResponse;
}>()
);
@ -52,3 +56,47 @@ export const logoutConfirmation = createAction(
export const logoutConfirmationDismiss = createAction(
'[Account::Authentication] Logout Confirmation Dismiss'
);
export const postLogin = createAction(
'[Account::Authentication] Post Login',
props<{
loginRes: LoginResponse;
}>()
);
export const privacyAgree = createAction(
'[Account::Authentication] Privacy Agree',
props<{
loginRes: LoginResponse;
}>()
);
export const privacyAgreeSuccess = createAction(
'[Account::Authentication] Privacy Agree Success'
);
export const privacyAgreeFailure = createAction(
'[Account::Authentication] Privacy Agree Failure',
props<{ error: any }>()
);
export const privacyDisagree = createAction(
'[Account::Authentication] Privacy Disagree'
);
export const changePassword = createAction(
'[Account::Authentication] Change Password',
props<{ req: UserPasswordSetRequest }>()
);
export const changePasswordSuccess = createAction(
'[Account::Authentication] Change Password Success',
props<{
res: UserPasswordSetResponse;
}>()
);
export const changePasswordFailure = createAction(
'[Account::Authentication] Change Password Failure',
props<{ error: any }>()
);

View File

@ -6,7 +6,11 @@ import { catchError, exhaustMap, map, tap, switchMap } from 'rxjs/operators';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { PiService, Login2Response } from '@ucap-webmessenger/pi';
import {
PiService,
Login2Response,
UserTermsActionResponse
} from '@ucap-webmessenger/pi';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import {
DialogService,
@ -22,11 +26,30 @@ import {
logoutConfirmationDismiss,
webLogin,
webLoginSuccess,
webLoginFailure
webLoginFailure,
postLogin,
privacyAgree,
privacyDisagree,
privacyAgreeFailure,
privacyAgreeSuccess,
changePassword,
changePasswordFailure,
changePasswordSuccess
} from './actions';
import { LoginInfo } from '../../../types';
import { AppAuthenticationService } from '../../../services/authentication.service';
import {
LoginInfo,
KEY_LOGIN_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '@app/types';
import { AppAuthenticationService } from '@app/services/authentication.service';
import { NGXLogger } from 'ngx-logger';
import { Store } from '@ngrx/store';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
ServiceProtocolService,
UserPasswordSetResponse
} from '@ucap-webmessenger/protocol-service';
@Injectable()
export class Effects {
@ -125,11 +148,139 @@ export class Effects {
)
);
postLogin$ = createEffect(
() =>
this.actions$.pipe(
ofType(postLogin),
map(action => action.loginRes),
tap(async loginRes => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
if (!loginRes.privateInformationAgree) {
const privacyTotalUrl = this.piService.privacyTotalUrl({
companyCode: loginInfo.companyCode,
userSeq: loginRes.userSeq,
token: loginRes.tokenString,
deviceType: environmentsInfo.deviceType,
localeCode: loginInfo.localeCode,
textOnly: 'true'
});
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
width: '100%',
height: '500px',
disableClose: true,
data: {
title: '개인정보 동의'
// html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
}
});
if (result.choice) {
this.store.dispatch(privacyAgree({ loginRes }));
} else {
this.store.dispatch(privacyDisagree());
return;
}
}
if (!!loginRes.passwordExpired) {
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
width: '100%',
height: '500px',
disableClose: true,
data: {
title: '패스워드 만료',
message: ''
}
});
if (result.choice) {
} else {
return;
}
}
})
),
{ dispatch: false }
);
privacyAgree$ = createEffect(() =>
this.actions$.pipe(
ofType(privacyAgree),
map(action => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
return {
loginInfo,
environmentsInfo,
loginResponse: action.loginRes
};
}),
exhaustMap(params =>
this.piService
.userTermsAction({
userSeq: params.loginResponse.userSeq,
token: params.loginResponse.tokenString,
deviceType: params.environmentsInfo.deviceType
})
.pipe(
map((res: UserTermsActionResponse) => {
if ('00' !== res.responseCode) {
return privacyAgreeFailure({ error: 'Failed' });
} else {
return privacyAgreeSuccess();
}
}),
catchError(error => of(privacyAgreeFailure({ error })))
)
)
)
);
changePassword$ = createEffect(() =>
this.actions$.pipe(
ofType(changePassword),
map(action => action.req),
exhaustMap(req =>
this.serviceProtocolService.userPasswordSet(req).pipe(
map((res: UserPasswordSetResponse) => {
return changePasswordSuccess({
res
});
}),
catchError(error => of(changePasswordFailure({ error })))
)
)
)
);
constructor(
private actions$: Actions,
private router: Router,
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private piService: PiService,
private appAuthenticationService: AppAuthenticationService,
private serviceProtocolService: ServiceProtocolService,
private dialogService: DialogService,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private logger: NGXLogger

View File

@ -7,7 +7,7 @@ export const reducer = createReducer(
on(loginSuccess, (state, action) => {
return {
...state,
loginInfo: action.loginInfo
loginRes: action.loginRes
};
})
);

View File

@ -3,18 +3,18 @@ import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
// tslint:disable-next-line: no-empty-interface
export interface State {
loginInfo: LoginResponse | null;
loginRes: LoginResponse | null;
}
export const initialState: State = {
loginInfo: null
loginRes: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {
loginInfo: createSelector(
loginRes: createSelector(
selector,
(state: State) => state.loginInfo
(state: State) => state.loginRes
)
};
}

View File

@ -2,22 +2,16 @@ import { Type } from '@angular/core';
import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
import * as AuthenticationStore from './authentication';
import * as PrivacyStore from './privacy';
export interface State {
authentication: AuthenticationStore.State;
privacy: PrivacyStore.State;
}
export const effects: Type<any>[] = [
AuthenticationStore.Effects,
PrivacyStore.Effects
];
export const effects: Type<any>[] = [AuthenticationStore.Effects];
export function reducers(state: State | undefined, action: Action) {
return combineReducers({
authentication: AuthenticationStore.reducer,
privacy: PrivacyStore.reducer
authentication: AuthenticationStore.reducer
})(state, action);
}
@ -28,12 +22,6 @@ export function selectors<S>(selector: Selector<any, State>) {
selector,
(state: State) => state.authentication
)
),
PrivacySelector: PrivacyStore.selectors(
createSelector(
selector,
(state: State) => state.privacy
)
)
};
}

View File

@ -1,25 +0,0 @@
import { createAction, props } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
export const agreeConfirmationNotNeeded = createAction(
'[Account::Privacy] Agree Confirmation not needed'
);
export const agreeConfirmationYes = createAction(
'[Account::Privacy] Agree Confirmation Yes',
props<{
loginInfo: LoginResponse;
}>()
);
export const agreeConfirmationNo = createAction(
'[Account::Privacy] Agree Confirmation No'
);
export const agreeSuccess = createAction('[Account::Privacy] Agree Success');
export const agreeFailure = createAction(
'[Account::Privacy] Agree Failure',
props<{ error: any }>()
);

View File

@ -1,157 +0,0 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, exhaustMap, map } from 'rxjs/operators';
import {
PiService,
UserTermsActionResponse,
ResponseStatus
} from '@ucap-webmessenger/pi';
import {
DialogService,
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
} from '@ucap-webmessenger/ui';
import { AppAuthenticationService } from '@app/services/authentication.service';
import { loginSuccess, logout } from '../authentication';
import {
agreeConfirmationYes,
agreeConfirmationNo,
agreeConfirmationNotNeeded,
agreeSuccess,
agreeFailure
} from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
LoginInfo,
KEY_LOGIN_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '@app/types';
import { initSettings } from '@app/store/setting/init';
@Injectable()
export class Effects {
// agreeConfirmation$ = createEffect(() =>
// this.actions$.pipe(
// ofType(loginSuccess),
// exhaustMap(async params => {
// if (params.loginInfo.privateInformationAgree) {
// return null;
// }
// const loginInfo = this.sessionStorageService.get<LoginInfo>(
// KEY_LOGIN_INFO
// );
// const environmentsInfo = this.sessionStorageService.get<
// EnvironmentsInfo
// >(KEY_ENVIRONMENTS_INFO);
// const privacyTotalUrl = this.piService.privacyTotalUrl({
// companyCode: params.loginInfo.companyCode,
// userSeq: params.loginInfo.userSeq,
// token: params.loginInfo.tokenString,
// deviceType: environmentsInfo.deviceType,
// localeCode: loginInfo.localeCode,
// textOnly: 'true'
// });
// const result = await this.dialogService.open<
// ConfirmDialogComponent,
// ConfirmDialogData,
// ConfirmDialogResult
// >(ConfirmDialogComponent, {
// width: '100%',
// height: '500px',
// disableClose: true,
// data: {
// title: '개인정보 동의',
// html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
// }
// });
// return {
// loginInfo: params.loginInfo,
// choice: result.choice
// };
// }),
// map(params => {
// if (!params) {
// return agreeConfirmationNotNeeded();
// }
// return params.choice
// ? agreeConfirmationYes({ loginInfo: params.loginInfo })
// : agreeConfirmationNo();
// })
// )
// );
agreeConfirmationYes$ = createEffect(() =>
this.actions$.pipe(
ofType(agreeConfirmationYes),
map(action => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
return {
loginInfo,
environmentsInfo,
loginResponse: action.loginInfo
};
}),
exhaustMap(params =>
this.piService
.userTermsAction({
userSeq: params.loginResponse.userSeq,
token: params.loginResponse.tokenString,
deviceType: params.environmentsInfo.deviceType
})
.pipe(
map((res: UserTermsActionResponse) => {
if ('00' !== res.responseCode) {
return agreeFailure({ error: 'Failed' });
} else {
return agreeSuccess();
}
}),
catchError(error => of(agreeFailure({ error })))
)
)
)
);
agreeSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(agreeSuccess),
map(() => initSettings())
)
);
agreeFailure$ = createEffect(() =>
this.actions$.pipe(
ofType(agreeFailure),
map(action => action),
map(() => logout())
)
);
constructor(
private actions$: Actions,
private router: Router,
private piService: PiService,
private sessionStorageService: SessionStorageService,
private appAuthenticationService: AppAuthenticationService,
private dialogService: DialogService
) {}
}

View File

@ -1,4 +0,0 @@
export * from './actions';
export * from './effects';
export * from './reducers';
export * from './state';

View File

@ -1,4 +0,0 @@
import { Action, combineReducers, createReducer, on } from '@ngrx/store';
import { State, initialState } from './state';
export const reducer = createReducer(initialState);

View File

@ -1,11 +0,0 @@
import { Selector, createSelector } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
// tslint:disable-next-line: no-empty-interface
export interface State {}
export const initialState: State = {};
export function selectors<S>(selector: Selector<any, State>) {
return {};
}

View File

@ -5,17 +5,17 @@ import {
VersionInfo2Response
} from '@ucap-webmessenger/api-public';
export const fetch = createAction(
'[Setting::VersionInfo] Fetch',
export const versionInfo2 = createAction(
'[Setting::VersionInfo] VersionInfo2',
props<VersionInfo2Request>()
);
export const fetchSuccess = createAction(
'[Setting::VersionInfo] Fetch Success',
props<VersionInfo2Response>()
export const versionInfo2Success = createAction(
'[Setting::VersionInfo] VersionInfo2 Success',
props<{ res: VersionInfo2Response }>()
);
export const fetchFailure = createAction(
'[Setting::VersionInfo] Fetch Failure',
export const versionInfo2Failure = createAction(
'[Setting::VersionInfo] VersionInfo2 Failure',
props<{ error: any }>()
);

View File

@ -12,39 +12,33 @@ import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { NGXLogger } from 'ngx-logger';
import { fetch, fetchSuccess, fetchFailure } from './actions';
import {
versionInfo2,
versionInfo2Success,
versionInfo2Failure
} from './actions';
@Injectable()
export class Effects {
fetch$ = createEffect(() =>
versionInfo2$ = createEffect(() =>
this.actions$.pipe(
ofType(fetch),
ofType(versionInfo2),
map(action => action),
exhaustMap(req =>
this.publicApiService.versionInfo2(req).pipe(
map(res => {
if (res.statusCode === StatusCode.Success) {
this.logger.debug('fetchSuccess', res);
return fetchSuccess(res);
return versionInfo2Success({ res });
} else {
return fetchFailure({ error: 'Failed' });
return versionInfo2Failure({ error: 'Failed' });
}
}),
catchError(error => of(fetchFailure({ error })))
catchError(error => of(versionInfo2Failure({ error })))
)
)
)
);
fetchSuccess$ = createEffect(
() =>
this.actions$.pipe(
ofType(fetchSuccess),
tap(params => {})
),
{ dispatch: false }
);
constructor(
private actions$: Actions,
private publicApiService: PublicApiService,

View File

@ -1,23 +1,23 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { fetchSuccess } from './actions';
import { versionInfo2Success } from './actions';
export const reducer = createReducer(
initialState,
on(fetchSuccess, (state, action) => {
on(versionInfo2Success, (state, action) => {
return {
...state,
profileImageRoot: action.profileRoot,
profileImageUploadUrl: action.profileUploadUrl,
profileImageRoot: action.res.profileRoot,
profileImageUploadUrl: action.res.profileUploadUrl,
fileUploadMaxSize:
!!action.fileAllowSize &&
!isNaN(action.fileAllowSize) &&
0 < action.fileAllowSize
? action.fileAllowSize
!!action.res.fileAllowSize &&
!isNaN(action.res.fileAllowSize) &&
0 < action.res.fileAllowSize
? action.res.fileAllowSize
: 0,
fileUploadUrl: action.uploadUrl,
fileDownloadUrl: action.downloadUrl,
serverIp: action.serverIp
fileUploadUrl: action.res.uploadUrl,
fileDownloadUrl: action.res.downloadUrl,
serverIp: action.res.serverIp
};
})
);

View File

@ -2,6 +2,10 @@
* Public API Surface of ucap-webmessenger-protocol-service
*/
export * from './lib/models/password-set';
export * from './lib/services/service-protocol.service';
export * from './lib/types/service';
export * from './lib/ucap-service-protocol.module';