mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-06 17:08:29 +08:00
ForgotPassword
This commit is contained in:
parent
d6856b1f54
commit
7ddde38019
@ -17,21 +17,26 @@
|
||||
package org.maxkey.web.contorller;
|
||||
|
||||
public class ImageCaptcha {
|
||||
String id;
|
||||
String state;
|
||||
String image;
|
||||
|
||||
public ImageCaptcha(String id, String image) {
|
||||
public ImageCaptcha(String state, String image) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.state = state;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ public class ImageCaptchaEndpoint {
|
||||
}else {
|
||||
state = authJwtService.genJwt();
|
||||
}
|
||||
kaptchaKey = authJwtService.resolveTicket(state);
|
||||
kaptchaKey = authJwtService.resolveJWTID(state);
|
||||
_logger.trace("kaptchaKey {} , Captcha Text is {}" ,kaptchaKey, kaptchaValue);
|
||||
|
||||
momentaryService.put("", kaptchaKey, kaptchaValue);
|
||||
|
||||
@ -30,7 +30,6 @@ import org.maxkey.constants.ConstsStatus;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.password.onetimepwd.OtpAuthnService;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
@ -70,8 +69,6 @@ public abstract class AbstractAuthenticationProvider {
|
||||
|
||||
protected OnlineTicketService onlineTicketServices;
|
||||
|
||||
protected MomentaryService momentaryService;
|
||||
|
||||
protected AuthJwtService authJwtService;
|
||||
|
||||
public static ArrayList<GrantedAuthority> grantedAdministratorsAuthoritys = new ArrayList<GrantedAuthority>();
|
||||
|
||||
@ -19,11 +19,14 @@ package org.maxkey.authn.jwt;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.authn.SigninPrincipal;
|
||||
import org.maxkey.configuration.AuthJwkConfig;
|
||||
import org.maxkey.crypto.jwt.HMAC512Service;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -44,6 +47,8 @@ public class AuthJwtService {
|
||||
AuthJwkConfig authJwkConfig;
|
||||
|
||||
CongressService congressService;
|
||||
|
||||
MomentaryService momentaryService;
|
||||
|
||||
public AuthJwtService(AuthJwkConfig authJwkConfig) throws JOSEException {
|
||||
this.authJwkConfig = authJwkConfig;
|
||||
@ -51,12 +56,16 @@ public class AuthJwtService {
|
||||
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
|
||||
}
|
||||
|
||||
public AuthJwtService(AuthJwkConfig authJwkConfig,CongressService congressService) throws JOSEException {
|
||||
public AuthJwtService(AuthJwkConfig authJwkConfig,CongressService congressService,MomentaryService momentaryService) throws JOSEException {
|
||||
this.authJwkConfig = authJwkConfig;
|
||||
|
||||
this.congressService = congressService;
|
||||
|
||||
this.momentaryService = momentaryService;
|
||||
|
||||
this.hmac512Service = new HMAC512Service(authJwkConfig.getSecret());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -156,7 +165,7 @@ public class AuthJwtService {
|
||||
return signedJWT.getJWTClaimsSet();
|
||||
}
|
||||
|
||||
public String resolveTicket(String authToken) throws ParseException {
|
||||
public String resolveJWTID(String authToken) throws ParseException {
|
||||
JWTClaimsSet claims = resolve(authToken);
|
||||
return claims.getJWTID();
|
||||
}
|
||||
@ -177,4 +186,21 @@ public class AuthJwtService {
|
||||
return authJwt;
|
||||
}
|
||||
|
||||
public boolean validateCaptcha(String state,String captcha) {
|
||||
try {
|
||||
String jwtId = resolveJWTID(state);
|
||||
if(StringUtils.isNotBlank(jwtId) &&StringUtils.isNotBlank(captcha)) {
|
||||
Object momentaryCaptcha = momentaryService.get("", jwtId);
|
||||
_logger.debug("captcha : {}, momentary Captcha : {}" ,captcha, momentaryCaptcha);
|
||||
if (!StringUtils.isBlank(captcha) && captcha.equals(momentaryCaptcha.toString())) {
|
||||
momentaryService.remove("", jwtId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
_logger.debug("Exception ",e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -26,7 +26,6 @@ import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstsLoginType;
|
||||
import org.maxkey.entity.Institutions;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
@ -59,13 +58,11 @@ public class MfaAuthenticationProvider extends AbstractAuthenticationProvider {
|
||||
AbstractAuthenticationRealm authenticationRealm,
|
||||
ApplicationConfig applicationConfig,
|
||||
OnlineTicketService onlineTicketServices,
|
||||
AuthJwtService authJwtService,
|
||||
MomentaryService momentaryService) {
|
||||
AuthJwtService authJwtService) {
|
||||
this.authenticationRealm = authenticationRealm;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.onlineTicketServices = onlineTicketServices;
|
||||
this.authJwtService = authJwtService;
|
||||
this.momentaryService = momentaryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
package org.maxkey.authn.provider;
|
||||
|
||||
import java.text.ParseException;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.maxkey.authn.AbstractAuthenticationProvider;
|
||||
import org.maxkey.authn.LoginCredential;
|
||||
import org.maxkey.authn.jwt.AuthJwtService;
|
||||
@ -28,7 +27,6 @@ import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.constants.ConstsLoginType;
|
||||
import org.maxkey.entity.Institutions;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
@ -60,13 +58,11 @@ public class NormalAuthenticationProvider extends AbstractAuthenticationProvider
|
||||
AbstractAuthenticationRealm authenticationRealm,
|
||||
ApplicationConfig applicationConfig,
|
||||
OnlineTicketService onlineTicketServices,
|
||||
AuthJwtService authJwtService,
|
||||
MomentaryService momentaryService) {
|
||||
AuthJwtService authJwtService) {
|
||||
this.authenticationRealm = authenticationRealm;
|
||||
this.applicationConfig = applicationConfig;
|
||||
this.onlineTicketServices = onlineTicketServices;
|
||||
this.authJwtService = authJwtService;
|
||||
this.momentaryService = momentaryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -138,19 +134,8 @@ public class NormalAuthenticationProvider extends AbstractAuthenticationProvider
|
||||
*/
|
||||
protected void captchaValid(String state ,String captcha) throws ParseException {
|
||||
// for basic
|
||||
String ticket = authJwtService.resolveTicket(state);
|
||||
if(ticket == null) {
|
||||
if(!authJwtService.validateCaptcha(state,captcha)) {
|
||||
throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha"));
|
||||
}
|
||||
Object momentaryCaptcha = momentaryService.get("", ticket);
|
||||
_logger.info("captcha : {} , momentary Captcha : {} " ,captcha, momentaryCaptcha);
|
||||
if (StringUtils.isBlank(captcha) || !captcha.equals(momentaryCaptcha.toString())) {
|
||||
_logger.debug("login captcha valid error.");
|
||||
throw new BadCredentialsException(WebContext.getI18nValue("login.error.captcha"));
|
||||
}
|
||||
momentaryService.remove("", ticket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ public class AuthorizationUtils {
|
||||
AuthJwtService authJwtService,
|
||||
OnlineTicketService onlineTicketService) throws ParseException {
|
||||
if(authJwtService.validateJwtToken(authorization)) {
|
||||
String ticket = authJwtService.resolveTicket(authorization);
|
||||
String ticket = authJwtService.resolveJWTID(authorization);
|
||||
OnlineTicket onlineTicket = onlineTicketService.get(ticket);
|
||||
if(onlineTicket != null) {
|
||||
setAuthentication(onlineTicket.getAuthentication());
|
||||
|
||||
@ -87,16 +87,14 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
|
||||
AbstractAuthenticationRealm authenticationRealm,
|
||||
ApplicationConfig applicationConfig,
|
||||
OnlineTicketService onlineTicketServices,
|
||||
AuthJwtService authJwtService,
|
||||
MomentaryService momentaryService
|
||||
AuthJwtService authJwtService
|
||||
) {
|
||||
_logger.debug("init authentication Provider .");
|
||||
return new NormalAuthenticationProvider(
|
||||
authenticationRealm,
|
||||
applicationConfig,
|
||||
onlineTicketServices,
|
||||
authJwtService,
|
||||
momentaryService
|
||||
authJwtService
|
||||
);
|
||||
}
|
||||
|
||||
@ -134,6 +132,7 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
|
||||
public AuthJwtService authJwtService(
|
||||
AuthJwkConfig authJwkConfig,
|
||||
RedisConnectionFactory redisConnFactory,
|
||||
MomentaryService momentaryService,
|
||||
@Value("${maxkey.server.persistence}") int persistence) throws JOSEException {
|
||||
CongressService congressService;
|
||||
if (persistence == ConstsPersistence.REDIS) {
|
||||
@ -142,7 +141,7 @@ public class AuthenticationAutoConfiguration implements InitializingBean {
|
||||
congressService = new InMemoryCongressService();
|
||||
}
|
||||
|
||||
AuthJwtService authJwtService = new AuthJwtService(authJwkConfig,congressService);
|
||||
AuthJwtService authJwtService = new AuthJwtService(authJwkConfig,congressService,momentaryService);
|
||||
|
||||
return authJwtService;
|
||||
}
|
||||
|
||||
@ -124,6 +124,32 @@ public class OtpAuthnService {
|
||||
}
|
||||
return otpAuthn;
|
||||
}
|
||||
|
||||
public AbstractOtpAuthn getMailOtpAuthn(String instId) {
|
||||
AbstractOtpAuthn otpAuthn = otpAuthnStore.getIfPresent(instId);
|
||||
if(otpAuthn == null) {
|
||||
EmailSenders emailSender =
|
||||
emailSendersService.findOne("where instid = ? ", new Object[]{instId}, new int[]{Types.VARCHAR});
|
||||
|
||||
String credentials = PasswordReciprocal.getInstance().decoder(emailSender.getCredentials());
|
||||
EmailConfig emailConfig =
|
||||
new EmailConfig(
|
||||
emailSender.getAccount(),
|
||||
credentials,
|
||||
emailSender.getSmtpHost(),
|
||||
emailSender.getPort(),
|
||||
ConstsBoolean.isTrue(emailSender.getSslSwitch()),
|
||||
emailSender.getSender());
|
||||
MailOtpAuthn mailOtpAuthn = new MailOtpAuthn(emailConfig);
|
||||
mailOtpAuthn.setInterval(60 * 5);//5 minute
|
||||
if(redisOptTokenStore != null) {
|
||||
mailOtpAuthn.setOptTokenStore(redisOptTokenStore);
|
||||
}
|
||||
otpAuthn = mailOtpAuthn;
|
||||
}
|
||||
otpAuthnStore.put(instId, otpAuthn);
|
||||
return otpAuthn;
|
||||
}
|
||||
|
||||
public void setRedisOptTokenStore(RedisOtpTokenStore redisOptTokenStore) {
|
||||
this.redisOptTokenStore = redisOptTokenStore;
|
||||
|
||||
@ -67,6 +67,11 @@ public class ChangePassword extends JpaBaseEntity{
|
||||
this.setInstId(userInfo.getInstId());
|
||||
}
|
||||
|
||||
public void clearPassword() {
|
||||
this.password ="";
|
||||
this.decipherable = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
|
||||
@ -152,6 +152,7 @@ public class PasswordPolicyRepository {
|
||||
|
||||
|
||||
public ArrayList<Rule> getPasswordPolicyRuleList() {
|
||||
getPasswordPolicy();
|
||||
return passwordPolicyRuleList;
|
||||
}
|
||||
|
||||
|
||||
@ -106,4 +106,4 @@ import { Observable } from 'rxjs';
|
||||
providers: [...LANG_PROVIDES, ...INTERCEPTOR_PROVIDES, ...I18NSERVICE_PROVIDES, ...APPINIT_PROVIDES],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule {}
|
||||
export class AppModule { }
|
||||
|
||||
@ -0,0 +1,120 @@
|
||||
<h3>{{ 'mxk.forgot.forgot' | i18n }}</h3>
|
||||
<form nz-form [formGroup]="formGroup" role="form">
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-steps nzType="navigation" [nzCurrent]="step" style="width: 100%">
|
||||
<nz-step nzTitle="{{ 'mxk.forgot.step1' | i18n }}" nzDescription=""> </nz-step>
|
||||
<nz-step nzTitle="{{ 'mxk.forgot.step2' | i18n }}" nzDescription=""></nz-step>
|
||||
</nz-steps>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%" *ngIf="step === 0">
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-radio-group
|
||||
[(ngModel)]="forgotType"
|
||||
[ngModelOptions]="{ standalone: true }"
|
||||
style="margin-bottom: 8px; width: 100%"
|
||||
nzSize="large"
|
||||
nzButtonStyle="solid"
|
||||
(ngModelChange)="ngModelChange()"
|
||||
>
|
||||
<label nz-radio-button [nzValue]="'mobile'" style="width: 50%">{{ 'mxk.forgot.type.mobile' | i18n }}</label>
|
||||
<label nz-radio-button [nzValue]="'email'" style="width: 50%">{{ 'mxk.forgot.type.email' | i18n }}</label>
|
||||
</nz-radio-group>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%" *ngIf="forgotType === 'email'">
|
||||
<nz-form-control nzErrorTip="">
|
||||
<nz-input-group nzSize="large" nzPrefixIcon="mail">
|
||||
<input nz-input formControlName="email" placeholder="{{ 'mxk.forgot.email' | i18n }}" />
|
||||
</nz-input-group>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%" *ngIf="forgotType === 'mobile'">
|
||||
<nz-form-control [nzErrorTip]="">
|
||||
<nz-input-group nzSize="large" nzPrefixIcon="mobile">
|
||||
<input nz-input formControlName="mobile" placeholder="{{ 'mxk.forgot.mobile' | i18n }}" />
|
||||
</nz-input-group>
|
||||
<ng-template #mobileErrorTip let-i>
|
||||
<ng-container *ngIf="i.errors.required">
|
||||
{{ 'validation.phone-number.required' | i18n }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="i.errors.pattern">
|
||||
{{ 'validation.phone-number.wrong-format' | i18n }}
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-form-control nzErrorTip="">
|
||||
<nz-input-group nzSearch nzSize="large" nzPrefixIcon="lock" nzSearch [nzAddOnAfter]="suffixImageCaptchaButton">
|
||||
<input type="text" formControlName="captcha" nz-input placeholder="{{ 'mxk.forgot.captcha' | i18n }}" />
|
||||
</nz-input-group>
|
||||
<ng-template #suffixImageCaptchaButton>
|
||||
<img src="{{ imageCaptcha }}" (click)="getImageCaptcha()" />
|
||||
</ng-template>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-form-control [nzErrorTip]="'' | i18n">
|
||||
<nz-input-group nzSize="large" nzPrefixIcon="mail" nzSearch [nzAddOnAfter]="suffixSendOtpCodeButton">
|
||||
<input nz-input formControlName="otpCaptcha" placeholder="{{ 'mxk.login.text.captcha' | i18n }}" />
|
||||
</nz-input-group>
|
||||
<ng-template #suffixSendOtpCodeButton>
|
||||
<button type="button" nz-button nzSize="large" (click)="sendOtpCode()" [disabled]="count > 0" nzBlock [nzLoading]="loading">
|
||||
{{ count ? count + 's' : ('mxk.forgot.sendCaptcha' | i18n) }}
|
||||
</button>
|
||||
</ng-template>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%">
|
||||
<button nz-button nzType="primary" nzSize="large" class="submit" (click)="onNextReset($event)">
|
||||
{{ 'mxk.forgot.next' | i18n }}
|
||||
</button>
|
||||
<a class="login" routerLink="/passport/login">{{ 'mxk.forgot.login' | i18n }}</a>
|
||||
</nz-form-item>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%" *ngIf="step === 1">
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-form-label nzRequired nzFor="password">{{ 'mxk.password.password' | i18n }}</nz-form-label>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-form-control nzErrorTip="The input is not valid password!">
|
||||
<nz-input-group nzSize="large" [nzSuffix]="suffixPasswordTemplate" style="width: 100%">
|
||||
<input
|
||||
[type]="passwordVisible ? 'text' : 'password'"
|
||||
nz-input
|
||||
placeholder="new password"
|
||||
[(ngModel)]="form.model.password"
|
||||
formControlName="password"
|
||||
id="password"
|
||||
/>
|
||||
</nz-input-group>
|
||||
<ng-template #suffixPasswordTemplate>
|
||||
<i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i>
|
||||
</ng-template>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-form-label nzRequired nzFor="confirmPassword">{{ 'mxk.password.confirmPassword' | i18n }}</nz-form-label>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%">
|
||||
<nz-form-control nzErrorTip="The input is not valid confirmPassword!">
|
||||
<input
|
||||
nz-input
|
||||
type="password"
|
||||
nzSize="large"
|
||||
placeholder="confirm password"
|
||||
[(ngModel)]="form.model.confirmPassword"
|
||||
formControlName="confirmPassword"
|
||||
name="confirmPassword"
|
||||
id="confirmPassword"
|
||||
/>
|
||||
</nz-form-control>
|
||||
</nz-form-item>
|
||||
<nz-form-item style="width: 100%">
|
||||
<button nz-button nzType="primary" nzSize="large" class="submit" (click)="onSubmit($event)">
|
||||
{{ 'mxk.forgot.submit' | i18n }}
|
||||
</button>
|
||||
<a class="login" routerLink="/passport/login">{{ 'mxk.forgot.login' | i18n }}</a>
|
||||
</nz-form-item>
|
||||
</nz-form-item>
|
||||
</form>
|
||||
@ -0,0 +1,21 @@
|
||||
@import '@delon/theme/index';
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
width: 460px;
|
||||
margin: 0 auto;
|
||||
|
||||
|
||||
::ng-deep {
|
||||
.ant-tabs .ant-tabs-bar {
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.login {
|
||||
float: right;
|
||||
line-height: @btn-height-lg;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ForgotComponent } from './forgot.component';
|
||||
|
||||
describe('ForgotComponent', () => {
|
||||
let component: ForgotComponent;
|
||||
let fixture: ComponentFixture<ForgotComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ForgotComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ForgotComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,176 @@
|
||||
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
|
||||
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { NzMessageService } from 'ng-zorro-antd/message';
|
||||
import { NzStepsModule } from 'ng-zorro-antd/steps';
|
||||
|
||||
import { ChangePassword } from '../../../entity/ChangePassword';
|
||||
import { ForgotPasswordService } from '../../../service/forgot-password.service';
|
||||
import { ImageCaptchaService } from '../../../service/image-captcha.service';
|
||||
import { PasswordService } from '../../../service/password.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-forgot',
|
||||
templateUrl: './forgot.component.html',
|
||||
styleUrls: ['./forgot.component.less']
|
||||
})
|
||||
export class ForgotComponent implements OnInit {
|
||||
form: {
|
||||
submitting: boolean;
|
||||
model: ChangePassword;
|
||||
} = {
|
||||
submitting: false,
|
||||
model: new ChangePassword()
|
||||
};
|
||||
|
||||
imageCaptcha = '';
|
||||
formGroup: FormGroup;
|
||||
state = '';
|
||||
step = 0;
|
||||
forgotType = 'mobile';
|
||||
passwordVisible = false;
|
||||
loading = false;
|
||||
count = 0;
|
||||
interval$: any;
|
||||
userId = '';
|
||||
username = '';
|
||||
|
||||
constructor(
|
||||
fb: FormBuilder,
|
||||
private forgotPasswordService: ForgotPasswordService,
|
||||
private imageCaptchaService: ImageCaptchaService,
|
||||
private msg: NzMessageService,
|
||||
private cdr: ChangeDetectorRef
|
||||
) {
|
||||
this.formGroup = fb.group({
|
||||
mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]],
|
||||
email: [null, [Validators.required]],
|
||||
password: [null, [Validators.required]],
|
||||
captcha: [null, [Validators.required]],
|
||||
otpCaptcha: [null, [Validators.required]],
|
||||
confirmPassword: [null, [Validators.required]]
|
||||
});
|
||||
}
|
||||
|
||||
get email(): AbstractControl {
|
||||
return this.formGroup.get('email')!;
|
||||
}
|
||||
get password(): AbstractControl {
|
||||
return this.formGroup.get('password')!;
|
||||
}
|
||||
get confirmPassword(): AbstractControl {
|
||||
return this.formGroup.get('confirmPassword')!;
|
||||
}
|
||||
get mobile(): AbstractControl {
|
||||
return this.formGroup.get('mobile')!;
|
||||
}
|
||||
get captcha(): AbstractControl {
|
||||
return this.formGroup.get('captcha')!;
|
||||
}
|
||||
|
||||
get otpCaptcha(): AbstractControl {
|
||||
return this.formGroup.get('otpCaptcha')!;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getImageCaptcha();
|
||||
}
|
||||
|
||||
getImageCaptcha(): void {
|
||||
this.imageCaptchaService.captcha({}).subscribe(res => {
|
||||
this.imageCaptcha = res.data.image;
|
||||
this.state = res.data.state;
|
||||
this.cdr.detectChanges();
|
||||
});
|
||||
}
|
||||
|
||||
//send sms
|
||||
sendOtpCode(): void {
|
||||
if (this.forgotType == 'mobile' && this.mobile.invalid) {
|
||||
this.mobile.markAsDirty({ onlySelf: true });
|
||||
this.mobile.updateValueAndValidity({ onlySelf: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.forgotType == 'email' && this.email.invalid) {
|
||||
this.email.markAsDirty({ onlySelf: true });
|
||||
this.email.updateValueAndValidity({ onlySelf: true });
|
||||
return;
|
||||
}
|
||||
if (this.forgotType == 'mobile') {
|
||||
this.forgotPasswordService
|
||||
.produceOtp({ mobile: this.mobile.value, state: this.state, captcha: this.captcha.value })
|
||||
.subscribe(res => {
|
||||
if (res.code !== 0) {
|
||||
this.msg.success(`发送失败`);
|
||||
this.getImageCaptcha();
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
this.userId = res.data.userId;
|
||||
this.username = res.data.username;
|
||||
//console.log(res.data);
|
||||
});
|
||||
} else if (this.forgotType == 'email') {
|
||||
this.forgotPasswordService
|
||||
.produceEmailOtp({ email: this.email.value, state: this.state, captcha: this.captcha.value })
|
||||
.subscribe(res => {
|
||||
if (res.code !== 0) {
|
||||
this.msg.success(`发送失败`);
|
||||
this.getImageCaptcha();
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
this.userId = res.data.userId;
|
||||
this.username = res.data.username;
|
||||
//console.log(res.data);
|
||||
});
|
||||
}
|
||||
this.count = 59;
|
||||
this.interval$ = setInterval(() => {
|
||||
this.count -= 1;
|
||||
if (this.count <= 0) {
|
||||
clearInterval(this.interval$);
|
||||
}
|
||||
this.cdr.detectChanges();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
onNextReset(e: MouseEvent) {
|
||||
if (this.otpCaptcha.invalid) {
|
||||
this.otpCaptcha.markAsDirty({ onlySelf: true });
|
||||
this.otpCaptcha.updateValueAndValidity({ onlySelf: true });
|
||||
return;
|
||||
}
|
||||
this.step = 1;
|
||||
}
|
||||
|
||||
onSubmit(e: MouseEvent) {
|
||||
this.forgotPasswordService
|
||||
.setPassWord({
|
||||
forgotType: this.forgotType,
|
||||
userId: this.userId,
|
||||
username: this.username,
|
||||
password: this.password.value,
|
||||
confirmPassword: this.confirmPassword.value,
|
||||
otpCaptcha: this.otpCaptcha.value,
|
||||
state: this.state
|
||||
})
|
||||
.subscribe(res => {
|
||||
if (res.code !== 0) {
|
||||
this.msg.success(`密码修改失败`);
|
||||
this.getImageCaptcha();
|
||||
this.step = 0;
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
this.msg.success(`密码修改成功`);
|
||||
});
|
||||
}
|
||||
|
||||
ngModelChange() {
|
||||
if (this.forgotType == 'email') {
|
||||
this.mobile.reset();
|
||||
}
|
||||
if (this.forgotType == 'mobile') {
|
||||
this.email.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,7 @@
|
||||
<label nz-checkbox formControlName="remember">{{ 'mxk.login.remember-me' | i18n }}</label>
|
||||
</nz-col>
|
||||
<nz-col [nzSpan]="12" class="text-right">
|
||||
<a class="forgot" routerLink="/passport/register">{{ 'mxk.login.forgot-password' | i18n }}</a></nz-col
|
||||
<a class="forgot" routerLink="/passport/forgot">{{ 'mxk.login.forgot-password' | i18n }}</a></nz-col
|
||||
>
|
||||
</nz-form-item>
|
||||
<nz-form-item *ngIf="loginType == 'normal' || loginType == 'mobile'">
|
||||
|
||||
@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { LayoutPassportComponent } from '../../layout/passport/passport.component';
|
||||
import { CallbackComponent } from './callback.component';
|
||||
import { ForgotComponent } from './forgot/forgot.component';
|
||||
import { UserLockComponent } from './lock/lock.component';
|
||||
import { UserLoginComponent } from './login/login.component';
|
||||
import { UserRegisterResultComponent } from './register-result/register-result.component';
|
||||
@ -29,6 +30,11 @@ const routes: Routes = [
|
||||
component: UserRegisterResultComponent,
|
||||
data: { title: '注册结果', titleI18n: 'app.register.register' }
|
||||
},
|
||||
{
|
||||
path: 'forgot',
|
||||
component: ForgotComponent,
|
||||
data: { title: '忘记密码', titleI18n: 'app.forgot.forgot' }
|
||||
},
|
||||
{
|
||||
path: 'lock',
|
||||
component: UserLockComponent,
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '@shared';
|
||||
import { NzStepsModule } from 'ng-zorro-antd/steps';
|
||||
|
||||
import { CallbackComponent } from './callback.component';
|
||||
import { ForgotComponent } from './forgot/forgot.component';
|
||||
import { UserLockComponent } from './lock/lock.component';
|
||||
import { UserLoginComponent } from './login/login.component';
|
||||
import { PassportRoutingModule } from './passport-routing.module';
|
||||
@ -11,7 +13,7 @@ import { UserRegisterComponent } from './register/register.component';
|
||||
const COMPONENTS = [UserLoginComponent, UserRegisterResultComponent, UserRegisterComponent, UserLockComponent, CallbackComponent];
|
||||
|
||||
@NgModule({
|
||||
imports: [SharedModule, PassportRoutingModule],
|
||||
declarations: [...COMPONENTS]
|
||||
imports: [SharedModule, PassportRoutingModule, NzStepsModule],
|
||||
declarations: [...COMPONENTS, ForgotComponent]
|
||||
})
|
||||
export class PassportModule {}
|
||||
export class PassportModule { }
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { _HttpClient, User } from '@delon/theme';
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ForgotPasswordService {
|
||||
constructor(private http: _HttpClient) { }
|
||||
|
||||
produceOtp(param: any) {
|
||||
return this.http.get('/forgotpassword/produceOtp?_allow_anonymous=true', param);
|
||||
}
|
||||
|
||||
produceEmailOtp(param: any) {
|
||||
return this.http.get(`/forgotpassword/produceEmailOtp?_allow_anonymous=true`, param);
|
||||
}
|
||||
|
||||
setPassWord(param: any) {
|
||||
return this.http.get('/forgotpassword/setpassword?_allow_anonymous=true', param);
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,22 @@
|
||||
"text.captcha": "Captcha",
|
||||
"text.smscode": "Code"
|
||||
},
|
||||
"forgot":{
|
||||
"forgot":"Forgot Password",
|
||||
"step1":"Authentication",
|
||||
"step2":"Resetting Password",
|
||||
"type.mobile":"By Mobile",
|
||||
"type.email":"By Email",
|
||||
"mobile":"Mobile Phone Number",
|
||||
"email":"Email",
|
||||
"captcha":"Picture Captcha",
|
||||
"sendCaptcha":"Send Captcha",
|
||||
"password":"New Password",
|
||||
"confirmPassword":"Confirm Password",
|
||||
"login":"Back Login",
|
||||
"next":"Next",
|
||||
"submit":"Confirm"
|
||||
},
|
||||
"menu": {
|
||||
"applist": "Apps",
|
||||
"sessions": "Sessions",
|
||||
@ -807,6 +823,7 @@
|
||||
"app.login.text.password": "Password",
|
||||
"app.login.text.captcha": "CAPTCHA",
|
||||
"app.login.text.smscode": "Code",
|
||||
"app.forgot.forgot":"Forgot Password",
|
||||
"app.register.register": "Register",
|
||||
"app.register.get-verification-code": "Get code",
|
||||
"app.register.sign-in": "Already have an account?",
|
||||
|
||||
@ -16,11 +16,27 @@
|
||||
"signup": "用户注册",
|
||||
"login": "登录",
|
||||
"text.username": "用户名",
|
||||
"text.mobile": "手机号",
|
||||
"text.mobile": "手机号码",
|
||||
"text.password": "密码",
|
||||
"text.captcha": "验证码",
|
||||
"text.smscode": "验证码"
|
||||
},
|
||||
"forgot":{
|
||||
"forgot":"忘记密码",
|
||||
"step1":"验证身份",
|
||||
"step2":"设置新密码",
|
||||
"type.mobile":"手机找回",
|
||||
"type.email":"邮箱找回",
|
||||
"mobile":"手机号码",
|
||||
"email":"邮箱",
|
||||
"captcha":"图形验证码",
|
||||
"sendCaptcha":"发送验证码",
|
||||
"password":"新密码",
|
||||
"confirmPassword":"确认新密码",
|
||||
"login":"返回登录",
|
||||
"next":"下一步",
|
||||
"submit":"提交"
|
||||
},
|
||||
"menu": {
|
||||
"applist": "应用",
|
||||
"sessions": "会话",
|
||||
@ -805,6 +821,7 @@
|
||||
"app.login.text.password": "密码",
|
||||
"app.login.text.captcha": "验证码",
|
||||
"app.login.text.smscode": "验证码",
|
||||
"app.forgot.forgot":"忘记密码",
|
||||
"app.register.register": "注册",
|
||||
"app.register.get-verification-code": "获取验证码",
|
||||
"app.register.sign-in": "使用已有账户登录",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -17,31 +17,21 @@
|
||||
|
||||
package org.maxkey.web.contorller;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.authn.annotation.CurrentUser;
|
||||
import org.maxkey.constants.ConstsOperateMessage;
|
||||
import org.maxkey.constants.ConstsPasswordSetType;
|
||||
import org.maxkey.constants.ConstsTimeInterval;
|
||||
import org.maxkey.entity.ChangePassword;
|
||||
import org.maxkey.entity.Message;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.persistence.repository.PasswordPolicyValidator;
|
||||
import org.maxkey.persistence.service.UserInfoService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.maxkey.web.message.Message;
|
||||
import org.maxkey.web.message.MessageType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value={"/config"})
|
||||
@ -52,8 +42,8 @@ public class ChangePasswodController {
|
||||
private UserInfoService userInfoService;
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value="/changePassword")
|
||||
public Message changePasswod(
|
||||
@RequestMapping(value = { "/changePassword" }, produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||
public ResponseEntity<?> changePasswod(
|
||||
@RequestBody ChangePassword changePassword,
|
||||
@CurrentUser UserInfo currentUser) {
|
||||
|
||||
@ -62,12 +52,9 @@ public class ChangePasswodController {
|
||||
changePassword.setInstId(currentUser.getInstId());
|
||||
changePassword.setPasswordSetType(ConstsPasswordSetType.PASSWORD_NORMAL);
|
||||
if(userInfoService.changePassword(changePassword)) {
|
||||
return new Message(WebContext.getI18nValue(ConstsOperateMessage.UPDATE_SUCCESS),MessageType.success);
|
||||
return new Message<ChangePassword>().buildResponse();
|
||||
}else {
|
||||
return new Message(
|
||||
WebContext.getI18nValue(ConstsOperateMessage.UPDATE_ERROR)+"<br>"
|
||||
+WebContext.getAttribute(PasswordPolicyValidator.PASSWORD_POLICY_VALIDATE_RESULT),
|
||||
MessageType.error);
|
||||
return new Message<ChangePassword>(Message.ERROR).buildResponse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
|
||||
* Copyright [2022] [MaxKey of copyright http://www.maxkey.top]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -19,22 +19,26 @@ package org.maxkey.web.contorller;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.maxkey.authn.jwt.AuthJwtService;
|
||||
import org.maxkey.configuration.EmailConfig;
|
||||
import org.maxkey.entity.ChangePassword;
|
||||
import org.maxkey.entity.Message;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
|
||||
import org.maxkey.password.onetimepwd.OtpAuthnService;
|
||||
import org.maxkey.persistence.repository.PasswordPolicyValidator;
|
||||
import org.maxkey.persistence.service.UserInfoService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(value = { "/forgotpassword" })
|
||||
@ -45,7 +49,7 @@ public class ForgotPasswordContorller {
|
||||
"^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
|
||||
|
||||
Pattern mobileRegex = Pattern.compile(
|
||||
"^(13[4,5,6,7,8,9]|15[0,8,9,1,7]|188|187)\\\\d{8}$");
|
||||
"^[1][3,4,5,7,8][0-9]{9}$");
|
||||
|
||||
@Autowired
|
||||
EmailConfig emailConfig;
|
||||
@ -64,101 +68,107 @@ public class ForgotPasswordContorller {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private UserInfoService userInfoService;
|
||||
|
||||
AuthJwtService authJwtService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("mailOtpAuthn")
|
||||
protected AbstractOtpAuthn mailOtpAuthn;
|
||||
UserInfoService userInfoService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("otpAuthnService")
|
||||
OtpAuthnService otpAuthnService;
|
||||
|
||||
|
||||
@RequestMapping(value = { "/forward" })
|
||||
public ModelAndView forwardreg() {
|
||||
_logger.debug("forgotpassword /forgotpassword/forward.");
|
||||
return new ModelAndView("forgotpassword/findpwd");
|
||||
}
|
||||
|
||||
@RequestMapping(value = { "/emailmobile" })
|
||||
public ModelAndView email(@RequestParam String emailMobile,@RequestParam String captcha) {
|
||||
_logger.debug("forgotpassword /forgotpassword/emailmobile.");
|
||||
_logger.debug("emailMobile : " + emailMobile);
|
||||
int forgotType = ForgotType.NOTFOUND;
|
||||
UserInfo userInfo = null;
|
||||
if (captcha != null && captcha
|
||||
.equals(WebContext.getSession().getAttribute(
|
||||
WebConstants.KAPTCHA_SESSION_KEY).toString())) {
|
||||
if(mobileRegex.matcher(emailMobile).matches()) {
|
||||
forgotType = ForgotType.MOBILE;
|
||||
}else if(emailRegex.matcher(emailMobile).matches()) {
|
||||
forgotType = ForgotType.EMAIL;
|
||||
}else {
|
||||
forgotType = ForgotType.EMAIL;
|
||||
emailMobile =emailMobile + "@" + emailConfig.getSmtpHost().substring(emailConfig.getSmtpHost().indexOf(".")+1);
|
||||
}
|
||||
|
||||
userInfo = userInfoService.findByEmailMobile(emailMobile);
|
||||
|
||||
if(null != userInfo) {
|
||||
if (forgotType == ForgotType.EMAIL ) {
|
||||
mailOtpAuthn.produce(userInfo);
|
||||
}else if (forgotType == ForgotType.MOBILE) {
|
||||
AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(userInfo.getInstId());
|
||||
smsOtpAuthn.produce(userInfo);
|
||||
}
|
||||
}
|
||||
|
||||
}else {
|
||||
_logger.debug("login captcha valid error.");
|
||||
forgotType = ForgotType.CAPTCHAERROR;
|
||||
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = { "/produceOtp" }, produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||
public ResponseEntity<?> produceOtp(
|
||||
@RequestParam String mobile,
|
||||
@RequestParam String state,
|
||||
@RequestParam String captcha) {
|
||||
_logger.debug("forgotpassword /forgotpassword/produceOtp.");
|
||||
_logger.debug(" Mobile {}: " ,mobile);
|
||||
if (!authJwtService.validateCaptcha(state,captcha)) {
|
||||
_logger.debug("login captcha valid error.");
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
|
||||
ModelAndView modelAndView = new ModelAndView("forgotpassword/resetpwd");
|
||||
modelAndView.addObject("userId", userInfo==null ?"":userInfo.getId());
|
||||
modelAndView.addObject("username", userInfo==null ?"":userInfo.getUsername());
|
||||
modelAndView.addObject("emailMobile", emailMobile);
|
||||
modelAndView.addObject("forgotType", forgotType);
|
||||
ChangePassword change = null;
|
||||
_logger.debug("Mobile Regex matches {}",mobileRegex.matcher(mobile).matches());
|
||||
if(StringUtils.isNotBlank(mobile) && mobileRegex.matcher(mobile).matches()) {
|
||||
UserInfo userInfo = userInfoService.findByEmailMobile(mobile);
|
||||
if(userInfo != null) {
|
||||
change = new ChangePassword(userInfo);
|
||||
change.clearPassword();
|
||||
AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(userInfo.getInstId());
|
||||
smsOtpAuthn.produce(userInfo);
|
||||
return new Message<ChangePassword>(change).buildResponse();
|
||||
}
|
||||
}
|
||||
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@RequestMapping(value = { "/produceEmailOtp" }, produces = {MediaType.APPLICATION_JSON_VALUE})
|
||||
public ResponseEntity<?> produceEmailOtp(
|
||||
@RequestParam String email,
|
||||
@RequestParam String state,
|
||||
@RequestParam String captcha) {
|
||||
_logger.debug("forgotpassword /forgotpassword/produceEmailOtp.");
|
||||
_logger.debug("Email {} : " , email);
|
||||
if (!authJwtService.validateCaptcha(state,captcha)) {
|
||||
_logger.debug("login captcha valid error.");
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
|
||||
return modelAndView;
|
||||
ChangePassword change = null;
|
||||
if(StringUtils.isNotBlank(email) && emailRegex.matcher(email).matches()) {
|
||||
UserInfo userInfo = userInfoService.findByEmailMobile(email);
|
||||
if(userInfo != null) {
|
||||
change = new ChangePassword(userInfo);
|
||||
change.clearPassword();
|
||||
AbstractOtpAuthn mailOtpAuthn = otpAuthnService.getMailOtpAuthn(userInfo.getInstId());
|
||||
mailOtpAuthn.produce(userInfo);
|
||||
return new Message<ChangePassword>(change).buildResponse();
|
||||
}
|
||||
}
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
|
||||
@RequestMapping(value = { "/setpassword" })
|
||||
public ModelAndView setPassWord(
|
||||
@RequestParam String userId,
|
||||
@RequestParam String username,
|
||||
@RequestParam int forgotType,
|
||||
@RequestParam String password,
|
||||
@RequestParam String confirmpassword,
|
||||
@RequestParam String captcha) {
|
||||
_logger.debug("forgotPassword /forgotpassword/pwdreseted.");
|
||||
ModelAndView modelAndView = new ModelAndView("forgotpassword/pwdreseted");
|
||||
if (null != password && password.equals(confirmpassword)) {
|
||||
UserInfo userInfo = new UserInfo();
|
||||
userInfo.setId(userId);
|
||||
userInfo.setUsername(username);
|
||||
userInfo.setPassword(password);
|
||||
userInfo.setDecipherable(password);
|
||||
UserInfo loadedUserInfo = userInfoService.findByUsername(username);
|
||||
AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(loadedUserInfo.getInstId());
|
||||
if ((forgotType == ForgotType.EMAIL && mailOtpAuthn.validate(userInfo, captcha)) ||
|
||||
(forgotType == ForgotType.MOBILE && smsOtpAuthn.validate(userInfo, captcha))
|
||||
) {
|
||||
/**
|
||||
if(userInfoService.changePassword(userInfo,true)) {
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.SUCCESS);
|
||||
}else {
|
||||
;
|
||||
modelAndView.addObject("validate_result", WebContext.getAttribute(PasswordPolicyValidator.PASSWORD_POLICY_VALIDATE_RESULT));
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.PASSWORDERROR);
|
||||
}*/
|
||||
} else {
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.CAPTCHAERROR);
|
||||
}
|
||||
} else {
|
||||
modelAndView.addObject("passwordResetResult", PasswordResetResult.PASSWORDERROR);
|
||||
public ResponseEntity<?> setPassWord(
|
||||
@ModelAttribute ChangePassword changePassword,
|
||||
@RequestParam String forgotType,
|
||||
@RequestParam String otpCaptcha,
|
||||
@RequestParam String state) {
|
||||
_logger.debug("forgotPassword /forgotpassword/setpassword.");
|
||||
if (StringUtils.isNotBlank(changePassword.getPassword() )
|
||||
&& changePassword.getPassword().equals(changePassword.getConfirmPassword())) {
|
||||
UserInfo loadedUserInfo = userInfoService.get(changePassword.getUserId());
|
||||
if(loadedUserInfo != null) {
|
||||
AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(loadedUserInfo.getInstId());
|
||||
AbstractOtpAuthn mailOtpAuthn = otpAuthnService.getMailOtpAuthn(loadedUserInfo.getInstId());
|
||||
if (
|
||||
(forgotType.equalsIgnoreCase("email")
|
||||
&& mailOtpAuthn !=null
|
||||
&& mailOtpAuthn.validate(loadedUserInfo, otpCaptcha))
|
||||
||
|
||||
(forgotType.equalsIgnoreCase("mobile")
|
||||
&& smsOtpAuthn !=null
|
||||
&& smsOtpAuthn.validate(loadedUserInfo, otpCaptcha))
|
||||
) {
|
||||
|
||||
if(userInfoService.changePassword(changePassword,true)) {
|
||||
return new Message<ChangePassword>(Message.SUCCESS).buildResponse();
|
||||
}else {
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
} else {
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
return modelAndView;
|
||||
return new Message<ChangePassword>(Message.FAIL).buildResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,9 +46,6 @@ public class SafeController {
|
||||
@Autowired
|
||||
private UserInfoService userInfoService;
|
||||
|
||||
|
||||
|
||||
|
||||
@RequestMapping(value="/forward/setting")
|
||||
public ModelAndView fowardSetting(@CurrentUser UserInfo currentUser) {
|
||||
ModelAndView modelAndView=new ModelAndView("safe/setting");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user