Rework verify code from unlogged action

This commit is contained in:
jeffcheasey88 2024-09-16 07:52:37 +02:00
parent ee9739f5d3
commit d89a11fba0
3 changed files with 116 additions and 34 deletions

View file

@ -2,9 +2,14 @@ package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST; import static dev.peerat.framework.RequestType.POST;
import java.lang.reflect.Constructor;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import dev.peerat.backend.model.PeerAtUser; import dev.peerat.backend.model.PeerAtUser;
@ -23,13 +28,28 @@ public class ForgotPassword extends FormResponse{
private Router<PeerAtUser> router; private Router<PeerAtUser> router;
private DatabaseRepository repo; private DatabaseRepository repo;
private Mail mail; private Mail mail;
private Map<String, Integer> codes; private Map<String, String> codes;
private List<Random> randoms;
public ForgotPassword(Router<PeerAtUser> router, DatabaseRepository repo, Mail mail){ public ForgotPassword(Router<PeerAtUser> router, DatabaseRepository repo, Mail mail){
this.router = router; this.router = router;
this.repo = repo; this.repo = repo;
this.mail = mail; this.mail = mail;
this.codes = new HashMap<>(); this.codes = new HashMap<>();
this.randoms = new ArrayList<>();
Random random = new Random();
int randoms = random.nextInt(10)+3;
for(int i = 0; i < randoms; i++) this.randoms.add(new SecureRandom());
try {
Constructor<?> constructor = UUID.class.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
this.uuidBuilder = constructor;
} catch (Exception e){
e.printStackTrace();
}
} }
@Route(path = "^/user/fpw$", type = POST) @Route(path = "^/user/fpw$", type = POST)
@ -54,16 +74,16 @@ public class ForgotPassword extends FormResponse{
} }
if(hasFields("code") && areValids("password")){ if(hasFields("code") && areValids("password")){
Integer checkCode = codes.get(email); String checkCode = codes.get(email);
if(checkCode == null){ if(checkCode == null){
context.response(400); context.response(400);
return; return;
} }
int code = json.<Number>get("code").intValue(); String code = json.<String>get("code");
String password = json.get("password"); String password = json.get("password");
if(code == checkCode.intValue()){ if(checkCode.equals(code)){
codes.remove(email); codes.remove(email);
repo.updatePassword(player, password); repo.updatePassword(player, password);
@ -74,18 +94,25 @@ public class ForgotPassword extends FormResponse{
context.response(400); context.response(400);
} }
}else{ }else{
int code = codeGenerator(); String code = codeGenerator();
codes.put(email, code); codes.put(email, code);
mail.send(email, "Forgot your Peer @ Code password ?", "Your check code is "+code+" !"); mail.send(email, "Forgot your Peer @ Code password ?", "Your check code is "+code+" !");
context.response(200); context.response(200);
} }
} }
private int codeGenerator(){ private Constructor<?> uuidBuilder;
int min = 1000;
int max = 9999; private String codeGenerator() throws Exception{
return new Random().nextInt((max-min)) + min; Random random = new Random();
Random target = this.randoms.get(random.nextInt(this.randoms.size()));
byte[] arrayOfByte = new byte[16];
target.nextBytes(arrayOfByte);
arrayOfByte[6] = (byte)(arrayOfByte[6] & 0xF);
arrayOfByte[6] = (byte)(arrayOfByte[6] | 0x40);
arrayOfByte[8] = (byte)(arrayOfByte[8] & 0x3F);
arrayOfByte[8] = (byte)(arrayOfByte[8] | 0x80);
return uuidBuilder.newInstance(arrayOfByte).toString();
} }
} }

View file

