diff --git a/pom.xml b/pom.xml index 8136386..075b2eb 100644 --- a/pom.xml +++ b/pom.xml @@ -90,6 +90,24 @@ org.springframework.boot spring-boot-starter-validation + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + diff --git a/src/main/java/com/crov/controllers/AuthController.java b/src/main/java/com/crov/controllers/AuthController.java new file mode 100644 index 0000000..1f1f956 --- /dev/null +++ b/src/main/java/com/crov/controllers/AuthController.java @@ -0,0 +1,23 @@ +package com.crov.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +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.RestController; + +import com.crov.services.AuthService; + +@RestController +@RequestMapping("/api/auth") +public class AuthController { + + @Autowired + private AuthService authService; + + @PostMapping("/token") + public ResponseEntity login(@RequestParam String username, @RequestParam String password) { + return ResponseEntity.ok(authService.login(username, password)); + } +} diff --git a/src/main/java/com/crov/controllers/SeguridadLicenciasController.java b/src/main/java/com/crov/controllers/SeguridadLicenciasController.java new file mode 100644 index 0000000..792f05f --- /dev/null +++ b/src/main/java/com/crov/controllers/SeguridadLicenciasController.java @@ -0,0 +1,199 @@ +package com.crov.controllers; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.crov.crovWSTotal.EncriptadorAES; +import com.crov.crovWSTotal.Utilerias; +import com.crov.models.ActivationKey; +import com.crov.models.ActivationKey.ActiveKey; +import com.crov.models.ActivationKey.TipoKey; +import com.crov.models.PersonSoftware; +import com.crov.models.PersonSoftware.ActivePerson; +import com.crov.models.PersonSoftware.BlackListPerson; +import com.crov.models.Software; +import com.crov.models.Software.ActiveSofware; +import com.crov.requests.PersonSoftwareRequest; +import com.crov.services.ActivationKeyService; +import com.crov.services.PersonSoftwareService; +import com.crov.services.SoftwareService; + +@RestController +@CrossOrigin(origins = "http://localhost:5173") +@RequestMapping("/api/seguridadLicencias") +public class SeguridadLicenciasController { + + private static final String LICENCIA_DEMO = "0db513ee-7757-11ed-a1eb-0242ac120002"; + + @Autowired + ActivationKeyService actKeyServ; + + @Autowired + SoftwareService softwareServ; + + @Autowired + PersonSoftwareService personServ; + + @PostMapping("/registroLicencia") + public ResponseEntity> registroLicencia(@RequestBody PersonSoftwareRequest licencia) throws ParseException { + + String token = ""; + + String modulosActivos = ""; + Date fecha_expiracion; + Integer validadorPersona = 0; + SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd"); + EncriptadorAES encrip = new EncriptadorAES(); + Date today = new Date(); + + // Observa que la llave ingresada exista y esté activa en la base de datos. + if (actKeyServ.revisarLicenciaActivaSinUso(licencia.getActivation_key().toString()) != 1) { + Map map = new HashMap<>(); + map.put("Status", "Transacción fallida."); + map.put("Token", "Llave incorrecta o utilizada."); + return ResponseEntity.ok(map); + } + + // Observa si la llave ingresada por el usuario es una de prueba. + if (licencia.getActivation_key().toString().equals(LICENCIA_DEMO)) { + // Se verifica que la MAc no se haya ingresado + if (softwareServ.revisarMacExistePreviamente(licencia.getMac()) != 0) { + Map map = new HashMap<>(); + map.put("Status", "Transacción fallida."); + map.put("Token", "Ya esta registrado en el sistema"); + return ResponseEntity.ok(map); + } else { + + ActivationKey actKey = new ActivationKey(); + Utilerias util = new Utilerias(); + // OBtenemos la fecha actual y le sumamos 15 días (pasa los meses, años, etc) + fecha_expiracion = (util.sumarDiasAFecha(new Date(), 30)); + String sdf = new SimpleDateFormat("yyyy-MM-dd").format(fecha_expiracion); + // Se genera el token + token = encrip.getAES(sdf.substring(0, 4) + licencia.getMac().substring(0, 17) + sdf.substring(5, 7) + + (licencia.getMac().substring(17, 45)) + sdf.substring(8, 10)); + } + } else { + // Verificamos que el usuario no haya sido registrado + validadorPersona = softwareServ.revisarMacExistePreviamente(licencia.getMac().toString()); + // Significa que la llave es vitalicia o de renta + // Generamos el modelo de ActivationKey + ActivationKey actKey = new ActivationKey(); + // Buscamos el objeto para actualizarlo + actKey = actKeyServ.getActivationCodePorCodigoActivacion(licencia.getActivation_key().toString()); + + // Se actualiza + actKeyServ.actualizarActiveKey(actKey.getId().toString()); + // Se general el token + // Es vitalicia + if (actKey.getActivationTime() == null) { + token = encrip.getAES("2050" + licencia.getMac().substring(0, 17) + "01" + + (licencia.getMac().substring(17, 45)) + "01"); + fecha_expiracion = formato.parse("2050-01-01"); + modulosActivos = actKey.getModules(); + if (modulosActivos == null) { + modulosActivos = ""; + } else { + modulosActivos = encrip.getAES(modulosActivos); + } + // No es vitalicia + }else { + Utilerias util = new Utilerias(); + fecha_expiracion = (util.sumarDiasAFecha(new Date(), actKey.getActivationTime())); + String sdf = new SimpleDateFormat("yyyy-MM-dd").format(fecha_expiracion); + token = encrip.getAES(sdf.substring(0, 4) + licencia.getMac().substring(0, 17) + sdf.substring(5, 7) + + (licencia.getMac().substring(17, 45)) + sdf.substring(8, 10)); + modulosActivos = actKey.getModules(); + if (modulosActivos == null) { + modulosActivos = ""; + } else { + modulosActivos = encrip.getAES(modulosActivos); + } + } + + } + + if (validadorPersona == 0) { + // Person vacia + PersonSoftware person = new PersonSoftware(); + // Software vacio + Software soft = new Software(); + + // Se construye persona. + token = token + "|" + modulosActivos; + person.setFirst_name(licencia.getFirst_name()); + person.setSecond_name(licencia.getSecond_name()); + person.setLast_name(licencia.getLast_name()); + person.setMiddle_name(licencia.getMiddle_name()); + person.setMail(licencia.getMail()); + person.setBirthdate(formato.parse(licencia.getBirthdate())); + person.setPhone(licencia.getPhone()); + person.setCreated_on(today); + person.setActivePerson(ActivePerson.Active); + person.setBlack_listPerson(BlackListPerson.Disabled); + + // Insercion de persona y se retorna el valor del ID. + person = personServ.savePerson(person); + + // Se construye software + soft.setPayment(licencia.getPayment()); + soft.setMac(licencia.getMac()); + soft.setActivation_key(licencia.getActivation_key()); + soft.setToken_product(token); + soft.setId_software_product(licencia.getId_product()); + soft.setId_customer(person.getId()); + soft.setActiveSofware(ActiveSofware.Active); + soft.setExpiration_date(fecha_expiracion); + soft.setCreated_on(today); + + softwareServ.save(soft); + + Map map = new HashMap<>(); + map.put("Token", token); + map.put("Status", "Transacción correcta."); + return ResponseEntity.ok(map); + } else { + + // La persona ya se había registrado y es necesario actualizarla + Software softwareModel = new Software(); + token = token + "|" + modulosActivos; + softwareModel = softwareServ.getSofwareByMac(licencia.getMac().toString()); + softwareModel.setToken_product(token); + softwareModel.setExpiration_date(fecha_expiracion); + softwareModel.setPaid(1); + softwareServ.save(softwareModel); + Map map = new HashMap<>(); + map.put("Token", token); + map.put("Status", "Transacción correcta."); + return ResponseEntity.ok(map); + } + + } + + @PostMapping("/generarLicenciaVitalicia") + public ResponseEntity generarLicenciaVitalicia() throws ParseException { + ActivationKey key = new ActivationKey(); + key.setActivation_code(UUID.randomUUID().toString()); + key.setActive_key(ActiveKey.Yes); + key.setModules("2"); + key.setTipo_key(TipoKey.Lifetime); + + actKeyServ.generarLicenciaVitalicia(key); + + return ResponseEntity.ok(key.getActivation_code()); + + } + +} diff --git a/src/main/java/com/crov/crovWSTotal/EncriptadorAES.java b/src/main/java/com/crov/crovWSTotal/EncriptadorAES.java new file mode 100644 index 0000000..b6180b5 --- /dev/null +++ b/src/main/java/com/crov/crovWSTotal/EncriptadorAES.java @@ -0,0 +1,74 @@ +package com.crov.crovWSTotal; + +import java.security.spec.KeySpec; +import java.util.Base64; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; + +public class EncriptadorAES { + + // Claves para encryotar y desencriptar las claves + private static final String key = "08wR?!5!S6_WO&-v$f#0RUdrEfRoclTh"; + private static final String salt = "huwlzO@a*&t8tr83e$l6hiy#k+vl!0cr"; + private SecretKey secretKeyTemp; + + public EncriptadorAES() { + // Se obtiene la instancia para evitar ataques de fuerza bruta + SecretKeyFactory secretKeyFactory; + KeySpec keySpec; + try { + // HMac y Sha512 para encriptar + secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512"); + // Indica que es encriptacion para password encviandole bites, se mandan las + // iteraciones y la longitud de cadena + keySpec = new PBEKeySpec(key.toCharArray(), salt.getBytes(), 65536, 256); + // Genera la lalve a partir de las especificaciones. + secretKeyTemp = secretKeyFactory.generateSecret(keySpec); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + // Metodo de encriptación + public String getAES(String data) { + byte[] iv = new byte[16]; + try { + // Parametro de inicialización + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + // LLave temporal generada en AES + SecretKeySpec secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), "AES"); + // Cifrado por bloques, para definir el tamaño de bloque + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + // Inicialización de Cipher para encriptar, se le manda los parametros de + // inicialización. + cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); + // Se codififica a String y retorna un String codificacdo + return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes("UTF-8"))); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + // Metodo de desincriptación + public String getAESDecrypt(String data) { + byte[] iv = new byte[16]; + try { + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + SecretKeySpec secretKey = new SecretKeySpec(secretKeyTemp.getEncoded(), "AES"); + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + // Se decofifica el cipher, retornando el valor del string + cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); + return new String(cipher.doFinal(Base64.getDecoder().decode(data))); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/com/crov/crovWSTotal/Utilerias.java b/src/main/java/com/crov/crovWSTotal/Utilerias.java new file mode 100644 index 0000000..31a9d70 --- /dev/null +++ b/src/main/java/com/crov/crovWSTotal/Utilerias.java @@ -0,0 +1,32 @@ +package com.crov.crovWSTotal; + +import java.util.Calendar; +import java.util.Date; + +public class Utilerias { + + public Date sumarDiasAFecha(Date fecha, int dias){ + if (dias==0) return fecha; + Calendar calendar = Calendar.getInstance(); + calendar.setTime(fecha); + calendar.add(Calendar.DAY_OF_YEAR, dias); + return calendar.getTime(); + } + + public Date restarSeisHorasAlDia(Date fecha) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(fecha); + calendar.add(Calendar.HOUR, -6); + return calendar.getTime(); + + } + + public Date restarHorasAlDia(Date fecha, int horas) { + if (horas == 0) return fecha; + Calendar calendar = Calendar.getInstance(); + calendar.setTime(fecha); + calendar.add(Calendar.HOUR, horas); + return calendar.getTime(); + + } +} diff --git a/src/main/java/com/crov/crovWSTotal/config/SecurityConfig.java b/src/main/java/com/crov/crovWSTotal/config/SecurityConfig.java deleted file mode 100644 index f9a1487..0000000 --- a/src/main/java/com/crov/crovWSTotal/config/SecurityConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.crov.crovWSTotal.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.core.userdetails.User; - -@Configuration -@Order(1) -public class SecurityConfig { - - @Bean - public InMemoryUserDetailsManager userDetailsService() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("admin") - .password("Saladeespera2") - .roles("USER") - .build(); - return new InMemoryUserDetailsManager(user); - } - - @Bean - public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - .csrf().disable() - .authorizeHttpRequests(auth -> auth - .anyRequest().authenticated() - ) - .httpBasic(); // Configuración de autenticación básica - - return http.build(); - } -} diff --git a/src/main/java/com/crov/models/ActivationKey.java b/src/main/java/com/crov/models/ActivationKey.java new file mode 100644 index 0000000..2bf0d43 --- /dev/null +++ b/src/main/java/com/crov/models/ActivationKey.java @@ -0,0 +1,117 @@ +package com.crov.models; + +import java.util.UUID; + +import org.springframework.lang.NonNull; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.PrePersist; +import jakarta.persistence.Table; + + +@Entity +@Table (name ="ACTIVATION_KEY") +public class ActivationKey { + + @Id + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String id; + @PrePersist + public void prePersist() { + if (id == null || id.isEmpty()) { + id = UUID.randomUUID().toString(); + } + } + @NonNull + @Column(name = "activation_code", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String activation_code; + @NonNull + @Enumerated(value = EnumType.STRING) + private TipoKey tipo_key; + @NonNull + @Enumerated(value = EnumType.STRING) + private ActiveKey active_key; + + private String modules; + + private Integer activationTime; + + public enum TipoKey{ + Lifetime, + Proof, + Rent, + ProductosAbarrotes, + ProductosFarmacia + } + + public enum ActiveKey{ + Yes, + No + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getActivation_code() { + return activation_code; + } + + public void setActivation_code(String activation_code) { + this.activation_code = activation_code; + } + + public TipoKey getTipo_key() { + return tipo_key; + } + + public void setTipo_key(TipoKey tipo_key) { + this.tipo_key = tipo_key; + } + + public ActiveKey getActive_key() { + return active_key; + } + + public void setActive_key(ActiveKey active_key) { + this.active_key = active_key; + } + + + public String getModules() { + return modules; + } + + public void setModules(String modules) { + this.modules = modules; + } + + + + public Integer getActivationTime() { + return activationTime; + } + + public void setActivationTime(Integer activationTime) { + this.activationTime = activationTime; + } + + public ActivationKey(String id) { + this.id = id; + } + public ActivationKey () { + + } + + + +} diff --git a/src/main/java/com/crov/models/Empresa.java b/src/main/java/com/crov/models/Empresa.java new file mode 100644 index 0000000..7fc9d57 --- /dev/null +++ b/src/main/java/com/crov/models/Empresa.java @@ -0,0 +1,48 @@ +package com.crov.models; + +import java.util.UUID; + + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name ="empresa") +public class Empresa { + + @Id + @GeneratedValue + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private UUID id; + + @Column(name = "token", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private UUID token; + + @Column(name="nombre") + private String nombre; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getNombre() { + return nombre; + } + public void setNombre(String nombre) { + this.nombre = nombre; + } + public UUID getToken() { + return token; + } + public void setToken(UUID token) { + this.token = token; + } + + +} diff --git a/src/main/java/com/crov/models/EmpresaUser.java b/src/main/java/com/crov/models/EmpresaUser.java new file mode 100644 index 0000000..16dd2c6 --- /dev/null +++ b/src/main/java/com/crov/models/EmpresaUser.java @@ -0,0 +1,109 @@ +package com.crov.models; + +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; + +@Entity +@Table (name ="EMPRESA_USER") +public class EmpresaUser { + + @Id + @GeneratedValue + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private UUID id; + + @Column(name="id_software_model") + private String softwareModel; + + @Column(name ="user_name") + private String userName; + + @Column(name="password") + private String password; + + @Enumerated(EnumType.STRING) + @Column(name ="active") + private Active active; + + @ManyToOne + @JoinColumn(name = "id_empresa") + private Empresa empresaModel; + + @Enumerated(EnumType.STRING) + @Column(name ="tipo_cliente") + private TipoCliente tipoCliente; + + @Column(name="no_backups") + private Integer noBackups; + + public enum Active{ + ENABLED, DISABLED + } + + public enum TipoCliente{ + MOVIL, RESPALDO, AMBOS, NADA + } + + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getSoftwareModel() { + return softwareModel; + } + + public void setSoftwareModel(String softwareModel) { + this.softwareModel = softwareModel; + } + + public String getUserName() { + return userName; + } + public void setUserName(String userName) { + this.userName = userName; + } + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + public Active getActive() { + return active; + } + public void setActive(Active active) { + this.active = active; + } + public Empresa getEmpresaModel() { + return empresaModel; + } + public void setEmpresaModel(Empresa empresaModel) { + this.empresaModel = empresaModel; + } + public TipoCliente getTipoCliente() { + return tipoCliente==null?TipoCliente.NADA:tipoCliente; + } + public void setTipoCliente(TipoCliente tipoCliente) { + this.tipoCliente = tipoCliente; + } + public Integer getNoBackups() { + return noBackups; + } + public void setNoBackups(Integer noBackups) { + this.noBackups = noBackups; + } + +} diff --git a/src/main/java/com/crov/models/PersonSoftware.java b/src/main/java/com/crov/models/PersonSoftware.java new file mode 100644 index 0000000..06b28a1 --- /dev/null +++ b/src/main/java/com/crov/models/PersonSoftware.java @@ -0,0 +1,183 @@ +package com.crov.models; + +import java.util.Date; +import java.util.UUID; + +import org.springframework.lang.NonNull; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Id; +import jakarta.persistence.PrePersist; +import jakarta.persistence.Table; + +@Entity +@Table (name ="PERSON_SOFTWARE") +public class PersonSoftware { + + @Id + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String id; + + @PrePersist + public void prePersist() { + if (id == null || id.isEmpty()) { + id = UUID.randomUUID().toString(); + } + } + @NonNull + private String first_name; + + private String second_name; + + private String last_name; + + private String middle_name; + + private String mail; + + + private Date birthdate; + + private String curp; + + private String rfc; + + private String phone; + + @Column(name="active", nullable = false, length = 8 ) + @Enumerated(value = EnumType.STRING) + private ActivePerson active; + + @Column(name="black_list", nullable = false, length = 8 ) + @Enumerated(value = EnumType.STRING) + private BlackListPerson black_list; + + private String black_list_description; + + @JsonFormat(pattern="yyyy-MM-dd") + private Date created_on; + + public PersonSoftware(String id, String first_name, String second_name, String last_name, String middle_name, + String mail, Date birthdate, String curp, String rfc, String phone, ActivePerson active, BlackListPerson black_list, + String black_list_description, Date created_on) { + this.id = id; + this.first_name = first_name; + this.second_name = second_name; + this.last_name = last_name; + this.middle_name = middle_name; + this.mail = mail; + this.birthdate = birthdate; + this.curp = curp; + this.rfc = rfc; + this.phone = phone; + this.active = active; + this.black_list = black_list; + this.black_list_description = black_list_description; + this.created_on = created_on; + } + public PersonSoftware() { + + } + public PersonSoftware(String id) { + this.id = id; + } + public enum ActivePerson{ + Active, + Inactive + } + public enum BlackListPerson{ + Enabled, + Disabled + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getFirst_name() { + return first_name; + } + public void setFirst_name(String first_name) { + this.first_name = first_name; + } + public String getSecond_name() { + return second_name; + } + public void setSecond_name(String second_name) { + this.second_name = second_name; + } + public String getLast_name() { + return last_name; + } + public void setLast_name(String last_name) { + this.last_name = last_name; + } + public String getMiddle_name() { + return middle_name; + } + public void setMiddle_name(String middle_name) { + this.middle_name = middle_name; + } + public String getMail() { + return mail; + } + public void setMail(String mail) { + this.mail = mail; + } + public Date getBirthdate() { + return birthdate; + } + public void setBirthdate(Date birthdate) { + this.birthdate = birthdate; + } + public String getCurp() { + return curp; + } + public void setCurp(String curp) { + this.curp = curp; + } + public String getRfc() { + return rfc; + } + public void setRfc(String rfc) { + this.rfc = rfc; + } + public String getPhone() { + return phone; + } + public void setPhone(String phone) { + this.phone = phone; + } + public ActivePerson getActivePerson() { + return active; + } + public void setActivePerson(ActivePerson active) { + this.active = active; + } + public BlackListPerson getBlack_listPerson() { + return black_list; + } + public void setBlack_listPerson(BlackListPerson black_list) { + this.black_list = black_list; + } + public String getBlack_list_description() { + return black_list_description; + } + public void setBlack_list_description(String black_list_description) { + this.black_list_description = black_list_description; + } + public Date getCreated_on() { + return created_on; + } + public void setCreated_on(Date created_on) { + this.created_on = created_on; + } + + +} diff --git a/src/main/java/com/crov/models/Software.java b/src/main/java/com/crov/models/Software.java new file mode 100644 index 0000000..669dcaa --- /dev/null +++ b/src/main/java/com/crov/models/Software.java @@ -0,0 +1,155 @@ +package com.crov.models; + +import java.util.Date; +import java.util.UUID; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.Id; +import jakarta.persistence.PrePersist; +import jakarta.persistence.Table; + +@Entity +@Table(name = "CUSTOMER_LICENSE_BY_PRODUCT") +public class Software { + + @Id + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String id; + + @PrePersist + public void prePersist() { + if (id == null || id.isEmpty()) { + id = UUID.randomUUID().toString(); + } + } + + private Float payment; + + @Column(unique = true, nullable = false) + private String mac; + + @Column(name = "activation_key", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String activation_key; + + private String token_product; + + @Column(name ="id_software_product") + private String id_software_product; + + @Column(name = "id_customer", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String id_customer; + + @Column(name="active", nullable = false, length = 8 ) + @Enumerated(value = EnumType.STRING) + private ActiveSofware active; + + public enum ActiveSofware{ + Active, + Inactive + } + + @JsonFormat(pattern="yyyy-MM-dd") + private Date expiration_date; + + @JsonFormat(pattern="yyyy-MM-dd") + private Date created_on; + + private Integer paid; + + public Software(String id, Float payment, String mac, String activation_key, String token_product, + String id_software_product, String id_customer, ActiveSofware active, Date expiration_date, Date created_on, Integer paid) { + this.id = id; + this.payment = payment; + this.mac = mac; + this.activation_key = activation_key; + this.token_product = token_product; + this.id_software_product = id_software_product; + this.id_customer = id_customer; + this.active = active; + this.expiration_date = expiration_date; + this.created_on = created_on; + this.paid = paid; + } + + public Software() { + + } + + public Software(String activation_key) { + this.activation_key = activation_key; + } + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public Float getPayment() { + return payment; + } + public void setPayment(Float payment) { + this.payment = payment; + } + public String getMac() { + return mac; + } + public void setMac(String mac) { + this.mac = mac; + } + + public String getActivation_key() { + return activation_key; + } + public void setActivation_key(String activation_key) { + this.activation_key = activation_key; + } + public String getId_software_product() { + return id_software_product; + } + public void setId_software_product(String id_software_product) { + this.id_software_product = id_software_product; + } + public String getId_customer() { + return id_customer; + } + public void setId_customer(String id_customer) { + this.id_customer = id_customer; + } + public ActiveSofware getActiveSofware() { + return active; + } + public void setActiveSofware(ActiveSofware active) { + this.active = active; + } + public Date getExpiration_date() { + return expiration_date; + } + public void setExpiration_date(Date expiration_date) { + this.expiration_date = expiration_date; + } + public Date getCreated_on() { + return created_on; + } + public void setCreated_on(Date created_on) { + this.created_on = created_on; + } + public String getToken_product() { + return token_product; + } + public void setToken_product(String token_product) { + this.token_product = token_product; + } + public Integer getPaid() { + return paid; + } + public void setPaid(Integer paid) { + this.paid = paid; + } + +} diff --git a/src/main/java/com/crov/models/Usuario.java b/src/main/java/com/crov/models/Usuario.java index 4e0ead2..6662953 100644 --- a/src/main/java/com/crov/models/Usuario.java +++ b/src/main/java/com/crov/models/Usuario.java @@ -18,7 +18,7 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @Entity -@Table(name = "usuario") +@Table(name = "usuarioCROV") public class Usuario { @Id diff --git a/src/main/java/com/crov/models/UsuarioModel.java b/src/main/java/com/crov/models/UsuarioModel.java new file mode 100644 index 0000000..307610b --- /dev/null +++ b/src/main/java/com/crov/models/UsuarioModel.java @@ -0,0 +1,152 @@ +package com.crov.models; + +import java.util.Date; +import java.util.UUID; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.PrePersist; +import jakarta.persistence.Table; +import jakarta.persistence.Temporal; +import jakarta.persistence.TemporalType; + + +@Entity +@Table(name = "USUARIO") +public class UsuarioModel { + + @Id + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "VARCHAR(255)") + private String id; + @PrePersist + public void prePersist() { + if (id == null || id.isEmpty()) { + id = UUID.randomUUID().toString(); + } + } + @Column(name="id_punto_venta") + private Integer idPuntoVenta; + @Column(name ="login") + private String login; + @Column(name="nombre") + private String nombre; + @Column(name="apellidos") + private String apellidos; + @Column(name="calular") + private String celular; + @Column(name="email") + private String email; + @Column(name="tipoCargo") + private String tipoCargo; + @Column(name="descripcion") + private String descipcion; + @Column(name="activo") + private Integer activo; + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "fec_registro", length = 19) + private Date fec_registro; + @ManyToOne + @JoinColumn(name = "id_empresa") + private EmpresaUser empresaUserModel; + + public UsuarioModel() { + } + public UsuarioModel(String id, Integer idPuntoVenta, String login, String nombre, String apellidos, String celular, + String email, String tipoCargo, String descipcion, Integer activo, Date fec_registro, + EmpresaUser empresaModel) { + super(); + this.id = id; + this.idPuntoVenta = idPuntoVenta; + this.login = login; + this.nombre = nombre; + this.apellidos = apellidos; + this.celular = celular; + this.email = email; + this.tipoCargo = tipoCargo; + this.descipcion = descipcion; + this.activo = activo; + this.fec_registro = fec_registro; + this.empresaUserModel = empresaModel; + } + public UsuarioModel(String id, Integer idPuntoVenta) { + super(); + this.id = id; + this.idPuntoVenta = idPuntoVenta; + } + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public Integer getIdPuntoVenta() { + return idPuntoVenta; + } + public void setIdPuntoVenta(Integer idPuntoVenta) { + this.idPuntoVenta = idPuntoVenta; + } + public String getLogin() { + return login; + } + public void setLogin(String login) { + this.login = login; + } + public String getNombre() { + return nombre; + } + public void setNombre(String nombre) { + this.nombre = nombre; + } + public String getApellidos() { + return apellidos; + } + public void setApellidos(String apellidos) { + this.apellidos = apellidos; + } + public String getCelular() { + return celular; + } + public void setCelular(String celular) { + this.celular = celular; + } + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + public String getTipoCargo() { + return tipoCargo; + } + public void setTipoCargo(String tipoCargo) { + this.tipoCargo = tipoCargo; + } + public String getDescipcion() { + return descipcion; + } + public void setDescipcion(String descipcion) { + this.descipcion = descipcion; + } + public Integer getActivo() { + return activo; + } + public void setActivo(Integer activo) { + this.activo = activo; + } + public Date getFec_registro() { + return fec_registro; + } + public void setFec_registro(Date fec_registro) { + this.fec_registro = fec_registro; + } + public EmpresaUser getEmpresaUserModel() { + return empresaUserModel; + } + public void setEmpresaUserModel(EmpresaUser empresaUserModel) { + this.empresaUserModel = empresaUserModel; + } + +} diff --git a/src/main/java/com/crov/repositories/ActivationKeyRepository.java b/src/main/java/com/crov/repositories/ActivationKeyRepository.java new file mode 100644 index 0000000..c8ef33f --- /dev/null +++ b/src/main/java/com/crov/repositories/ActivationKeyRepository.java @@ -0,0 +1,33 @@ +package com.crov.repositories; + +import java.util.UUID; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import com.crov.models.ActivationKey; + +@Repository +public interface ActivationKeyRepository extends JpaRepository{ + + @Query(value="SELECT IF(EXISTS(SELECT ac.activation_code, ac.active_key " + + "FROM activation_key ac WHERE ac.activation_code =:actCode AND active_key = 'Yes'),1,0)AS resul", nativeQuery=true) + int revisarLicenciaActivaSinUso(@Param ("actCode")String activation_code ); + + @Query(value="SELECT IF(EXISTS(SELECT ac.activation_code, ac.active_key " + + "FROM activation_key ac WHERE ac.activation_code =:actCode AND active_key = 'Yes' " + + "AND tipo_key ='Lifetime'),1,0)AS resul", nativeQuery=true) + int checkActiveCodeAndVitalicieKey(@Param ("actCode")String activation_code ); + + @Transactional + @Modifying + @Query(value="UPDATE activation_key ac SET ac.active_key = 'No' WHERE ac.id =:id_key" ,nativeQuery=true) + void updateActKeyToNo(@Param ("id_key") String id_key); + + @Query(value="SELECT ac.* FROM activation_key ac WHERE ac.activation_code =:acti_cod" ,nativeQuery=true) + ActivationKey getActivationCodePorCodigoActivacion(@Param ("acti_cod") String activation_code); +} diff --git a/src/main/java/com/crov/repositories/PersonSoftwareRepository.java b/src/main/java/com/crov/repositories/PersonSoftwareRepository.java new file mode 100644 index 0000000..580d9c8 --- /dev/null +++ b/src/main/java/com/crov/repositories/PersonSoftwareRepository.java @@ -0,0 +1,13 @@ +package com.crov.repositories; + +import java.util.UUID; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import com.crov.models.PersonSoftware; + +@Repository +public interface PersonSoftwareRepository extends CrudRepository{ + +} diff --git a/src/main/java/com/crov/repositories/SoftwareRepository.java b/src/main/java/com/crov/repositories/SoftwareRepository.java new file mode 100644 index 0000000..797874b --- /dev/null +++ b/src/main/java/com/crov/repositories/SoftwareRepository.java @@ -0,0 +1,21 @@ +package com.crov.repositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import com.crov.models.Software; + +@Repository +public interface SoftwareRepository extends JpaRepository{ + + @Query(value="SELECT IF(EXISTS(SELECT cl.mac FROM customer_license_by_product cl WHERE cl.mac =:vaMac ),1,0 )", nativeQuery=true) + int revisarMacExistePreviamente(@Param ("vaMac")String valueMac ); + + @Query(value="SELECT cl.* FROM customer_license_by_product cl WHERE cl.mac =:data_mac" ,nativeQuery=true) + Software getSoftwareByMac(@Param ("data_mac") String mac); + + @Query(value="SELECT cl.id FROM customer_license_by_product cl WHERE cl.token_product =:token" ,nativeQuery=true) + String getSoftwareByToken(@Param ("token") String mac); +} diff --git a/src/main/java/com/crov/requests/PersonSoftwareRequest.java b/src/main/java/com/crov/requests/PersonSoftwareRequest.java new file mode 100644 index 0000000..2ff7cf5 --- /dev/null +++ b/src/main/java/com/crov/requests/PersonSoftwareRequest.java @@ -0,0 +1,85 @@ +package com.crov.requests; + +import java.util.UUID; + +public class PersonSoftwareRequest { + private String first_name; + private String second_name; + private String last_name; + private String middle_name; + private String mail; + private String birthdate; + private String phone; + private String activation_key; + private String mac; + private String id_product; + private Float payment; + + public String getFirst_name() { + return first_name; + } + public void setFirst_name(String first_name) { + this.first_name = first_name; + } + public String getSecond_name() { + return second_name; + } + public void setSecond_name(String second_name) { + this.second_name = second_name; + } + public String getLast_name() { + return last_name; + } + public void setLast_name(String last_name) { + this.last_name = last_name; + } + public String getMiddle_name() { + return middle_name; + } + public void setMiddle_name(String middle_name) { + this.middle_name = middle_name; + } + public String getMail() { + return mail; + } + public void setMail(String mail) { + this.mail = mail; + } + public String getBirthdate() { + return birthdate; + } + public void setBirthdate(String birthdate) { + this.birthdate = birthdate; + } + public String getPhone() { + return phone; + } + public void setPhone(String phone) { + this.phone = phone; + } + public String getActivation_key() { + return activation_key; + } + public void setActivation_key(String activation_key) { + this.activation_key = activation_key; + } + public String getMac() { + return mac; + } + public void setMac(String mac) { + this.mac = mac; + } + public String getId_product() { + return id_product; + } + public void setId_product(String id_product) { + this.id_product = id_product; + } + public Float getPayment() { + return payment; + } + public void setPayment(Float payment) { + this.payment = payment; + } + +} diff --git a/src/main/java/com/crov/services/ActivationKeyService.java b/src/main/java/com/crov/services/ActivationKeyService.java new file mode 100644 index 0000000..01cac12 --- /dev/null +++ b/src/main/java/com/crov/services/ActivationKeyService.java @@ -0,0 +1,35 @@ +package com.crov.services; + +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.crov.models.ActivationKey; +import com.crov.repositories.ActivationKeyRepository; + + +@Service +public class ActivationKeyService { + + @Autowired + ActivationKeyRepository actiKeyRepo; + + public int revisarLicenciaActivaSinUso (String ActivationCode) { + return actiKeyRepo.revisarLicenciaActivaSinUso(ActivationCode); + } + + public ActivationKey getActivationCodePorCodigoActivacion(String actKey) { + + return actiKeyRepo.getActivationCodePorCodigoActivacion(actKey); + } + + public void actualizarActiveKey(String id_key) { + actiKeyRepo.updateActKeyToNo(id_key); + } + + public void generarLicenciaVitalicia(ActivationKey ak) { + actiKeyRepo.save(ak); + } + +} diff --git a/src/main/java/com/crov/services/AuthService.java b/src/main/java/com/crov/services/AuthService.java new file mode 100644 index 0000000..4ca2ac3 --- /dev/null +++ b/src/main/java/com/crov/services/AuthService.java @@ -0,0 +1,23 @@ +package com.crov.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class AuthService { + + private static final String PASSWORD = "Saladeespera2_?01092022"; + private static final String USERNAME = "CROVadminPV"; + @Autowired + private JwtTokenUtil jwtTokenUtil; + + public String login(String username, String password) { + // Aquí validas al usuario con tus reglas de negocio + if (username.equals(USERNAME) && password.equals(PASSWORD)) { + // Generar token si la autenticación es exitosa + return jwtTokenUtil.generateToken(username); + } else { + throw new RuntimeException("Credenciales inválidas"); + } + } +} diff --git a/src/main/java/com/crov/services/JwtRequestFilter.java b/src/main/java/com/crov/services/JwtRequestFilter.java new file mode 100644 index 0000000..38abcda --- /dev/null +++ b/src/main/java/com/crov/services/JwtRequestFilter.java @@ -0,0 +1,60 @@ +package com.crov.services; +import java.io.IOException; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Component +public class JwtRequestFilter extends OncePerRequestFilter { + + @Value("${jwt.secret}") + private String secret; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws IOException, ServletException { + + // Obtener el token del header "Authorization" + final String authorizationHeader = request.getHeader("Authorization"); + + String username = null; + String jwt = null; + + // Validar el formato "Bearer " + if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) { + jwt = authorizationHeader.substring(7); // Elimina el prefijo "Bearer " + try { + // Extraer el usuario del token + Claims claims = Jwts.parser() + .setSigningKey(secret.getBytes()) + .parseClaimsJws(jwt) + .getBody(); + username = claims.getSubject(); + } catch (Exception e) { + System.out.println("Token inválido o expirado: " + e.getMessage()); + } + } + + // Configurar el contexto de seguridad si el token es válido + if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + username, null, null); // Agrega roles/permisos si los tienes en tu token + authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authenticationToken); + } + + chain.doFilter(request, response); + } +} + diff --git a/src/main/java/com/crov/services/JwtTokenUtil.java b/src/main/java/com/crov/services/JwtTokenUtil.java new file mode 100644 index 0000000..3f4c2cd --- /dev/null +++ b/src/main/java/com/crov/services/JwtTokenUtil.java @@ -0,0 +1,34 @@ +package com.crov.services; + +import java.security.Key; +import java.util.Date; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; + +@Component +public class JwtTokenUtil { + + @Value("${jwt.secret}") + private String secret; + + @Value("${jwt.expiration}") + private long expirationTime; + + // Generar el token + public String generateToken(String username) { + byte[] keyBytes = secret.getBytes(); // Convierte la clave secreta en bytes + Key signingKey = Keys.hmacShaKeyFor(keyBytes); // Crea un objeto de clave segura + + return Jwts.builder() + .setSubject(username) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + expirationTime)) + .signWith(signingKey) // Firma con la clave segura + .compact(); + } +} diff --git a/src/main/java/com/crov/services/PersonSoftwareService.java b/src/main/java/com/crov/services/PersonSoftwareService.java new file mode 100644 index 0000000..133801c --- /dev/null +++ b/src/main/java/com/crov/services/PersonSoftwareService.java @@ -0,0 +1,19 @@ +package com.crov.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.crov.models.PersonSoftware; +import com.crov.repositories.PersonSoftwareRepository; + +@Service +public class PersonSoftwareService { + + @Autowired + PersonSoftwareRepository personRepo; + + public PersonSoftware savePerson(PersonSoftware person) { + return personRepo.save(person); + + } +} diff --git a/src/main/java/com/crov/services/SecurityConfig.java b/src/main/java/com/crov/services/SecurityConfig.java new file mode 100644 index 0000000..bf4693b --- /dev/null +++ b/src/main/java/com/crov/services/SecurityConfig.java @@ -0,0 +1,45 @@ +package com.crov.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.provisioning.InMemoryUserDetailsManager; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.User; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Autowired + private JwtRequestFilter jwtRequestFilter; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf().disable() // Deshabilita CSRF (opcional) + .authorizeHttpRequests() + .requestMatchers("/api/auth/token").permitAll() // Permite el acceso al endpoint de login + .anyRequest().authenticated() // Protege todos los demás endpoints + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // Sin sesiones + + // Agrega el filtro JWT antes del filtro predeterminado + http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { + return configuration.getAuthenticationManager(); + } +} diff --git a/src/main/java/com/crov/services/SoftwareService.java b/src/main/java/com/crov/services/SoftwareService.java new file mode 100644 index 0000000..217ba45 --- /dev/null +++ b/src/main/java/com/crov/services/SoftwareService.java @@ -0,0 +1,31 @@ +package com.crov.services; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.crov.models.Software; +import com.crov.repositories.SoftwareRepository; + +@Service +public class SoftwareService { + + @Autowired + SoftwareRepository softwareRepo; + + public int revisarMacExistePreviamente (String valueMac) { + + return softwareRepo.revisarMacExistePreviamente(valueMac); + } + + public Software save(Software software) { + return softwareRepo.save(software); + } + + public Software getSofwareByMac(String mac) { + return softwareRepo.getSoftwareByMac(mac); + } + + public String getIdSoftwareByToken(String token) { + return softwareRepo.getSoftwareByToken(token); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index ce08192..967c8b5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,5 @@ spring.mvc.pathmatch.matching-strategy=ant-path-matcher -spring.datasource.url=jdbc:mysql://localhost:3306/crov_total?createDatabaseIfNotExist=true +spring.datasource.url=jdbc:mysql://localhost:3306/crov?createDatabaseIfNotExist=true spring.datasource.username=root spring.datasource.password=root spring.jpa.hibernate.ddl-auto=update @@ -8,4 +8,6 @@ server.servlet.context-path=/ springdoc.api-docs.path=/v3/api-docs springdoc.swagger-ui.path=/swagger-ui.html server.port=8080 -swagger.ui.base.url=/ \ No newline at end of file +swagger.ui.base.url=/ +jwt.secret=OscarArmandoVargasCardenasBensonBenjaminArceHernandez01092022CROV +jwt.expiration=3600000 \ No newline at end of file