change password is modified
This commit is contained in:
parent
68e861a39b
commit
31153b52bf
|
@ -5,6 +5,9 @@
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<div fxFlex class="setting-tab">
|
<div fxFlex class="setting-tab">
|
||||||
<ucap-account-change-password
|
<ucap-account-change-password
|
||||||
|
[loginId]="data.loginId"
|
||||||
|
[phoneNumber]="data.phoneNumber"
|
||||||
|
[encryptedLoginPw]="data.encryptedLoginPw"
|
||||||
(changePassword)="onChangePassword($event)"
|
(changePassword)="onChangePassword($event)"
|
||||||
></ucap-account-change-password>
|
></ucap-account-change-password>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,24 +1,18 @@
|
||||||
import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
|
import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||||
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
|
||||||
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
|
||||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
|
|
||||||
import { DialogService } from '@ucap-webmessenger/ui';
|
import { DialogService } from '@ucap-webmessenger/ui';
|
||||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
|
||||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
|
||||||
import { AppAuthenticationService } from '@app/services/authentication.service';
|
|
||||||
import { StringUtil, CharactorType } from '@ucap-webmessenger/core';
|
|
||||||
|
|
||||||
import * as ServiceStore from '@app/store/messenger/service';
|
export interface ChangePasswordDialogData {
|
||||||
import CryptoJS from 'crypto-js';
|
loginId: string;
|
||||||
|
phoneNumber?: string;
|
||||||
export interface ChangePasswordDialogData {}
|
encryptedLoginPw?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ChangePasswordDialogResult {
|
export interface ChangePasswordDialogResult {
|
||||||
choice: boolean;
|
choice: boolean;
|
||||||
|
currentLoginPw?: string;
|
||||||
|
newLoginPw?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -27,170 +21,25 @@ export interface ChangePasswordDialogResult {
|
||||||
styleUrls: ['./change-password.dialog.component.scss']
|
styleUrls: ['./change-password.dialog.component.scss']
|
||||||
})
|
})
|
||||||
export class ChangePasswordDialogComponent implements OnInit, OnDestroy {
|
export class ChangePasswordDialogComponent implements OnInit, OnDestroy {
|
||||||
loginRes: LoginResponse;
|
|
||||||
sessionVerinfo: VersionInfo2Response;
|
|
||||||
isMe: boolean;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public dialogRef: MatDialogRef<
|
public dialogRef: MatDialogRef<
|
||||||
ChangePasswordDialogData,
|
ChangePasswordDialogData,
|
||||||
ChangePasswordDialogResult
|
ChangePasswordDialogResult
|
||||||
>,
|
>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: ChangePasswordDialogData,
|
@Inject(MAT_DIALOG_DATA) public data: ChangePasswordDialogData,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService
|
||||||
private sessionStorageService: SessionStorageService,
|
) {}
|
||||||
private appAuthenticationService: AppAuthenticationService,
|
|
||||||
private store: Store<any>
|
|
||||||
) {
|
|
||||||
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
|
|
||||||
KEY_VER_INFO
|
|
||||||
);
|
|
||||||
this.loginRes = this.sessionStorageService.get<LoginResponse>(
|
|
||||||
KEY_LOGIN_RES_INFO
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
ngOnDestroy(): void {}
|
ngOnDestroy(): void {}
|
||||||
|
|
||||||
onChangePassword(info: {
|
onChangePassword(info: { currentLoginPw: string; newLoginPw: string }): void {
|
||||||
currentLoginPw: string;
|
this.dialogRef.close({
|
||||||
newLoginPw: string;
|
choice: true,
|
||||||
newConfirmLoginPw: string;
|
currentLoginPw: info.currentLoginPw,
|
||||||
notValid: () => void;
|
newLoginPw: info.newLoginPw
|
||||||
}): void {
|
});
|
||||||
if (!info.currentLoginPw || '' === info.currentLoginPw.trim()) {
|
|
||||||
// 현재 비밀번호를 입력해주세요
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.appAuthenticationService.isSameForPassword(info.currentLoginPw)) {
|
|
||||||
// "현재 비밀번호가 다릅니다"
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!info.newLoginPw || '' === info.newLoginPw.trim()) {
|
|
||||||
// 신규 비밀번호를 입력해주세요
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (-1 < info.newLoginPw.indexOf(this.loginRes.userId)) {
|
|
||||||
// "사용자 ID를 비밀번호에 포함할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const phoneNumberOnly = !!this.loginRes.userInfo.hpNumber
|
|
||||||
? this.loginRes.userInfo.hpNumber.trim().replace(new RegExp('-', 'g'), '')
|
|
||||||
: '';
|
|
||||||
|
|
||||||
switch (phoneNumberOnly.length) {
|
|
||||||
case 11:
|
|
||||||
if (-1 < info.newLoginPw.indexOf(phoneNumberOnly.substr(3, 4))) {
|
|
||||||
// "사용자 휴대폰번호를 비밀번호에 포함할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (-1 < info.newLoginPw.indexOf(phoneNumberOnly.substr(7, 4))) {
|
|
||||||
// "사용자 휴대폰번호를 비밀번호에 포함할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
if (-1 < info.newLoginPw.indexOf(phoneNumberOnly.substr(3, 3))) {
|
|
||||||
// "사용자 휴대폰번호를 비밀번호에 포함할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (-1 < info.newLoginPw.indexOf(phoneNumberOnly.substr(6, 4))) {
|
|
||||||
// "사용자 휴대폰번호를 비밀번호에 포함할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!info.newConfirmLoginPw || '' === info.newConfirmLoginPw.trim()) {
|
|
||||||
// "신규 비밀번호 확인을 입력해주세요"
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (info.newLoginPw !== info.newConfirmLoginPw.trim()) {
|
|
||||||
// "신규 비밀번호와 신규 비밀번호 확인이 다릅니다"
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (info.currentLoginPw === info.newLoginPw.trim()) {
|
|
||||||
// "현재 비밀번호와 새로운 비밀번호가 같습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (0 < StringUtil.includes(info.newLoginPw, CharactorType.Space)) {
|
|
||||||
// "비밀번호에는 공백을 입력할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (StringUtil.isRepeat(info.newLoginPw, 3)) {
|
|
||||||
// "숫자나 문자를 3번이상 반복적으로 사용할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
StringUtil.isIncrements(info.newLoginPw, 3) ||
|
|
||||||
StringUtil.isDecrements(info.newLoginPw, 3)
|
|
||||||
) {
|
|
||||||
// "연속되는 숫자나 문자를 3번이상 사용할 수 없습니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let combinationCount = 0;
|
|
||||||
if (0 < StringUtil.includes(info.newLoginPw, CharactorType.Special)) {
|
|
||||||
combinationCount++;
|
|
||||||
}
|
|
||||||
if (0 < StringUtil.includes(info.newLoginPw, CharactorType.Number)) {
|
|
||||||
combinationCount++;
|
|
||||||
}
|
|
||||||
if (0 < StringUtil.includes(info.newLoginPw, CharactorType.Charactor)) {
|
|
||||||
combinationCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
let minPwLen = 0;
|
|
||||||
if (2 < combinationCount) {
|
|
||||||
minPwLen = 8;
|
|
||||||
} else if (2 === combinationCount) {
|
|
||||||
minPwLen = 10;
|
|
||||||
} else if (2 > combinationCount) {
|
|
||||||
// "2종류 이상 조합을 해야 합니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.newLoginPw.length < minPwLen) {
|
|
||||||
// "비밀번호는 %d가지가 조합된 경우 %d자를 넘어야 합니다."
|
|
||||||
info.notValid();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.store.dispatch(
|
|
||||||
ServiceStore.userPasswordSet({
|
|
||||||
req: {
|
|
||||||
loginId: this.loginRes.userId,
|
|
||||||
companyCode: this.loginRes.companyCode,
|
|
||||||
oldLoginPw: CryptoJS.enc.Hex.stringify(
|
|
||||||
CryptoJS.SHA256(info.currentLoginPw)
|
|
||||||
),
|
|
||||||
newLoginPw: CryptoJS.enc.Hex.stringify(
|
|
||||||
CryptoJS.SHA256(info.newLoginPw)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
this.dialogRef.close({ choice: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickChoice(choice: boolean): void {
|
onClickChoice(choice: boolean): void {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import CryptoJS from 'crypto-js';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SessionStorageService,
|
SessionStorageService,
|
||||||
LocalStorageService
|
LocalStorageService
|
||||||
|
@ -10,6 +8,7 @@ import { LocaleCode } from '@ucap-webmessenger/core';
|
||||||
import { LoginInfo, KEY_LOGIN_INFO } from '../types';
|
import { LoginInfo, KEY_LOGIN_INFO } from '../types';
|
||||||
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
||||||
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
|
||||||
|
import { PasswordUtil } from '@ucap-webmessenger/pi';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
@ -33,7 +32,7 @@ export class AppAuthenticationService {
|
||||||
this.sessionStorageService.set<LoginInfo>(KEY_LOGIN_INFO, {
|
this.sessionStorageService.set<LoginInfo>(KEY_LOGIN_INFO, {
|
||||||
...loginInfo,
|
...loginInfo,
|
||||||
initPw: loginInfo.loginId === loginInfo.loginPw,
|
initPw: loginInfo.loginId === loginInfo.loginPw,
|
||||||
loginPw: CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(loginInfo.loginPw))
|
loginPw: PasswordUtil.encrypt(loginInfo.loginPw)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (rememberMe) {
|
if (rememberMe) {
|
||||||
|
@ -51,11 +50,4 @@ export class AppAuthenticationService {
|
||||||
this.sessionStorageService.remove(KEY_VER_INFO);
|
this.sessionStorageService.remove(KEY_VER_INFO);
|
||||||
this.sessionStorageService.remove(KEY_LOGIN_INFO);
|
this.sessionStorageService.remove(KEY_LOGIN_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
isSameForPassword(pw: string): boolean {
|
|
||||||
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
|
|
||||||
return (
|
|
||||||
loginInfo.loginPw === CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(pw))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,3 +96,20 @@ export const privacyAgreeFailure = createAction(
|
||||||
export const privacyDisagree = createAction(
|
export const privacyDisagree = createAction(
|
||||||
'[Account::Authentication] Privacy Disagree'
|
'[Account::Authentication] Privacy Disagree'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const userPasswordSet = createAction(
|
||||||
|
'[Account::Authentication] User Password Set',
|
||||||
|
props<{ req: UserPasswordSetRequest }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const userPasswordSetSuccess = createAction(
|
||||||
|
'[Account::Authentication] User Password Set Success',
|
||||||
|
props<{
|
||||||
|
res: UserPasswordSetResponse;
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const userPasswordSetFailure = createAction(
|
||||||
|
'[Account::Authentication] User Password Set Failure',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
|
|
@ -34,7 +34,10 @@ import {
|
||||||
privacyAgreeSuccess,
|
privacyAgreeSuccess,
|
||||||
increaseLoginFailCount,
|
increaseLoginFailCount,
|
||||||
initialLoginFailCount,
|
initialLoginFailCount,
|
||||||
logoutInitialize
|
logoutInitialize,
|
||||||
|
userPasswordSet,
|
||||||
|
userPasswordSetSuccess,
|
||||||
|
userPasswordSetFailure
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import {
|
import {
|
||||||
LoginInfo,
|
LoginInfo,
|
||||||
|
@ -60,6 +63,10 @@ import {
|
||||||
ChangePasswordDialogData,
|
ChangePasswordDialogData,
|
||||||
ChangePasswordDialogResult
|
ChangePasswordDialogResult
|
||||||
} from '@app/layouts/messenger/dialogs/account/change-password.dialog.component';
|
} from '@app/layouts/messenger/dialogs/account/change-password.dialog.component';
|
||||||
|
import {
|
||||||
|
ServiceProtocolService,
|
||||||
|
UserPasswordSetResponse
|
||||||
|
} from '@ucap-webmessenger/protocol-service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Effects {
|
export class Effects {
|
||||||
|
@ -273,10 +280,24 @@ export class Effects {
|
||||||
width: '500px',
|
width: '500px',
|
||||||
height: '500px',
|
height: '500px',
|
||||||
disableClose: false,
|
disableClose: false,
|
||||||
data: {}
|
data: {
|
||||||
|
loginId: loginInfo.loginId,
|
||||||
|
encryptedLoginPw: loginInfo.loginPw,
|
||||||
|
phoneNumber: loginRes.userInfo.hpNumber
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!!result && result.choice) {
|
if (!!result && result.choice) {
|
||||||
|
this.store.dispatch(
|
||||||
|
userPasswordSet({
|
||||||
|
req: {
|
||||||
|
companyCode: loginInfo.companyCode,
|
||||||
|
loginId: loginInfo.loginId,
|
||||||
|
oldLoginPw: result.currentLoginPw,
|
||||||
|
newLoginPw: result.newLoginPw
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -324,6 +345,23 @@ export class Effects {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
userPasswordSet$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(userPasswordSet),
|
||||||
|
map(action => action.req),
|
||||||
|
exhaustMap(req =>
|
||||||
|
this.serviceProtocolService.userPasswordSet(req).pipe(
|
||||||
|
map((res: UserPasswordSetResponse) => {
|
||||||
|
return userPasswordSetSuccess({
|
||||||
|
res
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError(error => of(userPasswordSetFailure({ error })))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private actions$: Actions,
|
private actions$: Actions,
|
||||||
private ngZone: NgZone,
|
private ngZone: NgZone,
|
||||||
|
@ -334,7 +372,7 @@ export class Effects {
|
||||||
private appAuthenticationService: AppAuthenticationService,
|
private appAuthenticationService: AppAuthenticationService,
|
||||||
private protocolService: ProtocolService,
|
private protocolService: ProtocolService,
|
||||||
private authenticationProtocolService: AuthenticationProtocolService,
|
private authenticationProtocolService: AuthenticationProtocolService,
|
||||||
|
private serviceProtocolService: ServiceProtocolService,
|
||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
||||||
private logger: NGXLogger
|
private logger: NGXLogger
|
||||||
|
|
|
@ -6,7 +6,6 @@ import * as EventStore from './event';
|
||||||
import * as OptionStore from './option';
|
import * as OptionStore from './option';
|
||||||
import * as QueryStore from './query';
|
import * as QueryStore from './query';
|
||||||
import * as RoomStore from './room';
|
import * as RoomStore from './room';
|
||||||
import * as ServiceStore from './service';
|
|
||||||
import * as StatusStore from './status';
|
import * as StatusStore from './status';
|
||||||
import * as SyncStore from './sync';
|
import * as SyncStore from './sync';
|
||||||
import * as SettingsStore from './settings';
|
import * as SettingsStore from './settings';
|
||||||
|
@ -17,7 +16,6 @@ export interface State {
|
||||||
option: OptionStore.State;
|
option: OptionStore.State;
|
||||||
query: QueryStore.State;
|
query: QueryStore.State;
|
||||||
room: RoomStore.State;
|
room: RoomStore.State;
|
||||||
service: ServiceStore.State;
|
|
||||||
status: StatusStore.State;
|
status: StatusStore.State;
|
||||||
sync: SyncStore.State;
|
sync: SyncStore.State;
|
||||||
settings: SettingsStore.State;
|
settings: SettingsStore.State;
|
||||||
|
@ -29,7 +27,6 @@ export const effects: Type<any>[] = [
|
||||||
OptionStore.Effects,
|
OptionStore.Effects,
|
||||||
QueryStore.Effects,
|
QueryStore.Effects,
|
||||||
RoomStore.Effects,
|
RoomStore.Effects,
|
||||||
ServiceStore.Effects,
|
|
||||||
StatusStore.Effects,
|
StatusStore.Effects,
|
||||||
SyncStore.Effects,
|
SyncStore.Effects,
|
||||||
SettingsStore.Effects
|
SettingsStore.Effects
|
||||||
|
@ -42,7 +39,6 @@ export function reducers(state: State | undefined, action: Action) {
|
||||||
option: OptionStore.reducer,
|
option: OptionStore.reducer,
|
||||||
query: QueryStore.reducer,
|
query: QueryStore.reducer,
|
||||||
room: RoomStore.reducer,
|
room: RoomStore.reducer,
|
||||||
service: ServiceStore.reducer,
|
|
||||||
status: StatusStore.reducer,
|
status: StatusStore.reducer,
|
||||||
sync: SyncStore.reducer,
|
sync: SyncStore.reducer,
|
||||||
settings: SettingsStore.reducer
|
settings: SettingsStore.reducer
|
||||||
|
@ -66,9 +62,6 @@ export function selectors<S>(selector: Selector<any, State>) {
|
||||||
QuerySelector: QueryStore.selectors(
|
QuerySelector: QueryStore.selectors(
|
||||||
createSelector(selector, (state: State) => state.query)
|
createSelector(selector, (state: State) => state.query)
|
||||||
),
|
),
|
||||||
ServiceSelector: ServiceStore.selectors(
|
|
||||||
createSelector(selector, (state: State) => state.service)
|
|
||||||
),
|
|
||||||
StatusSelector: StatusStore.selectors(
|
StatusSelector: StatusStore.selectors(
|
||||||
createSelector(selector, (state: State) => state.status)
|
createSelector(selector, (state: State) => state.status)
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { createAction, props } from '@ngrx/store';
|
|
||||||
|
|
||||||
import {
|
|
||||||
UserPasswordSetRequest,
|
|
||||||
UserPasswordSetResponse
|
|
||||||
} from '@ucap-webmessenger/protocol-service';
|
|
||||||
|
|
||||||
export const userPasswordSet = createAction(
|
|
||||||
'[Account::Authentication] User Password Set',
|
|
||||||
props<{ req: UserPasswordSetRequest }>()
|
|
||||||
);
|
|
||||||
|
|
||||||
export const userPasswordSetSuccess = createAction(
|
|
||||||
'[Account::Authentication] User Password Set Success',
|
|
||||||
props<{
|
|
||||||
res: UserPasswordSetResponse;
|
|
||||||
}>()
|
|
||||||
);
|
|
||||||
|
|
||||||
export const userPasswordSetFailure = createAction(
|
|
||||||
'[Account::Authentication] User Password Set Failure',
|
|
||||||
props<{ error: any }>()
|
|
||||||
);
|
|
|
@ -1,47 +0,0 @@
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
import { Actions, ofType, createEffect } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
|
|
||||||
import { NGXLogger } from 'ngx-logger';
|
|
||||||
import { catchError, exhaustMap, map } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { of } from 'rxjs';
|
|
||||||
|
|
||||||
import {
|
|
||||||
userPasswordSet,
|
|
||||||
userPasswordSetSuccess,
|
|
||||||
userPasswordSetFailure
|
|
||||||
} from './actions';
|
|
||||||
import {
|
|
||||||
ServiceProtocolService,
|
|
||||||
UserPasswordSetResponse
|
|
||||||
} from '@ucap-webmessenger/protocol-service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class Effects {
|
|
||||||
userPasswordSet$ = createEffect(() =>
|
|
||||||
this.actions$.pipe(
|
|
||||||
ofType(userPasswordSet),
|
|
||||||
map(action => action.req),
|
|
||||||
exhaustMap(req =>
|
|
||||||
this.serviceProtocolService.userPasswordSet(req).pipe(
|
|
||||||
map((res: UserPasswordSetResponse) => {
|
|
||||||
return userPasswordSetSuccess({
|
|
||||||
res
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
catchError(error => of(userPasswordSetFailure({ error })))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private actions$: Actions,
|
|
||||||
private serviceProtocolService: ServiceProtocolService,
|
|
||||||
private store: Store<any>,
|
|
||||||
private logger: NGXLogger
|
|
||||||
) {}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
export * from './actions';
|
|
||||||
export * from './effects';
|
|
||||||
export * from './reducers';
|
|
||||||
export * from './state';
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { createReducer, on } from '@ngrx/store';
|
|
||||||
import { initialState } from './state';
|
|
||||||
|
|
||||||
export const reducer = createReducer(initialState);
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { Selector, createSelector } from '@ngrx/store';
|
|
||||||
|
|
||||||
export interface State {}
|
|
||||||
|
|
||||||
export const initialState: State = {};
|
|
||||||
|
|
||||||
export function selectors<S>(selector: Selector<any, State>) {
|
|
||||||
return {};
|
|
||||||
}
|
|
137
projects/ucap-webmessenger-pi/src/lib/utils/password.util.ts
Normal file
137
projects/ucap-webmessenger-pi/src/lib/utils/password.util.ts
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
import CryptoJS from 'crypto-js';
|
||||||
|
import { StringUtil, CharactorType } from '@ucap-webmessenger/core';
|
||||||
|
|
||||||
|
export interface PasswordValidationOption {
|
||||||
|
userId?: string;
|
||||||
|
phoneNumber?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum PasswordValidationResult {
|
||||||
|
Valid = 'Valid',
|
||||||
|
Empty = 'Empty',
|
||||||
|
IncludeUserId = 'IncludeUserId',
|
||||||
|
IncludePhoneNumber = 'IncludePhoneNumber',
|
||||||
|
IncludeSpace = 'IncludeSpace',
|
||||||
|
IncludeRepeated = 'IncludeRepeated',
|
||||||
|
IncludeIncrements = 'IncludeIncrements',
|
||||||
|
IncludeDecrements = 'IncludeDecrements',
|
||||||
|
LackOfCombination = 'LackOfCombination',
|
||||||
|
TooShortCombinationLength = 'TooShortCombinationLength'
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PasswordUtil {
|
||||||
|
static encrypt(password: string): string {
|
||||||
|
return CryptoJS.enc.Hex.stringify(CryptoJS.SHA256(password));
|
||||||
|
}
|
||||||
|
|
||||||
|
static validate(
|
||||||
|
password: string,
|
||||||
|
option?: PasswordValidationOption
|
||||||
|
): { code: PasswordValidationResult; extra?: any } {
|
||||||
|
if (!password || '' === password.trim()) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.Empty
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!option && !!option.userId) {
|
||||||
|
if (-1 < password.indexOf(option.userId)) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludeUserId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!option && !!option.phoneNumber) {
|
||||||
|
const phoneNumberOnly = option.phoneNumber
|
||||||
|
.trim()
|
||||||
|
.replace(new RegExp('-', 'g'), '');
|
||||||
|
|
||||||
|
switch (phoneNumberOnly.length) {
|
||||||
|
case 11:
|
||||||
|
if (-1 < password.indexOf(phoneNumberOnly.substr(3, 4))) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludePhoneNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (-1 < password.indexOf(phoneNumberOnly.substr(7, 4))) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludePhoneNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
if (-1 < password.indexOf(phoneNumberOnly.substr(3, 3))) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludePhoneNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (-1 < password.indexOf(phoneNumberOnly.substr(6, 4))) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludePhoneNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 < StringUtil.includes(password, CharactorType.Space)) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludeSpace
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (StringUtil.isRepeat(password, 3)) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludeRepeated
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (StringUtil.isIncrements(password, 3)) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludeIncrements
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (StringUtil.isDecrements(password, 3)) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.IncludeDecrements
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let combinationCount = 0;
|
||||||
|
if (0 < StringUtil.includes(password, CharactorType.Special)) {
|
||||||
|
combinationCount++;
|
||||||
|
}
|
||||||
|
if (0 < StringUtil.includes(password, CharactorType.Number)) {
|
||||||
|
combinationCount++;
|
||||||
|
}
|
||||||
|
if (0 < StringUtil.includes(password, CharactorType.Charactor)) {
|
||||||
|
combinationCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
let minPwLen = 0;
|
||||||
|
if (2 < combinationCount) {
|
||||||
|
minPwLen = 8;
|
||||||
|
} else if (2 === combinationCount) {
|
||||||
|
minPwLen = 10;
|
||||||
|
} else if (2 > combinationCount) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.LackOfCombination
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.length < minPwLen) {
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.TooShortCombinationLength,
|
||||||
|
extra: {
|
||||||
|
combinationCount,
|
||||||
|
minPwLen
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: PasswordValidationResult.Valid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,8 @@ export * from './lib/types/response-status.type';
|
||||||
|
|
||||||
export * from './lib/services/pi.service';
|
export * from './lib/services/pi.service';
|
||||||
|
|
||||||
|
export * from './lib/utils/password.util';
|
||||||
|
|
||||||
export * from './lib/ucap-pi.module';
|
export * from './lib/ucap-pi.module';
|
||||||
|
|
||||||
export * from './lib/config/urls';
|
export * from './lib/config/urls';
|
||||||
|
|
|
@ -5,43 +5,137 @@
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
type="password"
|
type="password"
|
||||||
formControlName="currentLoginPw"
|
[formControl]="currentLoginPwFormControl"
|
||||||
#currentLoginPw
|
|
||||||
/>
|
/>
|
||||||
<mat-error>
|
|
||||||
현재 패스워드를 입력해 주세요
|
|
||||||
</mat-error>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>신규 패스워드</mat-label>
|
<mat-label>신규 패스워드</mat-label>
|
||||||
<input
|
<input matInput type="password" [formControl]="newLoginPwFormControl" />
|
||||||
matInput
|
|
||||||
type="password"
|
|
||||||
formControlName="newLoginPw"
|
|
||||||
#newLoginPw
|
|
||||||
/>
|
|
||||||
<mat-error>
|
|
||||||
신규 패스워드를 입력해 주세요
|
|
||||||
</mat-error>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>신규 패스워드 확인</mat-label>
|
<mat-label>신규 패스워드 확인</mat-label>
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
type="password"
|
type="password"
|
||||||
formControlName="newConfirmLoginPw"
|
[formControl]="newConfirmLoginPwFormControl"
|
||||||
#newConfirmLoginPw
|
|
||||||
/>
|
/>
|
||||||
<mat-error>
|
|
||||||
신규 패스워드 확인을 입력해 주세요
|
|
||||||
</mat-error>
|
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
currentLoginPwFormControl.dirty &&
|
||||||
|
currentLoginPwFormControl.hasError('required')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
현재 비밀번호를 입력해 주세요
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
currentLoginPwFormControl.dirty &&
|
||||||
|
currentLoginPwFormControl.hasError('ucapPasswordSame')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
현재 비밀번호와 일치하지 않습니다
|
||||||
|
</mat-error>
|
||||||
|
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
newLoginPwFormControl.dirty &&
|
||||||
|
newLoginPwFormControl.hasError('required')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
신규 비밀번호를 입력해 주세요
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
newLoginPwFormControl.dirty &&
|
||||||
|
newLoginPwFormControl.hasError('ucapNotSameWith')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
현재 비밀번호와 동일합니다
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
newLoginPwFormControl.dirty &&
|
||||||
|
newLoginPwFormControl.hasError('ucapPassword')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<ng-container
|
||||||
|
[ngSwitch]="
|
||||||
|
newLoginPwFormControl.getError('ucapPassword').result.code
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<ng-container *ngSwitchCase="PasswordValidationResult.IncludeSpace">
|
||||||
|
비밀번호에는 공백을 입력할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="PasswordValidationResult.IncludeUserId">
|
||||||
|
사용자 ID를 비밀번호에 포함할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container
|
||||||
|
*ngSwitchCase="PasswordValidationResult.IncludePhoneNumber"
|
||||||
|
>
|
||||||
|
사용자 휴대폰번호를 비밀번호에 포함할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container
|
||||||
|
*ngSwitchCase="PasswordValidationResult.IncludeRepeated"
|
||||||
|
>
|
||||||
|
숫자나 문자를 3번이상 반복적으로 사용할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container
|
||||||
|
*ngSwitchCase="PasswordValidationResult.IncludeIncrements"
|
||||||
|
>
|
||||||
|
연속되는 숫자나 문자를 3번이상 사용할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container
|
||||||
|
*ngSwitchCase="PasswordValidationResult.IncludeDecrements"
|
||||||
|
>
|
||||||
|
연속되는 숫자나 문자를 3번이상 사용할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container
|
||||||
|
*ngSwitchCase="PasswordValidationResult.LackOfCombination"
|
||||||
|
>
|
||||||
|
2종류 이상 조합을 해야 합니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container
|
||||||
|
*ngSwitchCase="PasswordValidationResult.TooShortCombinationLength"
|
||||||
|
>
|
||||||
|
비밀번호에는 공백을 입력할 수 없습니다
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngSwitchCase="PasswordValidationResult.IncludeSpace">
|
||||||
|
비밀번호는{{
|
||||||
|
newLoginPwFormControl.getError('ucapPassword').result.extra
|
||||||
|
.combinationCount
|
||||||
|
}}가지가 조합된 경우{{
|
||||||
|
newLoginPwFormControl.getError('ucapPassword').result.extra
|
||||||
|
.minPwLen
|
||||||
|
}}자를 넘어야 합니다
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
newConfirmLoginPwFormControl.dirty &&
|
||||||
|
newConfirmLoginPwFormControl.hasError('required')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
신규 비밀번호 확인을 입력해 주세요
|
||||||
|
</mat-error>
|
||||||
|
<mat-error
|
||||||
|
*ngIf="
|
||||||
|
newConfirmLoginPwFormControl.dirty &&
|
||||||
|
newConfirmLoginPwFormControl.hasError('ucapSameWith')
|
||||||
|
"
|
||||||
|
>
|
||||||
|
신규 비밀번호와 신규 비밀번호 확인이 다릅니다
|
||||||
|
</mat-error>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
class="submit-button bg-accent-dark"
|
class="submit-button bg-accent-dark"
|
||||||
aria-label="패스워드 변경"
|
aria-label="패스워드 변경"
|
||||||
[disabled]="changePasswordForm.invalid || !changePasswordBtnEnable"
|
[disabled]="changePasswordForm.invalid"
|
||||||
(click)="onClickChangePassword()"
|
(click)="onClickChangePassword()"
|
||||||
>
|
>
|
||||||
패스워드 변경
|
패스워드 변경
|
||||||
|
|
|
@ -8,10 +8,66 @@ import {
|
||||||
ElementRef,
|
ElementRef,
|
||||||
ChangeDetectorRef
|
ChangeDetectorRef
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
import {
|
||||||
import { Company } from '@ucap-webmessenger/api-external';
|
FormControl,
|
||||||
import { LocalStorageService } from '@ucap-webmessenger/web-storage';
|
FormGroup,
|
||||||
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
Validators,
|
||||||
|
ValidatorFn,
|
||||||
|
AbstractControl,
|
||||||
|
ValidationErrors,
|
||||||
|
FormBuilder
|
||||||
|
} from '@angular/forms';
|
||||||
|
import {
|
||||||
|
PasswordUtil,
|
||||||
|
PasswordValidationOption,
|
||||||
|
PasswordValidationResult
|
||||||
|
} from '@ucap-webmessenger/pi';
|
||||||
|
|
||||||
|
export function ucapPassword(option: PasswordValidationOption): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
const result = PasswordUtil.validate(control.value, option);
|
||||||
|
return PasswordValidationResult.Valid !== result.code
|
||||||
|
? { ucapPassword: { result } }
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ucapPasswordSame(value: string): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
return !!value && value !== PasswordUtil.encrypt(control.value)
|
||||||
|
? { ucapPasswordSame: true }
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ucapNotSameWith(targetControl: AbstractControl): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
return !!targetControl &&
|
||||||
|
(targetControl.value as string) === (control.value as string)
|
||||||
|
? { ucapNotSameWith: true }
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ucapSameWith(targetControl: AbstractControl): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
return !!targetControl && targetControl.value !== control.value
|
||||||
|
? { ucapSameWith: true }
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ucapNotSame(value: string | number): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
return !!value && value === control.value ? { ucapNotSame: true } : null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ucapSame(value: string | number): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
return !!value && value !== control.value ? { ucapSame: true } : null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-account-change-password',
|
selector: 'ucap-account-change-password',
|
||||||
|
@ -20,48 +76,79 @@ import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
||||||
})
|
})
|
||||||
export class ChangePasswordComponent implements OnInit {
|
export class ChangePasswordComponent implements OnInit {
|
||||||
@Input()
|
@Input()
|
||||||
changePasswordBtnEnable: boolean;
|
loginId: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
phoneNumber: string;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
encryptedLoginPw: string;
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
changePassword = new EventEmitter<{
|
changePassword = new EventEmitter<{
|
||||||
currentLoginPw: string;
|
currentLoginPw: string;
|
||||||
newLoginPw: string;
|
newLoginPw: string;
|
||||||
newConfirmLoginPw: string;
|
|
||||||
notValid: () => void;
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
@ViewChild('currentLoginPw', { static: true })
|
|
||||||
currentLoginPwElementRef: ElementRef;
|
|
||||||
@ViewChild('newLoginPw', { static: true })
|
|
||||||
newLoginPwElementRef: ElementRef;
|
|
||||||
|
|
||||||
changePasswordForm: FormGroup;
|
changePasswordForm: FormGroup;
|
||||||
|
currentLoginPwFormControl = new FormControl('');
|
||||||
|
newLoginPwFormControl = new FormControl('');
|
||||||
|
newConfirmLoginPwFormControl = new FormControl('');
|
||||||
|
|
||||||
|
PasswordValidationResult = PasswordValidationResult;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private changeDetectorRef: ChangeDetectorRef,
|
private changeDetectorRef: ChangeDetectorRef
|
||||||
private localStorageService: LocalStorageService
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const loginInfo: LoginInfo = this.localStorageService.get<LoginInfo>(
|
const currentLoginPwValidators: ValidatorFn[] = [Validators.required];
|
||||||
KEY_LOGIN_INFO
|
if (!!this.encryptedLoginPw) {
|
||||||
|
currentLoginPwValidators.push(ucapPasswordSame(this.encryptedLoginPw));
|
||||||
|
}
|
||||||
|
this.currentLoginPwFormControl.setValidators(currentLoginPwValidators);
|
||||||
|
|
||||||
|
let validateOption: PasswordValidationOption = {};
|
||||||
|
if (!!this.loginId) {
|
||||||
|
validateOption = {
|
||||||
|
...validateOption,
|
||||||
|
userId: this.loginId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!!this.phoneNumber) {
|
||||||
|
validateOption = {
|
||||||
|
...validateOption,
|
||||||
|
phoneNumber: this.phoneNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const newLoginPwValidators: ValidatorFn[] = [
|
||||||
|
Validators.required,
|
||||||
|
ucapNotSameWith(this.currentLoginPwFormControl),
|
||||||
|
ucapPassword(validateOption)
|
||||||
|
];
|
||||||
|
this.newLoginPwFormControl.setValidators(newLoginPwValidators);
|
||||||
|
|
||||||
|
const newConfirmLoginPwValidators: ValidatorFn[] = [
|
||||||
|
Validators.required,
|
||||||
|
ucapSameWith(this.newLoginPwFormControl)
|
||||||
|
];
|
||||||
|
this.newConfirmLoginPwFormControl.setValidators(
|
||||||
|
newConfirmLoginPwValidators
|
||||||
);
|
);
|
||||||
|
|
||||||
this.changePasswordForm = this.formBuilder.group({
|
this.changePasswordForm = this.formBuilder.group({
|
||||||
currentLoginPw: ['', Validators.required],
|
currentLoginPwFormControl: this.currentLoginPwFormControl,
|
||||||
newLoginPw: ['', Validators.required],
|
newLoginPwFormControl: this.newLoginPwFormControl,
|
||||||
newConfirmLoginPw: ['', Validators.required]
|
newConfirmLoginPwFormControl: this.newConfirmLoginPwFormControl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickChangePassword() {
|
onClickChangePassword() {
|
||||||
this.changePassword.emit({
|
this.changePassword.emit({
|
||||||
currentLoginPw: this.changePasswordForm.get('currentLoginPw').value,
|
currentLoginPw: this.currentLoginPwFormControl.value,
|
||||||
newLoginPw: this.changePasswordForm.get('newLoginPw').value,
|
newLoginPw: this.newLoginPwFormControl.value
|
||||||
newConfirmLoginPw: this.changePasswordForm.get('newConfirmLoginPw').value,
|
|
||||||
notValid: () => {
|
|
||||||
this.currentLoginPwElementRef.nativeElement.focus();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user