@ -5,6 +5,7 @@ import static dev.peerat.framework.RequestType.POST;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.net.URL; import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.file.Files; import java.nio.file.Files;
@ -12,11 +13,15 @@ import java.nio.file.Paths;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyPairGenerator; import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.Base64.Encoder; import java.util.Base64.Encoder;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
@ -37,7 +42,7 @@ import dev.peerat.framework.Route;
import dev.peerat.framework.Router; import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonMap; import dev.peerat.framework.utils.json.JsonMap;
public class MailConfirmation extends FormResponse { public class MailConfirmation extends FormResponse{
private DatabaseRepository databaseRepo; private DatabaseRepository databaseRepo;
private Router<PeerAtUser> router; private Router<PeerAtUser> router;
@ -45,15 +50,16 @@ public class MailConfirmation extends FormResponse {
private KeyPairGenerator generator; private KeyPairGenerator generator;
private Encoder encoder; private Encoder encoder;
private String gitToken; private String gitToken;
private Map<String, Integer> playersWaiting; private Map<String, String> playersWaiting;
private Mail mail; private Mail mail;
private List<Random> randoms;
public MailConfirmation( public MailConfirmation(
DatabaseRepository databaseRepo, DatabaseRepository databaseRepo,
Router<PeerAtUser> router, Router<PeerAtUser> router,
@Injection("usersFiles") String initUsersFilesPath, @Injection("usersFiles") String initUsersFilesPath,
@Injection("gitToken") String gitToken, @Injection("gitToken") String gitToken,
@Injection("waitting") Map<String, Integer> playersWaiting, @Injection("waitting") Map<String, String> playersWaiting,
Mail mail) throws NoSuchAlgorithmException{ Mail mail) throws NoSuchAlgorithmException{
this.databaseRepo = databaseRepo; this.databaseRepo = databaseRepo;
@ -67,6 +73,20 @@ public class MailConfirmation extends FormResponse {
generator.initialize(4096); generator.initialize(4096);
encoder = Base64.getEncoder(); encoder = Base64.getEncoder();
this.randoms = new ArrayList<>();
Random random = new Random();
int randoms = random.nextInt(10)+3;
for(int i = 0; i < randoms; i++) this.randoms.add(new SecureRandom());
try {
Constructor<?> constructor = UUID.class.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
this.uuidBuilder = constructor;
} catch (Exception e){
e.printStackTrace();
}
validator("pseudo", "[a-zA-Z0-9&|!?{}\\[\\]%/*\\-+=:;,_#@ ]{3,100}"); validator("pseudo", "[a-zA-Z0-9&|!?{}\\[\\]%/*\\-+=:;,_#@ ]{3,100}");
validator("firstname", "^(?>[a-zA-Z]+ ?)+$"); validator("firstname", "^(?>[a-zA-Z]+ ?)+$");
validator("lastname", "^(?>[a-zA-Z]+ ?)+$"); validator("lastname", "^(?>[a-zA-Z]+ ?)+$");
@ -88,13 +108,13 @@ public class MailConfirmation extends FormResponse {
return; return;
} }
String email = json.get("email"); String email = json.get("email");
int code = json.<Number>get("code").intValue(); String code = json.<String>get("code");
String pseudo = json.get("pseudo"); String pseudo = json.get("pseudo");
String firstname = json.get("firstname"); String firstname = json.get("firstname");
String lastname = json.get("lastname"); String lastname = json.get("lastname");
String password = json.get("passwd"); String password = json.get("passwd");
Integer checkCode = playersWaiting.get(email); String checkCode = playersWaiting.get(email);
if(checkCode == null){ if(checkCode == null){
context.response(400); context.response(400);
return; return;
@ -103,7 +123,7 @@ public class MailConfirmation extends FormResponse {
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo); boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
boolean emailAvailable = databaseRepo.checkEmailAvailability(email); boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(pseudoAvailable && emailAvailable){ if(pseudoAvailable && emailAvailable){
if(code == checkCode.intValue()){ if(code.equals(checkCode)){
playersWaiting.remove(email); playersWaiting.remove(email);
int id = databaseRepo.register(pseudo, email, password, firstname, lastname, "", "", ""); int id = databaseRepo.register(pseudo, email, password, firstname, lastname, "", "", "");
if(id >= 0){ if(id >= 0){
@ -118,7 +138,7 @@ public class MailConfirmation extends FormResponse {
error.set("username_valid", pseudo); error.set("username_valid", pseudo);
error.set("email_valid", email); error.set("email_valid", email);
writer.write(error.toString()); writer.write(error.toString());
int ncode = codeGenerator(); String ncode = codeGenerator()+codeGenerator();
playersWaiting.put(email, ncode); playersWaiting.put(email, ncode);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+ncode+" !"); mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+ncode+" !");
} }
@ -134,13 +154,20 @@ public class MailConfirmation extends FormResponse {
} }
} }
private int codeGenerator(){ private Constructor<?> uuidBuilder;
int min = 1000;
int max = 9999; private String codeGenerator() throws Exception{
return new Random().nextInt((max-min)) + min; Random random = new Random();
Random target = this.randoms.get(random.nextInt(this.randoms.size()));
byte[] arrayOfByte = new byte[16];
target.nextBytes(arrayOfByte);
arrayOfByte[6] = (byte)(arrayOfByte[6] & 0xF);
arrayOfByte[6] = (byte)(arrayOfByte[6] | 0x40);
arrayOfByte[8] = (byte)(arrayOfByte[8] & 0x3F);
arrayOfByte[8] = (byte)(arrayOfByte[8] | 0x80);
return uuidBuilder.newInstance(arrayOfByte).toString();
} }
private void createFolderToSaveSourceCode(String pseudo) throws IOException { private void createFolderToSaveSourceCode(String pseudo) throws IOException {
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo))); Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));

View file

@ -2,8 +2,13 @@ package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST; import static dev.peerat.framework.RequestType.POST;
import java.lang.reflect.Constructor;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc; import dev.peerat.backend.bonus.extract.RouteDoc;
@ -17,16 +22,32 @@ import dev.peerat.framework.Injection;
import dev.peerat.framework.Route; import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap; import dev.peerat.framework.utils.json.JsonMap;
public class Register extends FormResponse { public class Register extends FormResponse{
private DatabaseRepository databaseRepo; private DatabaseRepository databaseRepo;
private Map<String, Integer> playersWaiting; private Map<String, String> playersWaiting;
private Mail mail; private Mail mail;
private String host;
private List<Random> randoms;
public Register(DatabaseRepository databaseRepo, @Injection("waitting") Map<String, Integer> playersWaiting, Mail mail){ public Register(DatabaseRepository databaseRepo, @Injection("waitting") Map<String, String> playersWaiting, Mail mail, @Injection("issuer") String host){
this.databaseRepo = databaseRepo; this.databaseRepo = databaseRepo;
this.playersWaiting = playersWaiting; this.playersWaiting = playersWaiting;
this.mail = mail; this.mail = mail;
this.host = host;
this.randoms = new ArrayList<>();
Random random = new Random();
int randoms = random.nextInt(10)+3;
for(int i = 0; i < randoms; i++) this.randoms.add(new SecureRandom());
try {
Constructor<?> constructor = UUID.class.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
this.uuidBuilder = constructor;
} catch (Exception e){
e.printStackTrace();
}
} }
@RouteDoc(path = "/register", responseCode = 200, responseDescription = "L'utilisateur est inscrit") @RouteDoc(path = "/register", responseCode = 200, responseDescription = "L'utilisateur est inscrit")
@ -49,9 +70,9 @@ public class Register extends FormResponse {
boolean emailAvailable = databaseRepo.checkEmailAvailability(email); boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(emailAvailable){ if(emailAvailable){
int code = codeGenerator(); String code = codeGenerator()+codeGenerator();
playersWaiting.put(email, code); playersWaiting.put(email, code);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+code+" !"); mail.send(email, "Welcome @ Peer @ Code", "Please, confirm your code on "+host+"/?code="+code+" !");
context.response(200); context.response(200);
}else{ }else{
context.response(400); context.response(400);
@ -61,11 +82,18 @@ public class Register extends FormResponse {
} }
} }
private int codeGenerator(){ private Constructor<?> uuidBuilder;
int min = 1000;
int max = 9999; private String codeGenerator() throws Exception{
return new Random().nextInt((max-min)) + min; Random random = new Random();
Random target = this.randoms.get(random.nextInt(this.randoms.size()));
byte[] arrayOfByte = new byte[16];
target.nextBytes(arrayOfByte);
arrayOfByte[6] = (byte)(arrayOfByte[6] & 0xF);
arrayOfByte[6] = (byte)(arrayOfByte[6] | 0x40);
arrayOfByte[8] = (byte)(arrayOfByte[8] & 0x3F);
arrayOfByte[8] = (byte)(arrayOfByte[8] | 0x80);
return uuidBuilder.newInstance(arrayOfByte).toString();
} }
} }