MaxKey 3 anni fa
parent
commit
ffa1607c6f

+ 2 - 0
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/register-result/register-result.component.html

@@ -4,9 +4,11 @@
       {{ 'app.register-result.msg' | i18n: params }}
     </div>
   </ng-template>
+  <!--
   <button (click)="msg.success('email')" nz-button nzSize="large" [nzType]="'primary'">
     {{ 'app.register-result.view-mailbox' | i18n }}
   </button>
+  -->
   <button routerLink="/" nz-button nzSize="large">
     {{ 'app.register-result.back-home' | i18n }}
   </button>

+ 1 - 1
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/register-result/register-result.component.ts

@@ -10,6 +10,6 @@ export class UserRegisterResultComponent {
   params = { email: '' };
   email = '';
   constructor(route: ActivatedRoute, public msg: NzMessageService) {
-    this.params.email = this.email = route.snapshot.queryParams['email'] || 'ng-alain@example.com';
+    this.params.email = this.email = route.snapshot.queryParams['email'] || 'maxkeysupport@maxkey.top';
   }
 }

+ 22 - 0
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/register/register.component.html

@@ -4,6 +4,28 @@
   <nz-form-item>
     <nz-form-control [nzErrorTip]="mailErrorTip">
       <nz-input-group nzSize="large" nzAddonBeforeIcon="user">
+        <input nz-input formControlName="username" placeholder="username" />
+      </nz-input-group>
+      <ng-template #mailErrorTip let-i>
+        <ng-container *ngIf="i.errors?.required">{{ 'validation.email.required' | i18n }}</ng-container>
+        <ng-container *ngIf="i.errors?.email">{{ 'validation.email.wrong-format' | i18n }}</ng-container>
+      </ng-template>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control [nzErrorTip]="mailErrorTip">
+      <nz-input-group nzSize="large" nzAddonBeforeIcon="user">
+        <input nz-input formControlName="displayName" placeholder="displayName" />
+      </nz-input-group>
+      <ng-template #mailErrorTip let-i>
+        <ng-container *ngIf="i.errors?.required">{{ 'validation.email.required' | i18n }}</ng-container>
+        <ng-container *ngIf="i.errors?.email">{{ 'validation.email.wrong-format' | i18n }}</ng-container>
+      </ng-template>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control [nzErrorTip]="mailErrorTip">
+      <nz-input-group nzSize="large" nzAddonBeforeIcon="user">
         <input nz-input formControlName="mail" placeholder="Email" />
       </nz-input-group>
       <ng-template #mailErrorTip let-i>

+ 39 - 8
maxkey-web-frontend/maxkey-web-app/src/app/routes/passport/register/register.component.ts

@@ -4,8 +4,11 @@ import { Router } from '@angular/router';
 import { _HttpClient } from '@delon/theme';
 import { MatchControl } from '@delon/util/form';
 import { NzSafeAny } from 'ng-zorro-antd/core/types';
+import { NzMessageService } from 'ng-zorro-antd/message';
 import { finalize } from 'rxjs/operators';
 
