diff --git a/.vscode/settings.json b/.vscode/settings.json index 318cb70..600b409 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,5 +12,5 @@ }, "go.testFlags": ["-v"], "go.testTimeout": "100s", - "debug.node.autoAttach": "on" + "debug.node.autoAttach": "off" } diff --git a/package-lock.json b/package-lock.json index e22decd..248f9b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1766,9 +1766,9 @@ "integrity": "sha512-X9rUvoemcOBzjpytG77EeUPTQPZ4XX0ZYw41rmp9B7JNkUQ9xttrox5jXrRYPyDmfYlx6Wyt5f0zlGY+jGbmqw==" }, "@ucap/api-public": { - "version": "0.0.3", - "resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/@ucap/api-public/-/api-public-0.0.3.tgz", - "integrity": "sha512-FDg7WLiq5Y5aPxC66LXKQOnqily1zcaUdtl3ZMGU3HfENod/d6aFarqFZOw5y0C+OZQ1LB+jIKa+AP0V4zC0Ug==" + "version": "0.0.4", + "resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/@ucap/api-public/-/api-public-0.0.4.tgz", + "integrity": "sha512-RpCoRJWmHAFVZH809cYyNnHNwCZ3CuJA185d9kzAsIDUq6Y4FPAoGedUfUtZjwiMCfsP582f87sJzMUmVkn8IQ==" }, "@ucap/core": { "version": "0.0.5", @@ -2016,9 +2016,9 @@ "integrity": "sha512-Qnsk08yiL75crDh3DQ96eNi5sD2zoRUclXy033ug2FqAFmihMuU+B2XHalTl8YE4mRSwFdAacq/VIiePyLlqgA==" }, "@ucap/protocol-option": { - "version": "0.0.4", - "resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/@ucap/protocol-option/-/protocol-option-0.0.4.tgz", - "integrity": "sha512-dDf6xmV5bnVAcym/S4CTh+kgbgCXjSoZbgCQG3Ay9hbuu5IhJjwWC+qoLWDdao0h77souMOzWxBULAJadqKoFA==" + "version": "0.0.5", + "resolved": "http://10.81.13.221:8081/nexus/repository/npm-all/@ucap/protocol-option/-/protocol-option-0.0.5.tgz", + "integrity": "sha512-eqEFwPgOYPohx1/0f1+RmBvunP8ofR1BsCgms1BhXHKi9MkWoEOMDftMX23Sm4FdP1s1oaPgeqfwmFm4+clcfA==" }, "@ucap/protocol-ping": { "version": "0.0.2", diff --git a/package.json b/package.json index eb24795..b3fe9f8 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@ucap/api-external": "~0.0.5", "@ucap/api-message": "~0.0.3", "@ucap/api-prompt": "~0.0.3", - "@ucap/api-public": "~0.0.3", + "@ucap/api-public": "~0.0.4", "@ucap/core": "~0.0.5", "@ucap/logger": "~0.0.7", "@ucap/native": "~0.0.6", @@ -86,7 +86,7 @@ "@ucap/protocol-group": "~0.0.3", "@ucap/protocol-info": "~0.0.3", "@ucap/protocol-inner": "~0.0.2", - "@ucap/protocol-option": "~0.0.3", + "@ucap/protocol-option": "~0.0.5", "@ucap/protocol-ping": "~0.0.2", "@ucap/protocol-query": "~0.0.2", "@ucap/protocol-room": "~0.0.3", diff --git a/src/app/app-provider.module.ts b/src/app/app-provider.module.ts index cdf1975..3bb57fb 100644 --- a/src/app/app-provider.module.ts +++ b/src/app/app-provider.module.ts @@ -9,11 +9,14 @@ import { environment } from '@environments'; import { AppAuthenticationGuard } from './guards/app-authentication.guard'; +import { AppAuthenticationResolver } from './resolvers/app-authentication.resolver'; + import { AppAuthenticationService } from './services/app-authentication.service'; import { AppNativeService } from './services/app-native.service'; import { AppService } from './services/app.service'; const GUARDS = [AppAuthenticationGuard]; +const RESOLVERS = [AppAuthenticationResolver]; const SERVICES = [AppService, AppAuthenticationService, AppNativeService]; const axiosFactory = () => { @@ -48,8 +51,9 @@ const appInit = (appService: AppService) => { deps: [AppService], multi: true }, + ...SERVICES, ...GUARDS, - ...SERVICES + ...RESOLVERS ] }) export class AppProviderModule {} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 521d14c..dbfc571 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import { DefaultLayoutComponent } from '@app/layouts/components/default.layout.c import { NoNaviLayoutComponent } from '@app/layouts/components/no-navi.layout.component'; import { AppAuthenticationGuard } from '@app/guards/app-authentication.guard'; +import { AppAuthenticationResolver } from './resolvers/app-authentication.resolver'; const routes: Routes = [ { @@ -27,6 +28,9 @@ const routes: Routes = [ path: '', component: DefaultLayoutComponent, canActivate: [AppAuthenticationGuard], + resolve: { + authentication: AppAuthenticationResolver + }, children: [ { path: '', redirectTo: '/organization', pathMatch: 'full' }, { diff --git a/src/app/models/login-session.ts b/src/app/models/login-session.ts index 1cd0e54..44f7741 100644 --- a/src/app/models/login-session.ts +++ b/src/app/models/login-session.ts @@ -6,6 +6,7 @@ export interface LoginSession { initPw?: boolean; companyCode?: string; companyGroupType?: string; + companyGroupCode?: string; localeCode?: LocaleCode; encData?: string; deviceType?: DeviceType; diff --git a/src/app/resolvers/app-authentication.resolver.ts b/src/app/resolvers/app-authentication.resolver.ts new file mode 100644 index 0000000..f473093 --- /dev/null +++ b/src/app/resolvers/app-authentication.resolver.ts @@ -0,0 +1,287 @@ +import { Observable, forkJoin } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { Injectable, Inject } from '@angular/core'; +import { + Resolve, + ActivatedRouteSnapshot, + RouterStateSnapshot +} from '@angular/router'; + +import { Store, select } from '@ngrx/store'; + +import { StatusCode } from '@ucap/api'; +import { NativeService } from '@ucap/native'; +import { SSOMode } from '@ucap/protocol-authentication'; + +import { UCAP_NATIVE_SERVICE } from '@ucap/ng-native'; +import { SessionStorageService } from '@ucap/ng-web-storage'; +import { PublicApiService } from '@ucap/ng-api-public'; +import { ExternalApiService } from '@ucap/ng-api-external'; +import { ProtocolService } from '@ucap/ng-protocol'; +import { InnerProtocolService } from '@ucap/ng-protocol-inner'; +import { AuthenticationProtocolService } from '@ucap/ng-protocol-authentication'; +import { QueryProtocolService } from '@ucap/ng-protocol-query'; +import { OptionProtocolService } from '@ucap/ng-protocol-option'; + +import { CompanyActions } from '@ucap/ng-store-organization'; +import { LoginActions } from '@ucap/ng-store-authentication'; +import { + BuddyActions, + BuddySelector, + GroupActions, + GroupSelector +} from '@ucap/ng-store-group'; +import { RoomActions, RoomSelector } from '@ucap/ng-store-chat'; + +import { LoginSession } from '@app/models/login-session'; +import { AppKey } from '@app/types/app-key.type'; + +import { AppAuthenticationActions } from '@app/store/actions'; + +@Injectable() +export class AppAuthenticationResolver implements Resolve { + constructor( + private publicApiService: PublicApiService, + private externalApiService: ExternalApiService, + private protocolService: ProtocolService, + private innerProtocolService: InnerProtocolService, + private authenticationProtocolService: AuthenticationProtocolService, + private queryProtocolService: QueryProtocolService, + private optionProtocolService: OptionProtocolService, + private store: Store, + private sessionStorageService: SessionStorageService, + @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService + ) {} + + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): void | Observable | Promise { + return new Promise(async (resolve, reject) => { + try { + const loginSession = this.sessionStorageService.get( + AppKey.LoginSession + ); + const networkInfo = await this.nativeService.getNetworkInfo(); + const localIp = + !!networkInfo && 0 < networkInfo.length && !!networkInfo[0].ip + ? networkInfo[0].ip + : ''; + const localMac = + !!networkInfo && 0 < networkInfo.length && !!networkInfo[0].mac + ? networkInfo[0].mac + : ''; + + this.store.dispatch( + CompanyActions.companies({ + req: { companyGroupCode: loginSession.companyGroupCode } + }) + ); + + this.publicApiService + .versionInfo2({ + deviceType: loginSession.deviceType, + desktopType: loginSession.desktopType, + companyGroupType: loginSession.companyGroupType, + companyCode: loginSession.companyCode, + loginId: loginSession.loginId + }) + .pipe(take(1)) + .subscribe( + versionInfo2Res => { + if (StatusCode.Fail === versionInfo2Res.statusCode) { + this.store.dispatch( + AppAuthenticationActions.versionInfo2Failure({ + error: versionInfo2Res.errorMessage + }) + ); + + reject(versionInfo2Res.errorMessage); + return; + } + + this.store.dispatch( + AppAuthenticationActions.versionInfo2Success({ + res: versionInfo2Res + }) + ); + + this.protocolService + .connect(versionInfo2Res.serverIp) + .pipe(take(1)) + .subscribe( + () => { + this.externalApiService + .urlInfo({ + deviceType: loginSession.deviceType, + loginId: loginSession.loginId + }) + .pipe(take(1)) + .subscribe( + urlInfoRes => { + if (StatusCode.Fail === urlInfoRes.statusCode) { + this.store.dispatch( + AppAuthenticationActions.urlInfoFailure({ + error: versionInfo2Res.errorMessage + }) + ); + + reject(urlInfoRes.errorMessage); + return; + } + + this.store.dispatch( + AppAuthenticationActions.urlInfoSuccess({ + res: versionInfo2Res + }) + ); + + this.innerProtocolService + .conn({}) + .pipe(take(1)) + .subscribe( + connRes => { + this.authenticationProtocolService + .login({ + loginId: loginSession.loginId, + loginPw: loginSession.loginPw, + deviceType: loginSession.deviceType, + deviceId: ' ', + token: '', + localeCode: loginSession.localeCode, + pushId: ' ', + companyCode: loginSession.companyCode, + passwordEncodingType: 1, + clientVersion: '', + reconnect: false, + ip: localIp, + hostName: localMac, + ssoMode: SSOMode.AUTH, + userSpecificInformation: 'PRO_000482', + andId: '', + andPushRefreshYn: '' + }) + .pipe(take(1)) + .subscribe( + loginRes => { + this.store.dispatch( + LoginActions.loginSuccess({ loginRes }) + ); + + forkJoin([ + this.queryProtocolService + .auth({ + deviceType: loginSession.deviceType + }) + .pipe(take(1)), + this.optionProtocolService + .regView({}) + .pipe(take(1)) + ]) + .pipe(take(1)) + .subscribe( + ([authRes, regViewRes]) => { + forkJoin([ + this.store.pipe( + take(1), + select( + BuddySelector.buddySyncDate + ) + ), + this.store.pipe( + take(1), + select( + GroupSelector.groupSyncDate + ) + ), + this.store.pipe( + take(1), + select( + RoomSelector.roomsSyncDate + ) + ) + ]) + .pipe(take(1)) + .subscribe( + ([ + buddySyncDate, + groupSyncDate, + roomsSyncDate + ]) => { + this.store.dispatch( + BuddyActions.buddy2({ + req: { + syncDate: buddySyncDate + } + }) + ); + this.store.dispatch( + GroupActions.groups({ + req: { + syncDate: groupSyncDate + } + }) + ); + this.store.dispatch( + RoomActions.rooms({ + req: { + localeCode: + loginSession.localeCode, + syncDate: roomsSyncDate + } + }) + ); + } + ); + + resolve(); + }, + error => { + reject(error); + } + ); + }, + error => { + this.store.dispatch( + LoginActions.loginFailure({ error }) + ); + reject(error); + } + ); + }, + error => { + reject(error); + } + ); + }, + error => { + this.store.dispatch( + AppAuthenticationActions.urlInfoFailure({ + error + }) + ); + reject(error); + } + ); + }, + error => { + reject(error); + } + ); + }, + error => { + this.store.dispatch( + AppAuthenticationActions.versionInfo2Failure({ + error + }) + ); + reject(error); + } + ); + } catch (error) { + reject(error); + } + }); + } +} diff --git a/src/app/services/app.service.ts b/src/app/services/app.service.ts index 85195c2..16c0abd 100644 --- a/src/app/services/app.service.ts +++ b/src/app/services/app.service.ts @@ -13,8 +13,12 @@ import { TranslateService } from '@ucap/ng-ui-organization'; import { LoginSession } from '@app/models/login-session'; import { AppKey } from '@app/types/app-key.type'; +import { environment } from '@environments'; + @Injectable() export class AppService { + readonly companyGroupCode = environment.companyConfig.companyGroupCode; + constructor( private sessionStorageService: SessionStorageService, private i18nService: I18nService, @@ -57,7 +61,8 @@ export class AppService { this.sessionStorageService.set(AppKey.LoginSession, { deviceType, - desktopType + desktopType, + companyGroupCode: this.companyGroupCode }); this.dateService.setDefaultTimezone('Asia/Seoul'); diff --git a/src/app/store/actions.ts b/src/app/store/actions.ts new file mode 100644 index 0000000..aa717d5 --- /dev/null +++ b/src/app/store/actions.ts @@ -0,0 +1,4 @@ +import * as AppActions from './app/actions'; +import * as AppAuthenticationActions from './authentication/actions'; + +export { AppActions, AppAuthenticationActions }; diff --git a/src/app/store/authentication/actions.ts b/src/app/store/authentication/actions.ts index a1ff6e7..0aa6044 100644 --- a/src/app/store/authentication/actions.ts +++ b/src/app/store/authentication/actions.ts @@ -1 +1,34 @@ -import { createAction } from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; + +import { VersionInfo2Response, VersionInfo2Request } from '@ucap/api-public'; +import { UrlInfoRequest, UrlInfoResponse } from '@ucap/api-external'; + +export const versionInfo2 = createAction( + '[ucap::app::authentication] versionInfo2', + props<{ req: VersionInfo2Request }>() +); + +export const versionInfo2Success = createAction( + '[ucap::app::authentication] versionInfo2 Success', + props<{ res: VersionInfo2Response }>() +); + +export const versionInfo2Failure = createAction( + '[ucap::app::authentication] versionInfo2 Failure', + props<{ error: any }>() +); + +export const urlInfo = createAction( + '[ucap::app::authentication] urlInfo', + props<{ req: UrlInfoRequest }>() +); + +export const urlInfoSuccess = createAction( + '[ucap::app::authentication] urlInfo Success', + props<{ res: UrlInfoResponse }>() +); + +export const urlInfoFailure = createAction( + '[ucap::app::authentication] urlInfo Failure', + props<{ error: any }>() +); diff --git a/src/app/store/authentication/reducers.ts b/src/app/store/authentication/reducers.ts index 70e7e20..2f1bf19 100644 --- a/src/app/store/authentication/reducers.ts +++ b/src/app/store/authentication/reducers.ts @@ -1,4 +1,17 @@ import { createReducer, on } from '@ngrx/store'; -import { initialState } from './state'; -export const reducer = createReducer(initialState); +import { initialState } from './state'; +import { versionInfo2Success } from './actions'; + +export const reducer = createReducer( + initialState, + on(versionInfo2Success, (state, action) => { + return { + ...state, + versionInfo2Response: { + ...state.versionInfo2Response, + ...action.res + } + }; + }) +); diff --git a/src/app/store/authentication/state.ts b/src/app/store/authentication/state.ts index 1e05bd0..756126c 100644 --- a/src/app/store/authentication/state.ts +++ b/src/app/store/authentication/state.ts @@ -1,9 +1,27 @@ import { Selector, createSelector } from '@ngrx/store'; -export interface State {} +import { VersionInfo2Response } from '@ucap/api-public'; +import { UrlInfoResponse } from '@ucap/api-external'; -export const initialState: State = {}; +export interface State { + versionInfo2Response: VersionInfo2Response | null; + urlInfoResponse: UrlInfoResponse | null; +} + +export const initialState: State = { + versionInfo2Response: null, + urlInfoResponse: null +}; export function selectors(selector: Selector) { - return {}; + return { + versionInfo2Response: createSelector( + selector, + (state: State) => state.versionInfo2Response + ), + urlInfoResponse: createSelector( + selector, + (state: State) => state.urlInfoResponse + ) + }; }