[REPO REFACTOR]: changed to a better git repository structure with branches

This commit is contained in:
2025-11-01 06:22:17 +01:00
parent 786322b6cd
commit 6ab8bccdd8
70 changed files with 4858 additions and 0 deletions

2
BYODSEC/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/bin/
/target/

54
BYODSEC/log/client.log Normal file
View File

@@ -0,0 +1,54 @@
2025-10-20 03:41:45 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 03:41:50 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: smt4497 -> Servidor
2025-10-20 18:03:23 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:03:34 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'alvgulveg' ha iniciado sesión correctamente.
2025-10-20 18:03:38 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: smt4497 -> Servidor
2025-10-20 18:03:40 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: alvgulveg -> Servidor
2025-10-20 18:04:04 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'ricolinad' ha iniciado sesión correctamente.
2025-10-20 18:04:15 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: ricolinad -> Servidor
2025-10-20 18:04:36 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'ricolinad' ha cerrado sesión correctamente.
2025-10-20 18:05:48 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:09:21 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:10:12 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:12:49 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' registrado correctamente.
2025-10-20 18:12:54 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:12:57 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' ha cerrado sesión correctamente.
2025-10-20 18:14:49 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:14:57 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'alvgulveg' ha iniciado sesión correctamente.
2025-10-20 18:15:04 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:15:08 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: smt4497 -> Servidor
2025-10-20 18:15:09 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: alvgulveg -> Servidor
2025-10-20 18:15:14 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: psancas -> Servidor
2025-10-20 18:16:28 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: psancas -> Servidor
2025-10-20 18:17:38 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'ricolinad' ha iniciado sesión correctamente.
2025-10-20 18:17:43 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: ricolinad -> Servidor
2025-10-20 18:18:16 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:20:11 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:20:24 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:24:49 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 18:25:09 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'smt4497': Ha ocurrido un error inesperado.
2025-10-20 18:25:20 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'smt4497': Ha ocurrido un error inesperado.
2025-10-20 18:25:23 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'smt4497': Ha ocurrido un error inesperado.
2025-10-20 18:25:47 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'smt4497' ha cerrado sesión correctamente.
2025-10-20 18:32:42 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:32:49 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'psancas': Ha ocurrido un error inesperado.
2025-10-20 18:32:56 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' ha cerrado sesión correctamente.
2025-10-20 18:35:05 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:35:07 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'psancas': Ha ocurrido un error inesperado.
2025-10-20 18:35:22 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' ha cerrado sesión correctamente.
2025-10-20 18:35:24 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:35:26 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' ha cerrado sesión correctamente.
2025-10-20 18:37:28 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:37:31 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'psancas': Ha ocurrido un error inesperado.
2025-10-20 18:37:40 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'psancas': Ha ocurrido un error inesperado.
2025-10-20 18:37:44 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' ha cerrado sesión correctamente.
2025-10-20 18:39:08 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:39:21 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'psancas': Ha ocurrido un error inesperado.
2025-10-20 18:41:15 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 18:41:25 WARN n.miarma.byodsec.client.ClientSocket - Intento de login fallido para 'psancas': Ha ocurrido un error inesperado.
2025-10-20 22:42:26 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ha iniciado sesión correctamente.
2025-10-20 22:42:36 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'smt4497' ya tiene una sesión activa.
2025-10-20 22:43:17 INFO n.miarma.byodsec.client.ClientSocket - El usuario 'psancas' ha iniciado sesión correctamente.
2025-10-20 22:43:20 INFO n.miarma.byodsec.client.ClientSocket - Mensaje enviado: smt4497 -> Servidor
2025-10-20 22:43:24 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'psancas' ha cerrado sesión correctamente.
2025-10-20 22:43:26 INFO n.miarma.byodsec.client.ClientSocket - Usuario 'smt4497' ha cerrado sesión correctamente.

575
BYODSEC/log/server.log Normal file
View File