+import { SignUpService } from '../../../service/signup.service';
+
 @Component({
   selector: 'passport-register',
   templateUrl: './register.component.html',
@@ -13,10 +16,19 @@ import { finalize } from 'rxjs/operators';
   changeDetection: ChangeDetectionStrategy.OnPush
 })
 export class UserRegisterComponent implements OnDestroy {
-  constructor(fb: FormBuilder, private router: Router, private http: _HttpClient, private cdr: ChangeDetectorRef) {
+  constructor(
+    fb: FormBuilder,
+    private signUpService: SignUpService,
+    private msg: NzMessageService,
+    private router: Router,
+    private http: _HttpClient,
+    private cdr: ChangeDetectorRef
+  ) {
     this.form = fb.group(
       {
-        mail: [null, [Validators.required, Validators.email]],
+        username: [null, [Validators.required]],
+        displayName: [null, [Validators.required]],
+        email: [null, [Validators.required, Validators.email]],
         password: [null, [Validators.required, Validators.minLength(6), UserRegisterComponent.checkPassword.bind(this)]],
         confirm: [null, [Validators.required, Validators.minLength(6)]],
         mobilePrefix: ['+86'],
@@ -31,8 +43,15 @@ export class UserRegisterComponent implements OnDestroy {
 
   // #region fields
 
-  get mail(): AbstractControl {
-    return this.form.get('mail')!;
+  get username(): AbstractControl {
+    return this.form.get('username')!;
+  }
+
+  get displayName(): AbstractControl {
+    return this.form.get('displayName')!;
+  }
+  get email(): AbstractControl {
+    return this.form.get('email')!;
   }
   get password(): AbstractControl {
     return this.form.get('password')!;
@@ -92,6 +111,13 @@ export class UserRegisterComponent implements OnDestroy {
       this.mobile.updateValueAndValidity({ onlySelf: true });
       return;
     }
+    this.signUpService.produceOtp({ mobile: this.mobile.value }).subscribe(res => {
+      if (res.code !== 0) {
+        this.msg.success(`短信发送失败`);
+        this.cdr.detectChanges();
+      }
+      this.msg.success(`短信发送成功`);
+    });
     this.count = 59;
     this.cdr.detectChanges();
     this.interval$ = setInterval(() => {
@@ -104,7 +130,6 @@ export class UserRegisterComponent implements OnDestroy {
   }
 
   // #endregion
-
   submit(): void {
     this.error = '';
     Object.keys(this.form.controls).forEach(key => {
@@ -118,15 +143,21 @@ export class UserRegisterComponent implements OnDestroy {
     const data = this.form.value;
     this.loading = true;
     this.cdr.detectChanges();
-    this.http
-      .post('/register?_allow_anonymous=true', data)
+    this.signUpService
+      .register(data)
       .pipe(
         finalize(() => {
           this.loading = false;
           this.cdr.detectChanges();
         })
       )
-      .subscribe(() => {
+      .subscribe(res => {
+        if (res.code !== 0) {
+          this.msg.success(`注册失败`);
+          this.cdr.detectChanges();
+          return;
+        }
+        this.msg.success(`注册成功`);
         this.router.navigate(['passport', 'register-result'], { queryParams: { email: data.mail } });
       });
   }

+ 16 - 0
maxkey-web-frontend/maxkey-web-app/src/app/service/signup.service.ts

@@ -0,0 +1,16 @@
+import { Injectable, Inject } from '@angular/core';
+import { _HttpClient, User } from '@delon/theme';
+@Injectable({
+  providedIn: 'root'
+})
+export class SignUpService {
+  constructor(private http: _HttpClient) { }
+
+  produceOtp(param: any) {
+    return this.http.get('/signup/produceOtp?_allow_anonymous=true', param);
+  }
+
+  register(param: any) {
+    return this.http.get('/signup/register?_allow_anonymous=true', param);
+  }
+}

+ 2 - 3
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/contorller/ForgotPasswordContorller.java

@@ -115,10 +115,9 @@ public class ForgotPasswordContorller {
     			@RequestParam String email,
     			@RequestParam String state,
     			@RequestParam String captcha) {
-        _logger.debug("forgotpassword  /forgotpassword/produceEmailOtp.");
-        _logger.debug("Email {} : " , email);
+        _logger.debug("/forgotpassword/produceEmailOtp Email {} : " , email);
         if (!authJwtService.validateCaptcha(state,captcha)) {
-        	_logger.debug("login captcha valid error.");
+        	_logger.debug("captcha valid error.");
         	return new Message<ChangePassword>(Message.FAIL).buildResponse();
         }
         

+ 70 - 178
maxkey-webs/maxkey-web-maxkey/src/main/java/org/maxkey/web/contorller/RegisterController.java

@@ -18,39 +18,33 @@
 package org.maxkey.web.contorller;
 
 import java.io.IOException;
-import java.util.Date;
+import java.util.regex.Pattern;
+
 import javax.servlet.ServletException;
-import org.apache.commons.mail.DefaultAuthenticator;
-import org.apache.commons.mail.EmailException;
-import org.apache.commons.mail.HtmlEmail;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
+
+import org.maxkey.authn.jwt.AuthJwtService;
 import org.maxkey.configuration.ApplicationConfig;
 import org.maxkey.constants.ConstsStatus;
 import org.maxkey.crypto.password.PasswordReciprocal;
-import org.maxkey.entity.Register;
+import org.maxkey.entity.Message;
 import org.maxkey.entity.UserInfo;
-import org.maxkey.persistence.service.RegisterService;
+import org.maxkey.password.onetimepwd.AbstractOtpAuthn;
+import org.maxkey.password.onetimepwd.OtpAuthnService;
 import org.maxkey.persistence.service.UserInfoService;
-import org.maxkey.util.DateUtils;
 import org.maxkey.util.StringUtils;
 import org.maxkey.web.WebContext;
-import org.maxkey.web.message.Message;
-import org.mybatis.spring.SqlSessionUtils;
 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.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
 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
@@ -58,183 +52,81 @@ import org.springframework.web.servlet.ModelAndView;
 public class RegisterController {
 	private static Logger _logger = LoggerFactory.getLogger(RegisterController.class);
 	
+	Pattern mobileRegex = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
+	
 	@Autowired
-	RegisterService registerService;
+	AuthJwtService authJwtService;
 	
 	@Autowired 
-  	@Qualifier("applicationConfig")
   	protected ApplicationConfig applicationConfig;
 	
 	@Autowired
-	@Qualifier("userInfoService")
 	private UserInfoService userInfoService;
 	
 	@Autowired
-	private PasswordEncoder passwordEncoder;
-	
-	
-	@RequestMapping(value={"/forward"})
-	public ModelAndView forward() {
-		_logger.debug("register  /register/register.");
-		return  new ModelAndView("register/register");
-	}
+    @Qualifier("otpAuthnService")
+    OtpAuthnService otpAuthnService;
 	
-	@RequestMapping(value={"/forward/email"})
-	public ModelAndView forwardEmail() {
-		_logger.debug("register  /register/register.");
-		return  new ModelAndView("register/registerInst");
-	}
-	
-	//邮件验证注册
-	@RequestMapping(value={"/register"})
-	public ModelAndView reg(@ModelAttribute("register") Register register) {
-		_logger.debug("register  /register/register.");
-		_logger.debug(""+register);
-		ModelAndView modelAndView= new ModelAndView("register/registered");
-		
-		UserInfo userInfo = registerService.findByEmail(register.getWorkEmail());
-		
-		if(userInfo!=null){
-			modelAndView.addObject("registered", 1);
-			return modelAndView;
-		}
-		
-		register.setId(register.generateId());
-		registerService.insert(register);
-		HtmlEmail email = new HtmlEmail();
-		  
-		try {
-			email.setHostName(applicationConfig.getEmailConfig().getSmtpHost());
-			email.setSmtpPort(applicationConfig.getEmailConfig().getPort());
-			email.setAuthenticator(new DefaultAuthenticator(
-							applicationConfig.getEmailConfig().getUsername(), 
-							applicationConfig.getEmailConfig().getPassword()
-						));
-			
-			email.addTo(register.getWorkEmail(), register.getDisplayName());
-			email.setFrom(applicationConfig.getEmailConfig().getSender(), "MaxKey");
-			email.setSubject("MaxKey Identity & Access Registration activate Email .");
-			  
-			String activateUrl=WebContext.getHttpContextPath()+"/register/forward/activate/"+register.getId();
-			
-			
-			// set the html message
-			String emailText="<html>";
-			 			emailText+="<a href='"+activateUrl+"'>activate</a><br>";
-			 			emailText+=" or copy "+activateUrl+" to brower.";
-			 	   emailText+="</html>";
-			email.setHtmlMsg(emailText);
-			
-			// set the alternative message
-			email.setTextMsg("Your email client does not support HTML messages");
-			
-			// send the email
-			email.send();
-		} catch (EmailException e) {
-			e.printStackTrace();
-		}
-		modelAndView.addObject("registered", 0); 
-		return  modelAndView;
-	}
-	
-	@GetMapping(value={"/forward/activate/{id}"})
-	public ModelAndView confirm(@PathVariable("id") String id) {
-		_logger.debug("register  /register/forward/activate.");
-		Register register=registerService.get(id);
-		ModelAndView mav=new ModelAndView("register/activate");
-		if(register!=null){
-			mav.addObject("model", register);
-		}
-		
-		return mav;
-	}
-	
-	@PostMapping(value={"/activate/{id}"})
-	public ModelAndView setPassWord(@PathVariable("id") String id,
-									@RequestParam String password,
-									@RequestParam String confirmpassword) {
-		_logger.debug("register  /register/setpassword.");
-		ModelAndView modelAndView=new ModelAndView("register/activated");
-		if(password.equals(confirmpassword)){
-			Register register=registerService.get(id);
-			if(register!=null){
-				SqlSession  sqlSession  = SqlSessionUtils.getSqlSession(
-									WebContext.getBean("sqlSessionFactory",SqlSessionFactory.class));
-				sqlSession.commit(false);
-				
-				UserInfo userInfo=new UserInfo();
-				userInfo.setUsername(register.getWorkEmail());
-				userInfo.setDisplayName(register.getDisplayName());
-				
-				userInfo.setWorkPhoneNumber(register.getWorkPhone());
-				userInfo.setEmail(register.getWorkEmail());
-				userInfo.setStatus(ConstsStatus.ACTIVE);
-				userInfo.setDecipherable(PasswordReciprocal.getInstance().encode(password));
-				
-				password = passwordEncoder.encode(password );
-				userInfo.setPassword(password);
-				//default InstId
-				if(StringUtils.isEmpty(userInfo.getInstId())) {
-					userInfo.setInstId("1");
-				}
-				userInfo.setPasswordLastSetTime(DateUtils.format(new Date(), DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS));
-				userInfoService.insert(userInfo);
-
-				registerService.remove(id);
-				sqlSession.commit(true);
-				modelAndView.addObject("activate", 1);
-			}else{
-				modelAndView.addObject("activate", 2);
-			}
-		}else{
-			modelAndView.addObject("activate", 0);
-		}
-		return  modelAndView;
-	}
+	@Autowired
+	private PasswordEncoder passwordEncoder;
  	
+	@ResponseBody
+	@RequestMapping(value = { "/produceOtp" }, produces = {MediaType.APPLICATION_JSON_VALUE})
+	public ResponseEntity<?> produceOtp(
+	    			@RequestParam String mobile) {
+        _logger.debug("/signup/produceOtp Mobile {}: " ,mobile);
+ 
+    	_logger.debug("Mobile Regex matches {}",mobileRegex.matcher(mobile).matches());
+    	if(StringUtils.isNotBlank(mobile) && mobileRegex.matcher(mobile).matches()) {
+    		UserInfo userInfo = new UserInfo();
+    		userInfo.setUsername(mobile);
+    		userInfo.setMobile(mobile);
+        	AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(WebContext.getInst().getId());
+        	smsOtpAuthn.produce(userInfo);
+        	return new Message<UserInfo>(userInfo).buildResponse();
+        }
+            
+        return new Message<UserInfo>(Message.FAIL).buildResponse();
+    }
+	  
 	//直接注册
- 	@RequestMapping(value={"/registeron"})
+ 	@RequestMapping(value={"/register"})
  	@ResponseBody
-	public Message registeron(UserInfo userInfo,@RequestParam String emailMobile) throws ServletException, IOException {
- 		
- 		if(StringUtils.isEmpty(emailMobile)) {
- 			return new Message(WebContext.getI18nValue("register.emailMobile.error"),"1");
- 		}
- 		
- 		if(StringUtils.isValidEmail(emailMobile)) {
- 			userInfo.setEmail(emailMobile);
- 		}
- 		
- 		if(StringUtils.isValidMobileNo(emailMobile)) {
- 			userInfo.setMobile(emailMobile);
- 		}
- 		
- 		if(!(StringUtils.isValidEmail(emailMobile)||StringUtils.isValidMobileNo(emailMobile))) {
- 			return new Message(WebContext.getI18nValue("register.emailMobile.error"),"1");
- 		}
- 		
- 		UserInfo temp = userInfoService.findByEmailMobile(emailMobile);
- 		
- 		if(temp!=null) {
- 			return new Message(WebContext.getI18nValue("register.emailMobile.exist"),"1");
- 		}
- 		
- 		temp = userInfoService.findByUsername(userInfo.getUsername());
- 		if(temp!=null) {
- 			return new Message(WebContext.getI18nValue("register.user.error"),"1");
- 		}
- 		//default InstId
- 		if(StringUtils.isEmpty(userInfo.getInstId())) {
-			userInfo.setInstId("1");
-		}
- 		
- 		userInfo.setStatus(ConstsStatus.ACTIVE);
- 		
- 		if(userInfoService.insert(userInfo)) {
- 			return new Message(WebContext.getI18nValue("login.text.register.success"),"0");
+	public ResponseEntity<?> register(
+				@ModelAttribute UserInfo userInfo,
+				@RequestParam String captcha) throws ServletException, IOException {
+ 		UserInfo validateUserInfo = new UserInfo();
+ 		validateUserInfo.setUsername(userInfo.getMobile());
+ 		validateUserInfo.setMobile(userInfo.getMobile());
+ 		AbstractOtpAuthn smsOtpAuthn = otpAuthnService.getByInstId(WebContext.getInst().getId());
+ 		if (smsOtpAuthn !=null 
+        				&& smsOtpAuthn.validate(validateUserInfo, captcha)){
+	 		UserInfo temp = userInfoService.findByEmailMobile(userInfo.getEmail());
+	 		
+	 		if(temp != null) {
+	 			return new Message<UserInfo>(Message.FAIL).buildResponse();
+	 		}
+	 		
+	 		temp = userInfoService.findByUsername(userInfo.getUsername());
+	 		if(temp != null) {
+	 			return new Message<UserInfo>(Message.FAIL).buildResponse();
+	 		}
+	 		
+	 		//default InstId
+	 		if(StringUtils.isEmpty(userInfo.getInstId())) {
+				userInfo.setInstId("1");
+			}
+	 		String password = userInfo.getPassword();
+	 		userInfo.setDecipherable(PasswordReciprocal.getInstance().encode(password));
+	 		password = passwordEncoder.encode(password );
+			userInfo.setPassword(password);
+	 		userInfo.setStatus(ConstsStatus.INACTIVE);
+	 		
+	 		if(userInfoService.insert(userInfo)) {
+	 			return new Message<UserInfo>().buildResponse();
+	 		}
  		}
- 		return new Message(WebContext.getI18nValue("login.text.register.error"),"1");
- 		
+ 		return new Message<UserInfo>(Message.FAIL).buildResponse();
  	}
 
 }