@@ -0,0 +1,575 @@
2025-10-20 03:41:45 [main] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:58152
2025-10-20 03:41:45 [main] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 03:41:50 [main] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:35314
2025-10-20 03:41:50 [main] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de smt4497 a Servidor | hola
2025-10-20 03:42:15 [main] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:45928
2025-10-20 03:42:15 [main] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 03:42:15 [main] ERROR n.miarma.byodsec.server.RemoteSocket - Fallo procesando solicitud
jakarta.persistence.NonUniqueResultException: Query did not return a unique result: 2 results were returned
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:114)
at org.hibernate.query.spi.AbstractSelectionQuery.getSingleResult(AbstractSelectionQuery.java:291)
at net.miarma.byodsec.common.db.dao.SessionDAO.getByUserId(SessionDAO.java:10)
at net.miarma.byodsec.server.RemoteSocket.main(RemoteSocket.java:126)
Caused by: org.hibernate.NonUniqueResultException: Query did not return a unique result: 2 results were returned
at org.hibernate.query.spi.AbstractSelectionQuery.uniqueElement(AbstractSelectionQuery.java:305)
at org.hibernate.query.spi.AbstractSelectionQuery.getSingleResult(AbstractSelectionQuery.java:288)
... 2 common frames omitted
2025-10-20 18:03:22 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:36678
2025-10-20 18:03:22 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:03:33 [pool-3-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:50342
2025-10-20 18:03:33 [pool-3-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para alvgulveg
2025-10-20 18:03:37 [pool-4-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:60208
2025-10-20 18:03:37 [pool-4-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de smt4497 a Servidor | illo que
2025-10-20 18:03:40 [pool-5-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:60218
2025-10-20 18:03:40 [pool-5-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de alvgulveg a Servidor | yoyoyo
2025-10-20 18:04:04 [pool-6-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:54898
2025-10-20 18:04:04 [pool-6-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para ricolinad
2025-10-20 18:04:15 [pool-7-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:35428
2025-10-20 18:04:15 [pool-7-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de ricolinad a Servidor | we are number one
2025-10-20 18:04:33 [pool-8-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:37304
2025-10-20 18:04:33 [pool-8-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:04:35 [pool-9-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:59664
2025-10-20 18:04:35 [pool-9-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para b176f04e-6b8a-4447-948a-af290d3ebb82
2025-10-20 18:04:35 [pool-10-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:59676
2025-10-20 18:04:35 [pool-10-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 85218286-76fc-46af-b3c0-71bb09896531
2025-10-20 18:05:47 [pool-11-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:47858
2025-10-20 18:05:47 [pool-11-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:05:51 [pool-12-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:47864
2025-10-20 18:05:51 [pool-12-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:09:20 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:55666
2025-10-20 18:09:20 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:09:27 [pool-3-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:41602
2025-10-20 18:09:27 [pool-3-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:10:12 [pool-4-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:46782
2025-10-20 18:10:12 [pool-4-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:10:26 [pool-5-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:51828
2025-10-20 18:10:26 [pool-5-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:12:48 [pool-6-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34644
2025-10-20 18:12:48 [pool-6-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando REGISTER para psancas
2025-10-20 18:12:54 [pool-7-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34658
2025-10-20 18:12:54 [pool-7-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:12:57 [pool-8-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:56042
2025-10-20 18:12:57 [pool-8-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 585d98f3-5951-40d6-8d35-f32b65d9d43e
2025-10-20 18:14:48 [pool-9-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:39960
2025-10-20 18:14:48 [pool-9-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:14:56 [pool-10-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:60056
2025-10-20 18:14:57 [pool-10-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para alvgulveg
2025-10-20 18:15:03 [pool-11-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:60068
2025-10-20 18:15:03 [pool-11-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:15:07 [pool-12-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34964
2025-10-20 18:15:07 [pool-12-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de smt4497 a Servidor | dsadasdas
2025-10-20 18:15:09 [pool-13-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34978
2025-10-20 18:15:09 [pool-13-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de alvgulveg a Servidor | sfdsgefrgfr
2025-10-20 18:15:14 [pool-14-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34986
2025-10-20 18:15:14 [pool-14-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de psancas a Servidor | odio a la derecha
2025-10-20 18:16:28 [pool-15-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:54852
2025-10-20 18:16:28 [pool-15-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de psancas a Servidor | dictadura
2025-10-20 18:17:38 [pool-16-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:43520
2025-10-20 18:17:38 [pool-16-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para ricolinad
2025-10-20 18:17:43 [pool-17-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:43528
2025-10-20 18:17:43 [pool-17-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de ricolinad a Servidor | we are number one
2025-10-20 18:18:15 [pool-18-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:60346
2025-10-20 18:18:16 [pool-18-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:20:10 [pool-19-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34420
2025-10-20 18:20:10 [pool-19-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:20:23 [pool-20-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:45642
2025-10-20 18:20:23 [pool-20-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:20:45 [pool-21-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:40882
2025-10-20 18:20:45 [pool-21-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:20:55 [pool-22-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:35040
2025-10-20 18:20:55 [pool-22-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:24:49 [pool-23-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:52902
2025-10-20 18:24:49 [pool-23-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:25:08 [pool-24-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:56154
2025-10-20 18:25:08 [pool-24-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:25:09 [pool-24-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:90)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:25:20 [pool-25-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:47508
2025-10-20 18:25:20 [pool-25-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:25:20 [pool-25-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:90)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:25:22 [pool-26-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:47518
2025-10-20 18:25:22 [pool-26-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 18:25:23 [pool-26-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:90)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=195) Duplicate entry 'cb1465ad-6d6d-4784-a2e9-9670a60e778a' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:25:47 [pool-27-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:36890
2025-10-20 18:25:47 [pool-27-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a
2025-10-20 18:32:42 [pool-28-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:47312
2025-10-20 18:32:42 [pool-28-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:32:48 [pool-29-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:39420
2025-10-20 18:32:48 [pool-29-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:32:49 [pool-29-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.client.ClientHandler.run(ClientHandler.java:90)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:32:55 [pool-30-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:47214
2025-10-20 18:32:55 [pool-30-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 585d98f3-5951-40d6-8d35-f32b65d9d43e
2025-10-20 18:35:05 [pool-31-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:36694
2025-10-20 18:35:05 [pool-31-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:35:06 [pool-32-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:36710
2025-10-20 18:35:07 [pool-32-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:35:07 [pool-32-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.client.ClientHandler.run(ClientHandler.java:90)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=195) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:35:22 [pool-33-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:45686
2025-10-20 18:35:22 [pool-33-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 585d98f3-5951-40d6-8d35-f32b65d9d43e
2025-10-20 18:35:24 [pool-34-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:45688
2025-10-20 18:35:24 [pool-34-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:35:26 [pool-35-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:45378
2025-10-20 18:35:26 [pool-35-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 585d98f3-5951-40d6-8d35-f32b65d9d43e
2025-10-20 18:37:27 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:39072
2025-10-20 18:37:27 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:37:31 [pool-3-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:39080
2025-10-20 18:37:31 [pool-3-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:37:31 [pool-3-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:93)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:37:39 [pool-4-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:42422
2025-10-20 18:37:39 [pool-4-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:37:40 [pool-4-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:93)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:37:44 [pool-5-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:42426
2025-10-20 18:37:44 [pool-5-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 585d98f3-5951-40d6-8d35-f32b65d9d43e
2025-10-20 18:39:07 [pool-6-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:42476
2025-10-20 18:39:07 [pool-6-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:39:20 [pool-7-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:52194
2025-10-20 18:39:20 [pool-7-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:39:21 [pool-7-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:93)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 18:41:14 [pool-8-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:49238
2025-10-20 18:41:14 [pool-8-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:41:24 [pool-9-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:49240
2025-10-20 18:41:24 [pool-9-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 18:41:25 [pool-9-thread-1] ERROR n.miarma.byodsec.server.RemoteSocket - Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]]
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:70)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:93)
at net.miarma.byodsec.server.ClientHandler.run(ClientHandler.java:93)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
at java.base/java.lang.Thread.run(Thread.java:1474)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement [(conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'] [insert into sessions (userId,sessionId) values (?,?)]
at org.hibernate.dialect.MariaDBDialect.lambda$buildSQLExceptionConversionDelegate$1(MariaDBDialect.java:379)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:34)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:115)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:193)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.performNonBatchedMutation(AbstractMutationExecutor.java:148)
at org.hibernate.engine.jdbc.mutation.internal.MutationExecutorSingleNonBatched.performNonBatchedOperations(MutationExecutorSingleNonBatched.java:53)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:66)
at org.hibernate.engine.jdbc.mutation.internal.AbstractMutationExecutor.execute(AbstractMutationExecutor.java:55)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.doStaticInserts(InsertCoordinatorStandard.java:191)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.coordinateInsert(InsertCoordinatorStandard.java:129)
at org.hibernate.persister.entity.mutation.InsertCoordinatorStandard.insert(InsertCoordinatorStandard.java:101)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:113)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:646)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:513)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:378)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:140)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1443)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:488)
at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2321)
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2029)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:394)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:167)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commitNoRollbackOnly(JdbcResourceLocalTransactionCoordinatorImpl.java:249)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:243)
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:90)
... 4 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: (conn=241) Duplicate entry '585d98f3-5951-40d6-8d35-f32b65d9d43e' for key 'userId'
at org.mariadb.jdbc.export.ExceptionFactory.createException(ExceptionFactory.java:301)
at org.mariadb.jdbc.export.ExceptionFactory.create(ExceptionFactory.java:386)
at org.mariadb.jdbc.message.ClientMessage.readPacket(ClientMessage.java:187)
at org.mariadb.jdbc.client.impl.StandardClient.readPacket(StandardClient.java:1376)
at org.mariadb.jdbc.client.impl.StandardClient.readResults(StandardClient.java:1315)
at org.mariadb.jdbc.client.impl.StandardClient.readResponse(StandardClient.java:1234)
at org.mariadb.jdbc.client.impl.StandardClient.execute(StandardClient.java:1158)
at org.mariadb.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:91)
at org.mariadb.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:345)
at org.mariadb.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:322)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:190)
... 26 common frames omitted
2025-10-20 22:42:25 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:53230
2025-10-20 22:42:25 [pool-2-thread-1] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 22:42:35 [pool-2-thread-2] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:40972
2025-10-20 22:42:35 [pool-2-thread-2] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para smt4497
2025-10-20 22:43:17 [pool-2-thread-3] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34616
2025-10-20 22:43:17 [pool-2-thread-3] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGIN para psancas
2025-10-20 22:43:20 [pool-2-thread-4] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:34618
2025-10-20 22:43:20 [pool-2-thread-4] INFO n.miarma.byodsec.server.RemoteSocket - Procesando SEND_MESSAGE de smt4497 a Servidor | hola
2025-10-20 22:43:23 [pool-2-thread-5] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:41190
2025-10-20 22:43:23 [pool-2-thread-5] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para 585d98f3-5951-40d6-8d35-f32b65d9d43e
2025-10-20 22:43:26 [pool-2-thread-6] INFO n.miarma.byodsec.server.RemoteSocket - Nueva conexión desde /127.0.0.1:41194
2025-10-20 22:43:26 [pool-2-thread-6] INFO n.miarma.byodsec.server.RemoteSocket - Procesando LOGOUT para cb1465ad-6d6d-4784-a2e9-9670a60e778a

155
BYODSEC/pom.xml Normal file
View File

@@ -0,0 +1,155 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.miarma</groupId>
<artifactId>integridos</artifactId>
<version>1.0.0</version>
<name>net.miarma.integridos.Integridos</name>
<properties>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
</properties>
<dependencies>
<!-- ##### Gson ##### -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.12.1</version>
</dependency>
<!-- ################ -->
<!-- ##### SLF4J + Logback #####-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.13</version>
</dependency>
<!-- ########################## -->
<!-- ##### BASE DE DATOS Y DATA SOURCE ##### -->
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>7.1.1.Final</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.1.0</version>
</dependency>
<!-- ##################################### -->
<!-- ##### JWT Tokens ##### -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.5.0</version>
</dependency>
<!-- ####################### -->
<!-- ##### BCrypt ##### -->
<dependency>
<groupId>org.mindrot</groupId>
<artifactId>jbcrypt</artifactId>
<version>0.4</version>
</dependency>
<!-- ################### -->
<!-- ###################### SWING ############################# -->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>11.4.2</version>
</dependency>
<dependency>
<groupId>com.formdev</groupId>
<artifactId>flatlaf-intellij-themes</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>com.formdev</groupId>
<artifactId>flatlaf</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>com.formdev</groupId>
<artifactId>flatlaf-extras</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>com.github.jiconfont</groupId>
<artifactId>jiconfont</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.github.jiconfont</groupId>
<artifactId>jiconfont-swing</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>com.github.jiconfont</groupId>
<artifactId>jiconfont-font_awesome</artifactId>
<version>4.7.0.1</version>
</dependency>
<dependency>
<groupId>com.github.jiconfont</groupId>
<artifactId>jiconfont-google_material_design_icons</artifactId>
<version>2.2.0.2</version>
</dependency>
<!-- ################################################################# -->
</dependencies>
<build>
<plugins>
<!-- Maven Shade Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>net.miarma.integridos.net.miarma.integridos.Integridos</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,128 @@
package net.miarma.byodsec;
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
import jiconfont.icons.font_awesome.FontAwesome;
import jiconfont.icons.google_material_design_icons.GoogleMaterialDesignIcons;
import jiconfont.swing.IconFontSwing;
import net.miarma.byodsec.common.ConfigManager;
import net.miarma.byodsec.common.db.DBPopulator;
import net.miarma.byodsec.client.ui.MainWindow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
@SuppressWarnings("all")
public class Byodsec {
private static final Logger logger = LoggerFactory.getLogger(Byodsec.class);
private static ConfigManager configManager = ConfigManager.getInstance();
public static void main(String[] args) {
initConfig();
initDB();
initProperties();
initJKS();
initUI();
}
private static void initConfig() {
File configFile = configManager.getConfigFile();
File parentDir = configFile.getParentFile();
if (!parentDir.exists()) {
if (parentDir.mkdirs()) {
logger.info("Created app directory: " + parentDir.getAbsolutePath());
} else {
logger.error("Failed to create app directory: " + parentDir.getAbsolutePath());
return;
}
}
if (!configFile.exists()) {
try (InputStream in = Byodsec.class.getClassLoader().getResourceAsStream("default.properties")) {
if (in != null) {
Files.copy(in, configFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
logger.info("Default config file created at: {}", configFile.getAbsolutePath());
} else {
logger.error("Resource default.properties not found!");
}
} catch (IOException e) {
logger.error("Error creating config file: ", e);
}
} else {
logger.info("Config file already exists at: {}", configFile.getAbsolutePath());
}
configManager.loadConfig();
}
private static void initDB() {
if(DBPopulator.getInstance().isFirstRun())
DBPopulator.getInstance().populate();
}
private static void initJKS() {
File jksFile = configManager.getJksFile();
if (!jksFile.exists()) {
String path = jksFile.getAbsolutePath();
String password = configManager.getStringProperty("jksPassword");
logger.info("Executing JKS initialization command...");
ProcessBuilder pb = new ProcessBuilder(
"keytool",
"-genkeypair",
"-alias", "byodsec",
"-keyalg", "RSA",
"-keystore", path,
"-storepass", password,
"-keypass", password,
"-dname", "CN=localhost, OU=Byodsec, O=Chat33, L=Sevilla, ST=Andalucia, C=ES",
"-validity", "365"
);
pb.inheritIO();
Process process = null;
try {
process = pb.start();
process.waitFor();
} catch (IOException e) {
logger.error("Error executing JKS initialization command: ", e);
throw new RuntimeException(e);
} catch (InterruptedException e) {
logger.error("Error executing JKS initialization command: ", e);
throw new RuntimeException(e);
}
}
}
private static void initProperties() {
// especificamos mediante propiedades el KS y la contraseña
System.setProperty("javax.net.ssl.keyStore", configManager.getJksFile().getAbsolutePath());
System.setProperty("javax.net.ssl.keyStorePassword", configManager.getStringProperty("jksPassword"));
System.setProperty("javax.net.ssl.trustStore", configManager.getJksFile().getAbsolutePath());
System.setProperty("javax.net.ssl.trustStorePassword", configManager.getStringProperty("jksPassword"));
}
private static void initUI() {
try {
UIManager.setLookAndFeel(new FlatMacDarkLaf());
} catch(UnsupportedLookAndFeelException e) {
logger.error("Error setting LaF. Falling back to default Swing looks.");
}
IconFontSwing.register(FontAwesome.getIconFont());
IconFontSwing.register(GoogleMaterialDesignIcons.getIconFont());
SwingUtilities.invokeLater(() -> {
new MainWindow().setVisible(true);
});
}
}

View File

@@ -0,0 +1,97 @@
package net.miarma.byodsec.client;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import javax.net.ssl.*;
import com.google.gson.Gson;
import net.miarma.byodsec.common.ConfigManager;
import net.miarma.byodsec.common.db.dto.LoginDTO;
import net.miarma.byodsec.common.db.dto.MessageDTO;
import net.miarma.byodsec.common.socket.SocketRequest;
import net.miarma.byodsec.common.socket.SocketResponse;
public class ClientSocket implements AutoCloseable {
private SSLSocket socket;
private PrintWriter output;
private BufferedReader input;
private final Gson gson = new Gson();
private final ConfigManager configManager = ConfigManager.getInstance();
public ClientSocket() throws IOException {
configManager.loadConfig();
// inicializamos el socket SSL, la versión de TLS y los Cipher Suites a utilizar
SSLSocketFactory factory;
try {
factory = initSSL();
} catch (Exception e) {
throw new IOException("Error initializing SSL context.", e);
}
this.socket = (SSLSocket) factory.createSocket("localhost", 6969);
this.socket.setEnabledProtocols(new String[]{ "TLSv1.3" });
this.socket.setEnabledCipherSuites(new String[]{
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_CHACHA20_POLY1305_SHA256"
});
// buffers
this.output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
this.input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
private SSLSocketFactory initSSL() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(configManager.getJksFile().getAbsolutePath()),
configManager.getStringProperty("jksPassword").toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, configManager.getStringProperty("jksPassword").toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
public SocketResponse login(String username, String password) throws IOException {
SocketRequest msg = new SocketRequest(SocketRequest.Action.LOGIN, new LoginDTO(username, password));
output.println(gson.toJson(msg));
return gson.fromJson(input.readLine(), SocketResponse.class);
}
public SocketResponse register(String username, String password) throws IOException {
SocketRequest msg = new SocketRequest(SocketRequest.Action.REGISTER, new LoginDTO(username, password));
output.println(gson.toJson(msg));
return gson.fromJson(input.readLine(), SocketResponse.class);
}
public SocketResponse logout(String userId) throws IOException {
SocketRequest msg = new SocketRequest(SocketRequest.Action.LOGOUT, userId);
output.println(gson.toJson(msg));
return gson.fromJson(input.readLine(), SocketResponse.class);
}
public SocketResponse sendMessage(MessageDTO message) throws Exception {
SocketRequest msg = new SocketRequest(SocketRequest.Action.SEND_MESSAGE, message);
output.println(gson.toJson(msg));
return gson.fromJson(input.readLine(), SocketResponse.class);
}
@Override
public void close() {
try {
input.close();
output.close();
socket.close();
} catch (Exception ignored) {}
}
}

View File

@@ -0,0 +1,62 @@
package net.miarma.byodsec.client.ui;
import javax.swing.*;
import java.awt.*;
public class AutoShrinkLabel extends JLabel {
public AutoShrinkLabel(String text) {
super(text);
setHorizontalAlignment(SwingConstants.CENTER);
}
@Override
protected void paintComponent(Graphics g) {
String text = getText();
if (text == null || text.isEmpty()) {
super.paintComponent(g);
return;
}
Insets insets = getInsets();
int availableHeight = getHeight() - insets.top - insets.bottom;
int availableWidth = getWidth() - insets.left - insets.right;
if (availableWidth <= 0 || availableHeight <= 0) {
return;
}
Graphics2D graphics2d = (Graphics2D) g.create();
Font font = getFont();
int fontSize = font.getSize();
FontMetrics fm;
int textWidth;
int textHeight;
do {
Font testFont = font.deriveFont((float) fontSize);
fm = graphics2d.getFontMetrics(testFont);
textWidth = fm.stringWidth(text);
textHeight = fm.getHeight();
if (textWidth <= availableWidth && textHeight <= availableHeight) {
font = testFont;
break;
}
fontSize--;
} while (fontSize > 5);
graphics2d.setFont(font);
int x = (getWidth() - fm.stringWidth(text)) / 2;
int y = (getHeight() + fm.getAscent() - fm.getDescent()) / 2;
graphics2d.drawString(text, x, y);
graphics2d.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 50);
}
}

View File

@@ -0,0 +1,442 @@
/*
* Created by JFormDesigner on Wed Oct 01 16:21:10 CEST 2025
*/
package net.miarma.byodsec.client.ui;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;
import com.google.gson.Gson;
import jiconfont.icons.font_awesome.FontAwesome;
import jiconfont.swing.IconFontSwing;
import net.miarma.byodsec.common.Constants;
import net.miarma.byodsec.common.security.IntegrityProvider;
import net.miarma.byodsec.common.socket.SocketResponse;
import net.miarma.byodsec.common.socket.SocketStatus;
import net.miarma.byodsec.common.db.dto.MessageDTO;
import net.miarma.byodsec.common.db.entities.UserEntity;
import net.miarma.byodsec.client.ClientSocket;
import net.miginfocom.swing.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author jomaa
*/
public class MainWindow extends JFrame {
public static UserEntity _loggedUser;
private static final Logger logger = LoggerFactory.getLogger(ClientSocket.class);
public MainWindow() {
initComponents();
this.setTitle(Constants.APP_NAME);
versionLabel.setText(Constants.APP_NAME + " v" + Constants.APP_VERSION + " by Security Team 33");
setIcons();
}
private void setIcons() {
userLabel.setIcon(IconFontSwing.buildIcon(FontAwesome.USER, 18, Color.WHITE));
passwordLabel.setIcon(IconFontSwing.buildIcon(FontAwesome.KEY, 18, Color.WHITE));
loginBtn.setIcon(IconFontSwing.buildIcon(FontAwesome.SIGN_IN, 18, Color.WHITE));
registerBtn.setIcon(IconFontSwing.buildIcon(FontAwesome.USER_PLUS, 18, Color.WHITE));
clientLabel.setIcon(IconFontSwing.buildIcon(FontAwesome.USER_CIRCLE, 16, Color.WHITE));
logoutBtn.setIcon(IconFontSwing.buildIcon(FontAwesome.SIGN_OUT, 16, Color.WHITE));
}
private void clearLoginInputs() {
userTextField.setText("");
passwordTextField.setText("");
}
private void clearMainInputs() {
clientTextField.setText("");
}
private void appendChatMessage(String message) {
chatTextArea.append(message + "\r\n");
chatTextArea.setCaretPosition(chatTextArea.getDocument().getLength());
}
private void setView(String name) {
((CardLayout)getContentPane().getLayout()).show(getContentPane(), name);
}
private void loginBtn(ActionEvent e) {
String username = userTextField.getText();
String password = new String(passwordTextField.getPassword());
try (ClientSocket client = new ClientSocket()) {
SocketResponse res = client.login(username, password);
if (res.getStatus() == SocketStatus.OK) {
_loggedUser = new Gson().fromJson(
new Gson().toJson(res.getData()),
UserEntity.class
);
logger.info("El usuario '{}' ha iniciado sesión correctamente.", username);
JOptionPane.showMessageDialog(this,
res.getMessage().getMessage(),
res.getStatus().toString(),
JOptionPane.INFORMATION_MESSAGE
);
clientLabel.setText("Cliente: " + _loggedUser.getUserName());
this.setTitle(Constants.APP_NAME + " @" + _loggedUser.getUserName());
clearLoginInputs();
setView("mainPanel");
} else if(res.getStatus() == SocketStatus.ALREADY_LOGGED_IN) {
logger.info("El usuario '{}' ya tiene una sesión activa.", username);
JOptionPane.showMessageDialog(this,
res.getMessage() != null ? res.getMessage().getMessage() : "Respuesta sin mensaje",
res.getStatus().toString(),
JOptionPane.WARNING_MESSAGE
);
} else {
logger.warn("Intento de login fallido para '{}': {}", username,
res.getMessage() != null ? res.getMessage().getMessage() : "Respuesta sin mensaje");
JOptionPane.showMessageDialog(this,
res.getMessage() != null ? res.getMessage().getMessage() : "Respuesta sin mensaje",
res.getStatus().toString(),
JOptionPane.ERROR_MESSAGE
);
}
} catch (IOException ex) {
logger.error("Error de conexión con el servidor al intentar loguear '{}': {}", username, ex.getMessage());
JOptionPane.showMessageDialog(this,
"Error de conexión con el servidor",
"Error",
JOptionPane.ERROR_MESSAGE
);
}
}
private void registerBtn(ActionEvent e) {
String username = userTextField.getText();
String password = new String(passwordTextField.getPassword());
try (ClientSocket client = new ClientSocket()) {
SocketResponse res = client.register(username, password);
if(res.getStatus() == SocketStatus.OK) {
logger.info("Usuario '{}' registrado correctamente.", username);
} else {
logger.warn("Error al registrar '{}': {}", username,
res.getMessage() != null ? res.getMessage().getMessage() : "Respuesta sin mensaje");
}
JOptionPane.showMessageDialog(this,
res.getMessage() != null ? res.getMessage().getMessage() : "Respuesta sin mensaje",
res.getStatus().toString(),
res.getStatus() == SocketStatus.OK ?
JOptionPane.INFORMATION_MESSAGE : JOptionPane.ERROR_MESSAGE
);
clearLoginInputs();
} catch (IOException ex) {
logger.error("Error de conexión con el servidor al registrar '{}': {}", username, ex.getMessage());
JOptionPane.showMessageDialog(this,
"Error de conexión con el servidor",
"Error",
JOptionPane.ERROR_MESSAGE
);
}
}
private void logout() {
if (_loggedUser != null) {
try (ClientSocket client = new ClientSocket()) {
SocketResponse res = client.logout(_loggedUser.getUserId());
if (res != null && res.getMessage() != null) {
if (res.getStatus() == SocketStatus.OK) {
logger.info("Usuario '{}' ha cerrado sesión correctamente.", _loggedUser.getUserName());
this.setTitle(Constants.APP_NAME);
} else {
logger.warn("Intento de logout de '{}' con estado: {}", _loggedUser.getUserName(), res.getStatus());
}
JOptionPane.showMessageDialog(this,
res.getMessage().getMessage(),
res.getStatus().toString(),
res.getStatus() == SocketStatus.OK ?
JOptionPane.INFORMATION_MESSAGE : JOptionPane.ERROR_MESSAGE
);
}
} catch (IOException ex) {
logger.error("Error de conexión con el servidor al hacer logout de '{}': {}", _loggedUser.getUserName(), ex.getMessage());
JOptionPane.showMessageDialog(this,
"Error de conexión con el servidor",
"Error",
JOptionPane.ERROR_MESSAGE
);
}
}
clearMainInputs();
_loggedUser = null;
}
private void thisWindowClosing(WindowEvent e) {
logout();
}
private void send(ActionEvent e) {
try (ClientSocket client = new ClientSocket()) {
String message = clientTextField.getText();
MessageDTO dto = new MessageDTO(_loggedUser.getUserName(), message);
SocketResponse res = client.sendMessage(dto);
appendChatMessage(String.format("%s: %s", _loggedUser.getUserName(), message));
appendChatMessage("Servidor: " + res.getData());
if (res.getStatus() == SocketStatus.OK) {
logger.info("Mensaje enviado: {} -> Servidor", _loggedUser.getUserName());
} else if (res.getStatus() == SocketStatus.SESSION_EXPIRED) {
logger.warn("Sesión expirada para '{}'. Se cerrará sesión.", _loggedUser.getUserName());
_loggedUser = null;
setView("loginPanel");
clearMainInputs();
} else {
logger.warn("Error enviando mensaje de {} a Servidor: {}", _loggedUser.getUserName(),
res.getMessage() != null ? res.getMessage().getMessage() : "Sin mensaje");
}
clearMainInputs();
} catch (Exception ex) {
logger.error("Error de conexión con el servidor enviando mensaje de {} a Servidor: {}",
_loggedUser.getUserName(), ex.getMessage());
JOptionPane.showMessageDialog(this,
"Error de conexión con el servidor",
"Error",
JOptionPane.ERROR_MESSAGE
);
}
}
private void logoutBtn(ActionEvent e) {
logout();
setView("loginPanel");
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
// Generated using JFormDesigner Educational license - José Manuel Amador Gallardo (José Manuel Amador)
loginPanel = new JPanel();
logo = new JLabel();
userPanel = new JPanel();
userLabel = new JLabel();
userTextField = new JTextField();
passwordPanel = new JPanel();
passwordLabel = new JLabel();
passwordTextField = new JPasswordField();
loginBtn = new JButton();
btnLoginPanel = new JPanel();
noAccountLabel = new JLabel();
registerBtn = new JButton();
versionLabel = new JLabel();
mainPanel = new JPanel();
chatScrollPane = new JScrollPane();
chatTextArea = new JTextArea();
clientPanel = new JPanel();
clientLabel = new JLabel();
logoutBtn = new JButton();
clientTextField = new JTextField();
//======== this ========
setResizable(false);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
thisWindowClosing(e);
}
});
var contentPane = getContentPane();
contentPane.setLayout(new CardLayout(6, 6));
//======== loginPanel ========
{
loginPanel.setLayout(new MigLayout(
"hidemode 3,gapy 12",
// columns
"[grow,fill]",
// rows
"[]para" +
"[fill]" +
"[fill]para" +
"[]" +
"[grow,fill]"));
//---- logo ----
logo.setIcon(new ImageIcon(getClass().getResource("/images/logo.png")));
logo.setMaximumSize(new Dimension(256, 256));
logo.setMinimumSize(new Dimension(256, 256));
logo.setPreferredSize(new Dimension(256, 256));
logo.setHorizontalTextPosition(SwingConstants.CENTER);
loginPanel.add(logo, "cell 0 0,alignx center,growx 0");
//======== userPanel ========
{
userPanel.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
"[fill]" +
"[grow,fill]",
// rows
"[grow,fill]"));
//---- userLabel ----
userLabel.setText("Usuario:");
userLabel.setFont(new Font("Adwaita Sans", Font.PLAIN, 18));
userLabel.setMaximumSize(new Dimension(130, 23));
userLabel.setMinimumSize(new Dimension(130, 23));
userLabel.setPreferredSize(new Dimension(130, 23));
userPanel.add(userLabel, "cell 0 0");
//---- userTextField ----
userTextField.setFont(new Font("Adwaita Sans", Font.PLAIN, 18));
userPanel.add(userTextField, "cell 1 0");
}
loginPanel.add(userPanel, "cell 0 1");
//======== passwordPanel ========
{
passwordPanel.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
"[fill]" +
"[grow,fill]",
// rows
"[grow,fill]"));
//---- passwordLabel ----
passwordLabel.setText("Contrase\u00f1a:");
passwordLabel.setFont(new Font("Adwaita Sans", Font.PLAIN, 18));
passwordLabel.setMaximumSize(new Dimension(130, 23));
passwordLabel.setMinimumSize(new Dimension(130, 23));
passwordLabel.setPreferredSize(new Dimension(130, 23));
passwordPanel.add(passwordLabel, "cell 0 0");
//---- passwordTextField ----
passwordTextField.setFont(new Font("Adwaita Sans", Font.PLAIN, 18));
passwordPanel.add(passwordTextField, "cell 1 0");
}
loginPanel.add(passwordPanel, "cell 0 2");
//---- loginBtn ----
loginBtn.setText("Iniciar sesi\u00f3n");
loginBtn.setFont(new Font("Adwaita Sans", Font.PLAIN, 18));
loginBtn.addActionListener(e -> loginBtn(e));
loginPanel.add(loginBtn, "cell 0 3,alignx trailing,growx 0");
//======== btnLoginPanel ========
{
btnLoginPanel.setLayout(new MigLayout(
"hidemode 3,aligny bottom",
// columns
"[grow,fill]",
// rows
"[]" +
"[fill]para" +
"[]"));
//---- noAccountLabel ----
noAccountLabel.setText("\u00bfNo tiene cuenta?");
btnLoginPanel.add(noAccountLabel, "cell 0 0,alignx center,growx 0");
//---- registerBtn ----
registerBtn.setText("Registrarse");
registerBtn.setFont(new Font("Adwaita Sans", Font.PLAIN, 18));
registerBtn.addActionListener(e -> registerBtn(e));
btnLoginPanel.add(registerBtn, "cell 0 1,alignx center,growx 0");
//---- versionLabel ----
versionLabel.setForeground(new Color(0xa0a0a0));
btnLoginPanel.add(versionLabel, "cell 0 2,alignx center,growx 0");
}
loginPanel.add(btnLoginPanel, "cell 0 4");
}
contentPane.add(loginPanel, "loginPanel");
//======== mainPanel ========
{
mainPanel.setLayout(new MigLayout(
"hidemode 3",
// columns
"[grow,fill]",
// rows
"[grow,fill]" +
"[fill]" +
"[fill]"));
//======== chatScrollPane ========
{
//---- chatTextArea ----
chatTextArea.setEditable(false);
chatTextArea.setFocusable(false);
chatTextArea.setFont(new Font("Adwaita Mono", Font.PLAIN, 16));
chatScrollPane.setViewportView(chatTextArea);
}
mainPanel.add(chatScrollPane, "cell 0 0");
//======== clientPanel ========
{
clientPanel.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
"[grow,fill]" +
"[fill]",
// rows
"[]"));
//---- clientLabel ----
clientLabel.setText("Cliente: $c");
clientLabel.setFont(new Font("Adwaita Sans", Font.PLAIN, 16));
clientPanel.add(clientLabel, "cell 0 0");
//---- logoutBtn ----
logoutBtn.setText("Cerrar sesi\u00f3n");
logoutBtn.setFont(new Font("Adwaita Sans", Font.PLAIN, 16));
logoutBtn.addActionListener(e -> logoutBtn(e));
clientPanel.add(logoutBtn, "cell 1 0");
}
mainPanel.add(clientPanel, "cell 0 1");
//---- clientTextField ----
clientTextField.addActionListener(e -> send(e));
mainPanel.add(clientTextField, "cell 0 2");
}
contentPane.add(mainPanel, "mainPanel");
setSize(400, 600);
setLocationRelativeTo(getOwner());
// JFormDesigner - End of component initialization //GEN-END:initComponents @formatter:on
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables @formatter:off
// Generated using JFormDesigner Educational license - José Manuel Amador Gallardo (José Manuel Amador)
private JPanel loginPanel;
private JLabel logo;
private JPanel userPanel;
private JLabel userLabel;
private JTextField userTextField;
private JPanel passwordPanel;
private JLabel passwordLabel;
private JPasswordField passwordTextField;
private JButton loginBtn;
private JPanel btnLoginPanel;
private JLabel noAccountLabel;
private JButton registerBtn;
private JLabel versionLabel;
private JPanel mainPanel;
private JScrollPane chatScrollPane;
private JTextArea chatTextArea;
private JPanel clientPanel;
private JLabel clientLabel;
private JButton logoutBtn;
private JTextField clientTextField;
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
}

View File

@@ -0,0 +1,176 @@
JFDML JFormDesigner: "8.2.4.0.393" Java: "21.0.8" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormWindow( "javax.swing.JFrame", new FormLayoutManager( class java.awt.CardLayout ) {
"hgap": 6
"vgap": 6
} ) {
name: "this"
"$sizePolicy": 1
"resizable": false
"defaultCloseOperation": 3
addEvent( new FormEvent( "java.awt.event.WindowListener", "windowClosing", "thisWindowClosing", true ) )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3,gapy 12"
"$columnConstraints": "[grow,fill]"
"$rowConstraints": "[]para[fill][fill]para[][grow,fill]"
} ) {
name: "loginPanel"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "logo"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/images/logo.png" )
"maximumSize": new java.awt.Dimension( 256, 256 )
"minimumSize": new java.awt.Dimension( 256, 256 )
"preferredSize": new java.awt.Dimension( 256, 256 )
"horizontalTextPosition": 0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0,alignx center,growx 0"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[fill][grow,fill]"
"$rowConstraints": "[grow,fill]"
} ) {
name: "userPanel"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "userLabel"
"text": "Usuario:"
"font": &Font0 new java.awt.Font( "Adwaita Sans", 0, 18 )
"maximumSize": new java.awt.Dimension( 130, 23 )
"minimumSize": new java.awt.Dimension( 130, 23 )
"preferredSize": new java.awt.Dimension( 130, 23 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "userTextField"
"font": &Font1 new java.awt.Font( "Adwaita Sans", 0, 18 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[fill][grow,fill]"
"$rowConstraints": "[grow,fill]"
} ) {
name: "passwordPanel"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "passwordLabel"
"text": "Contraseña:"
"font": #Font0
"maximumSize": new java.awt.Dimension( 130, 23 )
"minimumSize": new java.awt.Dimension( 130, 23 )
"preferredSize": new java.awt.Dimension( 130, 23 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JPasswordField" ) {
name: "passwordTextField"
"font": #Font1
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "loginBtn"
"text": "Iniciar sesión"
"font": &Font2 new java.awt.Font( "Adwaita Sans", 0, 18 )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "loginBtn", true ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3,alignx trailing,growx 0"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3,aligny bottom"
"$columnConstraints": "[grow,fill]"
"$rowConstraints": "[][fill]para[]"
} ) {
name: "btnLoginPanel"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "noAccountLabel"
"text": "¿No tiene cuenta?"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "registerBtn"
"text": "Registrarse"
"font": #Font2
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "registerBtn", true ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1,alignx center,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "versionLabel"
"foreground": new java.awt.Color( 160, 160, 160, 255 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2,alignx center,growx 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "loginPanel"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[grow,fill]"
"$rowConstraints": "[grow,fill][fill][fill]"
} ) {
name: "mainPanel"
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
name: "chatScrollPane"
add( new FormComponent( "javax.swing.JTextArea" ) {
name: "chatTextArea"
"editable": false
"focusable": false
"font": new java.awt.Font( "Adwaita Mono", 0, 16 )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[grow,fill][fill]"
"$rowConstraints": "[]"
} ) {
name: "clientPanel"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "clientLabel"
"text": "Cliente: $c"
"font": &Font3 new java.awt.Font( "Adwaita Sans", 0, 16 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "logoutBtn"
"text": "Cerrar sesión"
"font": #Font3
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "logoutBtn", true ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "clientTextField"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "send", true ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "mainPanel"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 400, 600 )
} )
}
}

View File

@@ -0,0 +1,105 @@
package net.miarma.byodsec.common;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
public class ConfigManager {
private static ConfigManager INSTANCE;
private final File jksFile;
private final File configFile;
private final Properties config;
private static final String JKS_FILE_NAME = "byodsec.jks";
private static final String CONFIG_FILE_NAME = "config.properties";
private final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
private ConfigManager() {
String jksPath = getBaseDir() + JKS_FILE_NAME;
String configPath = getBaseDir() + CONFIG_FILE_NAME;
this.jksFile = new File(jksPath);
this.configFile = new File(configPath);
this.config = new Properties();
}
public static ConfigManager getInstance() {
if(INSTANCE == null) {
INSTANCE = new ConfigManager();
}
return INSTANCE;
}
public void loadConfig() {
try (FileInputStream fis = new FileInputStream(configFile);
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8)) {
config.load(isr);
} catch (IOException e) {
logger.error("Error loading configuration file: ", e);
}
}
public File getJksFile() {
return jksFile;
}
public File getConfigFile() {
return configFile;
}
public String getHomeDir() {
return getOS() == OSType.WINDOWS ?
"C:/Users/" + System.getProperty("user.name") + "/" :
getOS() == OSType.LINUX ?
(System.getProperty("user.home").contains("root") ? "/root/" :
"/home/" + System.getProperty("user.name") + "/") :
getOS() == OSType.MACOS ? "/Users/" + System.getProperty("user.name") + "/" : System.getProperty("user.home");
}
public String getBaseDir() {
return getHomeDir() +
(getOS() == OSType.WINDOWS || getOS() == OSType.MACOS ? ".byodsec/" :
getOS() == OSType.LINUX ? ".config/byodsec/" :
".byodsec/");
}
public static OSType getOS() {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
return OSType.WINDOWS;
} else if (os.contains("nix") || os.contains("nux")) {
return OSType.LINUX;
} else if (os.contains("mac")) {
return OSType.MACOS;
} else {
return OSType.INVALID_OS;
}
}
public String getStringProperty(String key) {
return config.getProperty(key);
}
public int getIntProperty(String key) {
String value = config.getProperty(key);
return value != null ? Integer.parseInt(value) : 10;
}
public boolean getBooleanProperty(String key) {
return Boolean.parseBoolean(config.getProperty(key));
}
public void setProperty(String key, String value) {
config.setProperty(key, value);
saveConfig();
}
private void saveConfig() {
try (FileOutputStream fos = new FileOutputStream(configFile)) {
config.store(fos, "Configuration for: " + Constants.APP_NAME);
} catch (IOException e) {
logger.error("Error saving configuration file: ", e);
}
}
}

View File

@@ -0,0 +1,10 @@
package net.miarma.byodsec.common;
public class Constants {
public static final String APP_NAME = "BYODSEC";
public static final String APP_VERSION = "1.0.0";
private Constants() {
throw new AssertionError("Utility class cannot be instantiated.");
}
}

View File

@@ -0,0 +1,9 @@
package net.miarma.byodsec.common;
/**
* Enum que representa los diferentes tipos de sistemas operativos soportados
* @author José Manuel Amador Gallardo
*/
public enum OSType {
LINUX, WINDOWS, MACOS, INVALID_OS
}

View File

@@ -0,0 +1,39 @@
package net.miarma.byodsec.common.db;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
public class DBConnector {
private static DBConnector instance;
private EntityManagerFactory emf;
private final ThreadLocal<EntityManager> threadLocal = new ThreadLocal<>();
private DBConnector() {
this.emf = Persistence.createEntityManagerFactory("ssii-pai2");
}
public static DBConnector getInstance() {
if (instance == null) {
instance = new DBConnector();
}
return instance;
}
public EntityManager getEntityManager() {
EntityManager em = threadLocal.get();
if (em == null || !em.isOpen()) {
em = emf.createEntityManager();
threadLocal.set(em);
}
return em;
}
public void close() {
EntityManager em = threadLocal.get();
if (em != null && em.isOpen()) {
em.close();
}
threadLocal.remove();
}
}

View File

@@ -0,0 +1,51 @@
package net.miarma.byodsec.common.db;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import net.miarma.byodsec.common.security.PasswordHasher;
import net.miarma.byodsec.common.db.entities.UserEntity;
import java.util.UUID;
public class DBPopulator {
private final DBConnector conn = DBConnector.getInstance();
private EntityManager em;
private static DBPopulator instance;
private DBPopulator() {
em = conn.getEntityManager();
}
public static DBPopulator getInstance() {
if (instance == null) {
instance = new DBPopulator();
}
return instance;
}
public boolean isFirstRun() {
TypedQuery<Long> q = em.createQuery("SELECT COUNT(u) FROM UserEntity u", Long.class);
Long count = q.getSingleResult();
return count == 0;
}
public void populate() {
UserEntity u1 = new UserEntity(UUID.randomUUID().toString(),
"ricolinad", PasswordHasher.hash("ricardo2025"));
UserEntity u2 = new UserEntity(UUID.randomUUID().toString(),
"alvgulveg", PasswordHasher.hash("alcalde_dimision"));
UserEntity u3 = new UserEntity(UUID.randomUUID().toString(),
"smt4497", PasswordHasher.hash("quemenlaus"));
try {
em.getTransaction().begin();
em.persist(u1);
em.persist(u2);
em.persist(u3);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
} finally {
em.close();
}
}
}

View File

@@ -0,0 +1,20 @@
package net.miarma.byodsec.common.db.dao;
import jakarta.persistence.EntityManager;
import net.miarma.byodsec.common.db.entities.SessionEntity;
public class SessionDAO {
public SessionEntity getByUserId(EntityManager em, String userId) {
return em.createQuery("SELECT s FROM SessionEntity s WHERE s.userId = :userId", SessionEntity.class)
.setParameter("userId", userId)
.getSingleResult();
}
public boolean isLoggedIn(EntityManager em, String userId) {
Long count = em.createQuery(
"SELECT COUNT(s) FROM SessionEntity s WHERE s.userId = :userId", Long.class)
.setParameter("userId", userId)
.getSingleResult();
return count > 0;
}
}

View File

@@ -0,0 +1,16 @@
package net.miarma.byodsec.common.db.dao;
import jakarta.persistence.EntityManager;
import net.miarma.byodsec.common.db.entities.UserEntity;
public class UserDAO {
public UserEntity getByUserName(EntityManager em, String userName) {
try {
return em.createQuery("SELECT u FROM UserEntity u WHERE u.userName = :userName", UserEntity.class)
.setParameter("userName", userName)
.getSingleResult();
} catch (jakarta.persistence.NoResultException e) {
return null; // No se encontró, devolvemos null
}
}
}

View File

@@ -0,0 +1,30 @@
package net.miarma.byodsec.common.db.dto;
public class LoginDTO {
private String username;
private String password;
public LoginDTO() {
}
public LoginDTO(String username, String password) {
this.username = username;
this.password = password;
}
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;
}
}

View File

@@ -0,0 +1,31 @@
package net.miarma.byodsec.common.db.dto;
public class MessageDTO {
private String fromUserName;
private String messageText;
public MessageDTO() {}
public MessageDTO(String fromUserName, String messageText) {
this.fromUserName = fromUserName;
this.messageText = messageText;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getMessageText() {
return messageText;
}
public void setMessageText(String messageText) {
this.messageText = messageText;
}
}

View File

@@ -0,0 +1,66 @@
package net.miarma.byodsec.common.db.entities;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
@Entity
@Table(name = "sessions")
public class SessionEntity {
@Id
@Column(name = "sessionId", nullable = false, updatable = false)
private String sessionId;
@Column(name = "userId", nullable = false)
private String userId;
@Column(name = "createdAt", nullable = false, updatable = false, insertable = false)
private LocalDateTime createdAt;
@Column(name = "expiresAt", nullable = false, updatable = false, insertable = false)
private LocalDateTime expiresAt;
public SessionEntity() {}
public SessionEntity(String sessionId, String userId, LocalDateTime createdAt, LocalDateTime expiresAt) {
this.sessionId = sessionId;
this.userId = userId;
this.createdAt = createdAt;
this.expiresAt = expiresAt;
}
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public LocalDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(LocalDateTime createdAt) {
this.createdAt = createdAt;
}
public LocalDateTime getExpiresAt() {
return expiresAt;
}
public void setExpiresAt(LocalDateTime expiresAt) {
this.expiresAt = expiresAt;
}
}

View File

@@ -0,0 +1,52 @@
package net.miarma.byodsec.common.db.entities;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "users")
public class UserEntity {
@Id
@Column(name = "userId", nullable = false, updatable = false, length = 36)
private String userId;
@Column(name = "userName", unique = true, nullable = false, length = 64)
private String userName;
@Column(name = "password", nullable = false, length = 256)
private String password;
public UserEntity() {}
public UserEntity(String userId, String userName, String password) {
this.userId = userId;
this.userName = userName;
this.password = password;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
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;
}
}

View File

@@ -0,0 +1,30 @@
package net.miarma.byodsec.common.security;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class IntegrityProvider {
public static String generateHMAC(String key, String data) throws Exception {
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256HMAC.init(secretKey);
return byteArrayToHex(sha256HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8)));
}
public static String generateNonce() {
byte[] nonce = new byte[16];
new SecureRandom().nextBytes(nonce);
return Base64.getEncoder().encodeToString(nonce);
}
public static String byteArrayToHex(byte[] arr) {
StringBuilder sb = new StringBuilder(arr.length * 2);
for(byte b : arr) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}

View File

@@ -0,0 +1,22 @@
package net.miarma.byodsec.common.security;
import org.mindrot.jbcrypt.BCrypt;
/**
* Clase de utilidad para el hash de contraseñas.
* Utiliza BCrypt para generar y verificar hashes de contraseñas.
*
* @author José Manuel Amador Gallardo
*/
public class PasswordHasher {
private static final int SALT_ROUNDS = 12;
public static String hash(String plainPassword) {
return BCrypt.hashpw(plainPassword, BCrypt.gensalt(SALT_ROUNDS));
}
public static boolean verify(String plainPassword, String hashedPassword) {
return BCrypt.checkpw(plainPassword, hashedPassword);
}
}

View File

@@ -0,0 +1,41 @@
package net.miarma.byodsec.common.socket;
public class SocketRequest {
private SocketRequest.Action action;
private Object payload;
public SocketRequest() {}
public SocketRequest(SocketRequest.Action action, Object payload) {
this.action = action;
this.payload = payload;
}
public SocketRequest.Action getAction() {
return action;
}
public void setAction(SocketRequest.Action action) {
this.action = action;
}
public Object getPayload() {
return payload;
}
public void setPayload(Object payload) {
this.payload = payload;
}
@Override
public String toString() {
return "SocketRequest{" +
"action='" + action.name() + '\'' +
", payload=" + (payload != null ? payload.toString() : "null") +
'}';
}
public enum Action {
LOGIN, REGISTER, SEND_MESSAGE, LOGOUT
}
}

View File

@@ -0,0 +1,67 @@
package net.miarma.byodsec.common.socket;
public class SocketResponse {
private SocketStatus status;
private Message message;
private Object data;
public SocketResponse(SocketStatus status, Message message) {
this(status, message, message != null ? message.getMessage() : null);
}
public SocketResponse(SocketStatus status, Message message, Object data) {
this.status = status;
this.message = message;
this.data = data;
}
public SocketStatus getStatus() {
return status;
}
public Message getMessage() {
return message;
}
public Object getData() {
return data;
}
@Override
public String toString() {
return "SocketResponse{" +
"status=" + status +
", message=" + (message != null ? message.name() : "null") +
", data=" + (data != null ? data.toString() : "null") +
'}';
}
public enum Message {
LOGGED_OUT("Ha cerrado sesión correctamente"),
LOGGED_IN("Ha iniciado sesión correctamente"),
MESSAGE_SENT("Su mensaje se ha enviado"),
USER_NOT_FOUND("El usuario no existe."),
WRONG_PASSWORD("Contraseña incorrecta."),
USER_ALREADY_EXISTS("El usuario ya está registrado."),
CONNECTION_ERROR("Error de conexión con el servidor."),
UNKNOWN_ERROR("Ha ocurrido un error inesperado."),
SESSION_EXPIRED("Tu sesión ha expirado."),
INTEGRITY_FAIL("Fallo de integridad en el mensaje."),
INVALID_AMOUNT("Cantidad no válida."),
REPLAY_ATTACK("Intento de repetición detectado."),
RECIPIENT_NOT_FOUND("El destinatario no existe"),
REGISTERED("Se ha registrado correctamente"),
SESSION_ACTIVE("Ya hay una sesión activa para este usuario.");
private final String message;
Message(String userMessage) {
this.message = userMessage;
}
public String getMessage() {
return message;
}
}
}

View File

@@ -0,0 +1,15 @@
package net.miarma.byodsec.common.socket;
public enum SocketStatus {
OK,
ERROR,
SESSION_EXPIRED,
ALREADY_LOGGED_IN,
INTEGRITY_FAIL,
UNAUTHORIZED,
INVALID_REQUEST;
public static boolean isOk(String status) {
return OK.name().equalsIgnoreCase(status);
}
}

View File

@@ -0,0 +1,156 @@
package net.miarma.byodsec.server;
import com.google.gson.Gson;
import jakarta.persistence.EntityManager;
import net.miarma.byodsec.common.db.DBConnector;
import net.miarma.byodsec.common.db.dao.SessionDAO;
import net.miarma.byodsec.common.db.dao.UserDAO;
import net.miarma.byodsec.common.db.dto.LoginDTO;
import net.miarma.byodsec.common.db.dto.MessageDTO;
import net.miarma.byodsec.common.db.entities.SessionEntity;
import net.miarma.byodsec.common.db.entities.UserEntity;
import net.miarma.byodsec.common.security.PasswordHasher;
import net.miarma.byodsec.common.socket.SocketRequest;
import net.miarma.byodsec.common.socket.SocketResponse;
import net.miarma.byodsec.common.socket.SocketStatus;
import org.slf4j.Logger;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.util.UUID;
public class ClientHandler implements Runnable {
private final SSLSocket socket;
private final Gson gson;
private final UserDAO userDAO;
private final SessionDAO sessionDAO;
private final DBConnector conn;
private final Logger logger;
public ClientHandler(SSLSocket socket, Gson gson, UserDAO userDAO, SessionDAO sessionDAO, DBConnector conn, Logger logger) {
this.socket = socket;
this.gson = gson;
this.userDAO = userDAO;
this.sessionDAO = sessionDAO;
this.conn = conn;
this.logger = logger;
}
@Override
public void run() {
try (
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true);
) {
logger.info("Nueva conexión desde {}:{}", socket.getInetAddress(), socket.getPort());
SocketRequest msg = gson.fromJson(input.readLine(), SocketRequest.class);
SocketResponse res;
switch (msg.getAction()) {
case REGISTER -> {
LoginDTO dto = gson.fromJson(gson.toJson(msg.getPayload()), LoginDTO.class);
logger.info("Procesando REGISTER para {}", dto.getUsername());
EntityManager em = conn.getEntityManager();
try {
if (userDAO.getByUserName(em, dto.getUsername()) != null) {
res = new SocketResponse(SocketStatus.INVALID_REQUEST, SocketResponse.Message.USER_ALREADY_EXISTS);
} else {
em.getTransaction().begin();
UserEntity u = new UserEntity(UUID.randomUUID().toString(),
dto.getUsername(), PasswordHasher.hash(dto.getPassword()));
em.persist(u);
em.getTransaction().commit();
res = new SocketResponse(SocketStatus.OK, SocketResponse.Message.REGISTERED, u);
}
} catch (Exception e) {
if (em.getTransaction().isActive()) em.getTransaction().rollback();
logger.error(e.getMessage(), e);
res = new SocketResponse(SocketStatus.ERROR, SocketResponse.Message.UNKNOWN_ERROR, e.getMessage());
} finally {
conn.close();
}
}
case LOGIN -> {
LoginDTO dto = gson.fromJson(gson.toJson(msg.getPayload()), LoginDTO.class);
logger.info("Procesando LOGIN para {}", dto.getUsername());
try (EntityManager em = conn.getEntityManager()) {
UserEntity user = userDAO.getByUserName(em, dto.getUsername());
if (user == null) {
res = new SocketResponse(SocketStatus.INVALID_REQUEST, SocketResponse.Message.USER_NOT_FOUND);
} else if (PasswordHasher.verify(dto.getPassword(), user.getPassword())) {
if(sessionDAO.isLoggedIn(em, user.getUserId())) {
res = new SocketResponse(SocketStatus.ALREADY_LOGGED_IN, SocketResponse.Message.SESSION_ACTIVE);
} else {
res = new SocketResponse(SocketStatus.OK, SocketResponse.Message.LOGGED_IN, user);
SessionEntity session = new SessionEntity();
session.setSessionId(UUID.randomUUID().toString());
session.setUserId(user.getUserId());
em.getTransaction().begin();
em.persist(session);
em.getTransaction().commit();
}
} else {
res = new SocketResponse(SocketStatus.INVALID_REQUEST, SocketResponse.Message.WRONG_PASSWORD);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
res = new SocketResponse(SocketStatus.ERROR, SocketResponse.Message.UNKNOWN_ERROR, e.getMessage());
}
}
case LOGOUT -> {
String userId = gson.fromJson(gson.toJson(msg.getPayload()), String.class);
logger.info("Procesando LOGOUT para {}", userId);
try (EntityManager em = conn.getEntityManager()) {
SessionEntity session = sessionDAO.getByUserId(em, userId);
if (session != null) {
em.getTransaction().begin();
em.remove(session);
em.getTransaction().commit();
res = new SocketResponse(SocketStatus.OK, SocketResponse.Message.LOGGED_OUT);
} else {
res = new SocketResponse(SocketStatus.SESSION_EXPIRED, SocketResponse.Message.SESSION_EXPIRED);
}
}
}
case SEND_MESSAGE -> {
MessageDTO dto = gson.fromJson(gson.toJson(msg.getPayload()), MessageDTO.class);
logger.info("Procesando SEND_MESSAGE de {} a Servidor | {}", dto.getFromUserName(), dto.getMessageText());
EntityManager em = conn.getEntityManager();
try {
UserEntity fromUser = userDAO.getByUserName(em, dto.getFromUserName());
if (fromUser == null || !sessionDAO.isLoggedIn(em, fromUser.getUserId())) {
res = new SocketResponse(SocketStatus.SESSION_EXPIRED, SocketResponse.Message.SESSION_EXPIRED);
} else if (dto.getMessageText().isBlank()) {
res = new SocketResponse(SocketStatus.INVALID_REQUEST, SocketResponse.Message.INVALID_AMOUNT);
} else {
res = new SocketResponse(SocketStatus.OK, SocketResponse.Message.MESSAGE_SENT, dto.getMessageText());
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
res = new SocketResponse(SocketStatus.ERROR, SocketResponse.Message.UNKNOWN_ERROR, e.getMessage());
} finally {
conn.close();
}
}
default -> {
logger.warn("Acción desconocida recibida: {}", msg.getAction());
res = new SocketResponse(SocketStatus.INVALID_REQUEST, SocketResponse.Message.UNKNOWN_ERROR);
}
}
output.println(gson.toJson(res));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,55 @@
package net.miarma.byodsec.server;
import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import net.miarma.byodsec.common.ConfigManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import net.miarma.byodsec.common.db.DBConnector;
import net.miarma.byodsec.common.db.dao.SessionDAO;
import net.miarma.byodsec.common.db.dao.UserDAO;
public class RemoteSocket {
static void main(String[] args) throws IOException {
ConfigManager configManager = ConfigManager.getInstance();
configManager.loadConfig();
DBConnector conn = DBConnector.getInstance();
UserDAO userDAO = new UserDAO();
SessionDAO sessionDAO = new SessionDAO();
Gson gson = new Gson();
final Logger logger = LoggerFactory.getLogger(RemoteSocket.class);
// especificamos mediante propiedades el KS y la contraseña
System.setProperty("javax.net.ssl.keyStore", configManager.getJksFile().getAbsolutePath());
System.setProperty("javax.net.ssl.keyStorePassword", configManager.getStringProperty("jksPassword"));
System.setProperty("javax.net.ssl.trustStore", configManager.getJksFile().getAbsolutePath());
System.setProperty("javax.net.ssl.trustStorePassword", configManager.getStringProperty("jksPassword"));
// inicializamos el socket SSL, la versión de TLS y los Cipher Suites a utilizar
SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(6969);
serverSocket.setEnabledProtocols(new String[]{ "TLSv1.3" });
serverSocket.setEnabledCipherSuites(new String[]{
"TLS_AES_256_GCM_SHA384",
"TLS_AES_128_GCM_SHA256",
"TLS_CHACHA20_POLY1305_SHA256"
});
serverSocket.setNeedClientAuth(true);
// main loop
Executor executor = Executors.newFixedThreadPool(300);
while (true) {
SSLSocket socket = (SSLSocket) serverSocket.accept();
executor.execute(new ClientHandler(socket, gson, userDAO, sessionDAO, conn, logger));
}
}
}

View File

@@ -0,0 +1,29 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="ssii-pai2">
<description>
Persistence unit for PAI-2
</description>
<class>net.miarma.byodsec.common.db.entities.UserEntity</class>
<class>net.miarma.byodsec.common.db.entities.SessionEntity</class>
<properties>
<property name="jakarta.persistence.jdbc.url" value="jdbc:mariadb://miarma.net:3307/pai2" />
<property name="jakarta.persistence.jdbc.user" value="admin" />
<property name="jakarta.persistence.jdbc.password" value="55ii.P4I.1;" />
<property name="jakarta.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MariaDBDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.highlight_sql" value="true" />
</properties>
</persistence-unit>
</persistence>

View File

@@ -0,0 +1 @@
jksPassword=

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,53 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="CLIENT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log/client.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/client-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<appender name="SERVER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>log/server.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/server-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<logger name="net.miarma.byodsec.ui" level="INFO" additivity="false">
<appender-ref ref="CLIENT"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="net.miarma.byodsec.client.ClientSocket" level="INFO" additivity="false">
<appender-ref ref="CLIENT"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="net.miarma.byodsec.server.RemoteSocket" level="DEBUG" additivity="false">
<appender-ref ref="SERVER"/>
<appender-ref ref="STDOUT"/>
</logger>
<logger name="net.miarma.byodsec.db" level="INFO" additivity="false">
<appender-ref ref="SERVER"/>
<appender-ref ref="STDOUT"/>
</logger>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -0,0 +1,27 @@
USE pai2;
-- Cleanup
DROP TABLE IF EXISTS sessions;
DROP TABLE IF EXISTS users;
-- END Cleanup
-- DDL
CREATE TABLE users (
userId UUID NOT NULL PRIMARY KEY,
userName VARCHAR(64) NOT NULL UNIQUE,
password VARCHAR(256) NOT NULL
);
CREATE TABLE sessions (
sessionId UUID NOT NULL PRIMARY KEY,
userId UUID NOT NULL UNIQUE,
createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
expiresAt TIMESTAMP AS (createdAt + INTERVAL 15 MINUTE) STORED,
FOREIGN KEY (userId) REFERENCES users(userId) ON DELETE CASCADE
);
CREATE EVENT IF NOT EXISTS clear_expired_sessions
ON SCHEDULE EVERY 1 MINUTE
DO
DELETE FROM sessions WHERE expiresAt <= NOW();
-- END DDL