diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..f7e4a1d
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..73e9ed9
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ backend
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/cine/.classpath b/cine/.classpath
new file mode 100644
index 0000000..f7e4a1d
--- /dev/null
+++ b/cine/.classpath
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cine/.gitignore b/cine/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/cine/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/cine/.project b/cine/.project
new file mode 100644
index 0000000..d49c5d8
--- /dev/null
+++ b/cine/.project
@@ -0,0 +1,23 @@
+
+
+ cine
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/cine/.settings/org.eclipse.jdt.core.prefs b/cine/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/cine/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/cine/.settings/org.eclipse.m2e.core.prefs b/cine/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/cine/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/cine/pom.xml b/cine/pom.xml
new file mode 100644
index 0000000..5928dbc
--- /dev/null
+++ b/cine/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+
+ net.miarma
+ backend
+ 1.0.0
+
+ cine
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ runtime
+
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+
\ No newline at end of file
diff --git a/core/.classpath b/core/.classpath
new file mode 100644
index 0000000..f7e4a1d
--- /dev/null
+++ b/core/.classpath
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/.gitignore b/core/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/core/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/core/.project b/core/.project
new file mode 100644
index 0000000..1a64507
--- /dev/null
+++ b/core/.project
@@ -0,0 +1,23 @@
+
+
+ core
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/core/.settings/org.eclipse.jdt.core.prefs b/core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/core/.settings/org.eclipse.m2e.core.prefs b/core/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/core/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..d3adb50
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,68 @@
+
+ 4.0.0
+
+ net.miarma
+ backend
+ 1.0.0
+
+ core
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ runtime
+
+
+ jakarta.validation
+ jakarta.validation-api
+ 3.1.1
+
+
+ org.hibernate.validator
+ hibernate-validator
+ 8.0.0.Final
+
+
+ org.projectlombok
+ lombok
+ 1.18.42
+ compile
+
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/java/net/miarma/backend/core/CoreApplication.java b/core/src/main/java/net/miarma/backend/core/CoreApplication.java
new file mode 100644
index 0000000..272d01d
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/CoreApplication.java
@@ -0,0 +1,11 @@
+package net.miarma.backend.core;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class CoreApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(CoreApplication.class, args);
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/config/JwtFilter.java b/core/src/main/java/net/miarma/backend/core/config/JwtFilter.java
new file mode 100644
index 0000000..3bd250d
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/config/JwtFilter.java
@@ -0,0 +1,74 @@
+package net.miarma.backend.core.config;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.UUID;
+
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import net.miarma.backend.core.model.User;
+import net.miarma.backend.core.service.JwtService;
+import net.miarma.backend.core.service.UserService;
+
+@Component
+public class JwtFilter extends OncePerRequestFilter {
+
+ private final JwtService jwtService;
+ private final UserService userService;
+ private final long refreshThreshold = 300_000;
+
+ public JwtFilter(JwtService jwtService, UserService userService) {
+ this.jwtService = jwtService;
+ this.userService = userService;
+ }
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request,
+ HttpServletResponse response,
+ FilterChain filterChain) throws ServletException, IOException {
+
+ String authHeader = request.getHeader("Authorization");
+ if (authHeader != null && authHeader.startsWith("Bearer ")) {
+ String token = authHeader.substring(7);
+
+ try {
+ if (jwtService.validateToken(token)) {
+ UUID userId = jwtService.getUserId(token);
+ short serviceId = jwtService.getServiceId(token);
+
+ User user = userService.getById(userId);
+
+ List authorities = List.of(
+ new SimpleGrantedAuthority("ROLE_" + user.getGlobalRole())
+ );
+
+ UsernamePasswordAuthenticationToken auth =
+ new UsernamePasswordAuthenticationToken(user, null, authorities);
+ auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+ SecurityContextHolder.getContext().setAuthentication(auth);
+
+ long timeLeft = jwtService.getExpiration(token).getTime() - System.currentTimeMillis();
+ if (timeLeft < refreshThreshold) {
+ String newToken = jwtService.generateToken(userId, serviceId);
+ response.setHeader("X-Refresh-Token", newToken);
+ }
+ }
+ } catch (Exception e) {
+ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid or expired token");
+ return;
+ }
+ }
+
+ filterChain.doFilter(request, response);
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/net/miarma/backend/core/config/SecurityConfig.java b/core/src/main/java/net/miarma/backend/core/config/SecurityConfig.java
new file mode 100644
index 0000000..da00bb9
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/config/SecurityConfig.java
@@ -0,0 +1,41 @@
+package net.miarma.backend.core.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+ private final JwtFilter jwtFilter;
+
+ public SecurityConfig(JwtFilter jwtFilter) {
+ this.jwtFilter = jwtFilter;
+ }
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http
+ .csrf(csrf -> csrf.disable())
+ .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .authorizeHttpRequests(auth -> auth
+ .requestMatchers("/auth/**").permitAll()
+ .anyRequest().authenticated()
+ );
+
+ http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
+
+ return http.build();
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder(12);
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/controller/AuthController.java b/core/src/main/java/net/miarma/backend/core/controller/AuthController.java
new file mode 100644
index 0000000..11aa3a1
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/controller/AuthController.java
@@ -0,0 +1,60 @@
+package net.miarma.backend.core.controller;
+
+import java.util.Map;
+import java.util.UUID;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import jakarta.validation.Valid;
+import net.miarma.backend.core.dto.LoginRequest;
+import net.miarma.backend.core.dto.LoginResponse;
+import net.miarma.backend.core.service.AuthService;
+import net.miarma.backend.core.service.JwtService;
+
+@RestController
+@RequestMapping("/auth")
+public class AuthController {
+
+ private final AuthService authService;
+ private final JwtService jwtService;
+
+ public AuthController(AuthService authService, JwtService jwtService) {
+ this.authService = authService;
+ this.jwtService = jwtService;
+ }
+
+ @PostMapping("/login")
+ public ResponseEntity login(@Valid @RequestBody LoginRequest request) {
+ LoginResponse response = authService.login(request);
+ return ResponseEntity.ok(response);
+ }
+
+ @PostMapping("/refresh")
+ public ResponseEntity> refreshToken(@RequestHeader("Authorization") String authHeader) {
+ if (authHeader == null || !authHeader.startsWith("Bearer ")) {
+ return ResponseEntity.status(401).body("Token missing");
+ }
+
+ String token = authHeader.substring(7);
+ if (!jwtService.validateToken(token)) {
+ return ResponseEntity.status(401).body("Invalid token");
+ }
+
+ UUID userId = jwtService.getUserId(token);
+ short serviceId = jwtService.getServiceId(token);
+
+ String newToken = jwtService.generateToken(userId, serviceId);
+
+ return ResponseEntity.ok(Map.of(
+ "token", newToken,
+ "userId", userId,
+ "serviceId", serviceId
+ ));
+ }
+
+}
diff --git a/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java b/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java
new file mode 100644
index 0000000..96e56ee
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/controller/CredentialController.java
@@ -0,0 +1,5 @@
+package net.miarma.backend.core.controller;
+
+public class CredentialController {
+
+}
diff --git a/core/src/main/java/net/miarma/backend/core/controller/FileController.java b/core/src/main/java/net/miarma/backend/core/controller/FileController.java
new file mode 100644
index 0000000..d2dea16
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/controller/FileController.java
@@ -0,0 +1,5 @@
+package net.miarma.backend.core.controller;
+
+public class FileController {
+
+}
diff --git a/core/src/main/java/net/miarma/backend/core/controller/UserController.java b/core/src/main/java/net/miarma/backend/core/controller/UserController.java
new file mode 100644
index 0000000..aa465e9
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/controller/UserController.java
@@ -0,0 +1,10 @@
+package net.miarma.backend.core.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/users")
+public class UserController {
+
+}
diff --git a/core/src/main/java/net/miarma/backend/core/dto/LoginRequest.java b/core/src/main/java/net/miarma/backend/core/dto/LoginRequest.java
new file mode 100644
index 0000000..bb7b436
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/dto/LoginRequest.java
@@ -0,0 +1,37 @@
+package net.miarma.backend.core.dto;
+
+import jakarta.validation.constraints.NotBlank;
+
+public class LoginRequest {
+ @NotBlank
+ private String username;
+
+ @NotBlank
+ private String password;
+
+ private short serviceId;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public short getServiceId() {
+ return serviceId;
+ }
+
+ public void setServiceId(short serviceId) {
+ this.serviceId = serviceId;
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/dto/LoginResponse.java b/core/src/main/java/net/miarma/backend/core/dto/LoginResponse.java
new file mode 100644
index 0000000..194732a
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/dto/LoginResponse.java
@@ -0,0 +1,37 @@
+package net.miarma.backend.core.dto;
+
+public class LoginResponse {
+ private String token;
+ private short serviceId;
+ private UserDto user;
+
+ public LoginResponse(String token, short serviceId, UserDto user) {
+ this.token = token;
+ this.serviceId = serviceId;
+ this.user = user;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public short getServiceId() {
+ return serviceId;
+ }
+
+ public void setServiceId(short serviceId) {
+ this.serviceId = serviceId;
+ }
+
+ public UserDto getUser() {
+ return user;
+ }
+
+ public void setUser(UserDto user) {
+ this.user = user;
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/net/miarma/backend/core/dto/UserDto.java b/core/src/main/java/net/miarma/backend/core/dto/UserDto.java
new file mode 100644
index 0000000..58dd2a2
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/dto/UserDto.java
@@ -0,0 +1,81 @@
+package net.miarma.backend.core.dto;
+
+import java.time.Instant;
+import java.util.UUID;
+
+public class UserDto {
+ private UUID userId;
+ private String displayName;
+ private String avatar;
+ private Byte globalStatus;
+ private Byte globalRole;
+ private Instant createdAt;
+ private Instant updatedAt;
+
+ public UserDto(UUID userId, String displayName, String avatar, Byte globalStatus, Byte globalRole,
+ Instant createdAt, Instant updatedAt) {
+ this.userId = userId;
+ this.displayName = displayName;
+ this.avatar = avatar;
+ this.globalStatus = globalStatus;
+ this.globalRole = globalRole;
+ this.createdAt = createdAt;
+ this.updatedAt = updatedAt;
+ }
+
+ public UUID getUserId() {
+ return userId;
+ }
+
+ public void setUserId(UUID userId) {
+ this.userId = userId;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public Byte getGlobalStatus() {
+ return globalStatus;
+ }
+
+ public void setGlobalStatus(Byte globalStatus) {
+ this.globalStatus = globalStatus;
+ }
+
+ public Byte getGlobalRole() {
+ return globalRole;
+ }
+
+ public void setGlobalRole(Byte globalRole) {
+ this.globalRole = globalRole;
+ }
+
+ public Instant getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Instant createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Instant getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(Instant updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/model/Credential.java b/core/src/main/java/net/miarma/backend/core/model/Credential.java
new file mode 100644
index 0000000..790b109
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/model/Credential.java
@@ -0,0 +1,177 @@
+package net.miarma.backend.core.model;
+
+import java.nio.ByteBuffer;
+import java.time.Instant;
+import java.util.UUID;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.PostLoad;
+import jakarta.persistence.PrePersist;
+import jakarta.persistence.PreUpdate;
+import jakarta.persistence.Table;
+import jakarta.persistence.Transient;
+import jakarta.persistence.UniqueConstraint;
+
+@Entity
+@Table(
+ name = "credentials",
+ uniqueConstraints = {
+ @UniqueConstraint(columnNames = {"service_id", "username"}),
+ @UniqueConstraint(columnNames = {"service_id", "email"})
+ }
+)
+public class Credential {
+
+ @Id
+ @Column(columnDefinition = "BINARY(16)")
+ private byte[] credentialIdBin;
+
+ @Column(name = "user_id", columnDefinition = "BINARY(16)")
+ private byte[] userIdBin;
+
+ @Transient
+ private UUID credentialId;
+
+ @Transient
+ private UUID userId;
+
+ @Column(name = "service_id")
+ private Byte serviceId;
+
+ private String username;
+ private String email;
+ private String password;
+
+ private Byte status;
+
+ @CreationTimestamp
+ private Instant createdAt;
+
+ @UpdateTimestamp
+ private Instant updatedAt;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "user_id", insertable = false, updatable = false)
+ private User user;
+
+ @PrePersist
+ @PreUpdate
+ private void prePersist() {
+ if (credentialId != null) {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
+ bb.putLong(credentialId.getMostSignificantBits());
+ bb.putLong(credentialId.getLeastSignificantBits());
+ credentialIdBin = bb.array();
+ }
+ if (userId != null) {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
+ bb.putLong(userId.getMostSignificantBits());
+ bb.putLong(userId.getLeastSignificantBits());
+ userIdBin = bb.array();
+ }
+ }
+
+ @PostLoad
+ private void postLoad() {
+ if (credentialIdBin != null) {
+ ByteBuffer bb = ByteBuffer.wrap(credentialIdBin);
+ long high = bb.getLong();
+ long low = bb.getLong();
+ credentialId = new UUID(high, low);
+ }
+ if (userIdBin != null) {
+ ByteBuffer bb = ByteBuffer.wrap(userIdBin);
+ long high = bb.getLong();
+ long low = bb.getLong();
+ userId = new UUID(high, low);
+ }
+ }
+
+ public UUID getCredentialId() {
+ return credentialId;
+ }
+
+ public void setCredentialId(UUID credentialId) {
+ this.credentialId = credentialId;
+ }
+
+ public UUID getUserId() {
+ return userId;
+ }
+
+ public void setUserId(UUID userId) {
+ this.userId = userId;
+ }
+
+ public Byte getServiceId() {
+ return serviceId;
+ }
+
+ public void setServiceId(Byte serviceId) {
+ this.serviceId = serviceId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public Byte getStatus() {
+ return status;
+ }
+
+ public void setStatus(Byte status) {
+ this.status = status;
+ }
+
+ public Instant getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Instant createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Instant getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(Instant updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/model/File.java b/core/src/main/java/net/miarma/backend/core/model/File.java
new file mode 100644
index 0000000..8d36a25
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/model/File.java
@@ -0,0 +1,106 @@
+package net.miarma.backend.core.model;
+
+import java.time.Instant;
+import java.util.UUID;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.PrePersist;
+import jakarta.persistence.Table;
+import jakarta.persistence.Transient;
+
+@Entity
+@Table(name = "files")
+public class File {
+
+ @Id
+ @Column(name = "file_id", columnDefinition = "BINARY(16)")
+ private byte[] fileIdBin;
+
+ @Transient
+ private UUID fileId;
+
+ @Column(name = "file_name", nullable = false, length = 128)
+ private String fileName;
+
+ @Column(name = "file_path", nullable = false, length = 256)
+ private String filePath;
+
+ @Column(name = "mime_type", nullable = false, length = 64)
+ private String mimeType;
+
+ @Column(name = "uploaded_by", columnDefinition = "BINARY(16)", nullable = false)
+ private byte[] uploadedByBin;
+
+ @Transient
+ private UUID uploadedBy;
+
+ @Column(name = "uploaded_at", nullable = false, updatable = false)
+ private Instant uploadedAt;
+
+ @Column(name = "context", nullable = false)
+ private Short context;
+
+ @PrePersist
+ public void prePersist() {
+ if (fileId == null) {
+ fileId = UUID.randomUUID();
+ }
+ if (uploadedAt == null) {
+ uploadedAt = Instant.now();
+ }
+ }
+
+ public UUID getFileId() {
+ return fileId;
+ }
+
+ public void setFileId(UUID fileId) {
+ this.fileId = fileId;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getFilePath() {
+ return filePath;
+ }
+
+ public void setFilePath(String filePath) {
+ this.filePath = filePath;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ public void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ public UUID getUploadedBy() {
+ return uploadedBy;
+ }
+
+ public void setUploadedBy(UUID uploadedBy) {
+ this.uploadedBy = uploadedBy;
+ }
+
+ public Instant getUploadedAt() {
+ return uploadedAt;
+ }
+
+ public Short getContext() {
+ return context;
+ }
+
+ public void setContext(Short context) {
+ this.context = context;
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/model/User.java b/core/src/main/java/net/miarma/backend/core/model/User.java
new file mode 100644
index 0000000..5022bc3
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/model/User.java
@@ -0,0 +1,123 @@
+package net.miarma.backend.core.model;
+
+import java.nio.ByteBuffer;
+import java.time.Instant;
+import java.util.UUID;
+
+import org.hibernate.annotations.CreationTimestamp;
+import org.hibernate.annotations.UpdateTimestamp;
+
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+import jakarta.persistence.PostLoad;
+import jakarta.persistence.PrePersist;
+import jakarta.persistence.PreUpdate;
+import jakarta.persistence.Table;
+import jakarta.persistence.Transient;
+
+@Entity
+@Table(name = "users")
+public class User {
+
+ @Id
+ @Column(name = "user_id", columnDefinition = "BINARY(16)")
+ private byte[] userIdBin;
+
+ @Transient
+ private UUID userId;
+
+ @Column(name = "display_name", nullable = false)
+ private String displayName;
+
+ private String avatar;
+
+ @Column(name = "global_status")
+ private Byte globalStatus;
+
+ @Column(name = "global_role")
+ private Byte globalRole;
+
+ @CreationTimestamp
+ private Instant createdAt;
+
+ @UpdateTimestamp
+ private Instant updatedAt;
+
+ @PrePersist
+ @PreUpdate
+ private void prePersist() {
+ if (userId != null) {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
+ bb.putLong(userId.getMostSignificantBits());
+ bb.putLong(userId.getLeastSignificantBits());
+ userIdBin = bb.array();
+ }
+ }
+
+ @PostLoad
+ private void postLoad() {
+ if (userIdBin != null) {
+ ByteBuffer bb = ByteBuffer.wrap(userIdBin);
+ long high = bb.getLong();
+ long low = bb.getLong();
+ userId = new UUID(high, low);
+ }
+ }
+
+ public UUID getUserId() {
+ return userId;
+ }
+
+ public void setUserId(UUID userId) {
+ this.userId = userId;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+
+ public Byte getGlobalStatus() {
+ return globalStatus;
+ }
+
+ public void setGlobalStatus(Byte globalStatus) {
+ this.globalStatus = globalStatus;
+ }
+
+ public Byte getGlobalRole() {
+ return globalRole;
+ }
+
+ public void setGlobalRole(Byte globalRole) {
+ this.globalRole = globalRole;
+ }
+
+ public Instant getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Instant createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Instant getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(Instant updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/repository/CredentialRepository.java b/core/src/main/java/net/miarma/backend/core/repository/CredentialRepository.java
new file mode 100644
index 0000000..a082a50
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/repository/CredentialRepository.java
@@ -0,0 +1,22 @@
+package net.miarma.backend.core.repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import net.miarma.backend.core.model.Credential;
+
+public interface CredentialRepository extends JpaRepository {
+
+ Optional findByServiceIdAndUsername(short serviceId, String username);
+
+ Optional findByServiceIdAndEmail(short serviceId, String email);
+
+ Optional findByUserIdAndServiceId(UUID userId, short serviceId);
+
+ List findByUserId(UUID userId);
+
+}
+
diff --git a/core/src/main/java/net/miarma/backend/core/repository/FileRepository.java b/core/src/main/java/net/miarma/backend/core/repository/FileRepository.java
new file mode 100644
index 0000000..95919ba
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/repository/FileRepository.java
@@ -0,0 +1,20 @@
+package net.miarma.backend.core.repository;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import net.miarma.backend.core.model.File;
+
+public interface FileRepository extends JpaRepository {
+
+ Optional findById(UUID fileId);
+
+ List findByUploadedBy(UUID uploadedBy);
+
+ List findByContext(short context);
+
+ List findByUploadedByAndContext(UUID uploadedBy, short context);
+}
\ No newline at end of file
diff --git a/core/src/main/java/net/miarma/backend/core/repository/UserRepository.java b/core/src/main/java/net/miarma/backend/core/repository/UserRepository.java
new file mode 100644
index 0000000..3973cd0
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/repository/UserRepository.java
@@ -0,0 +1,11 @@
+package net.miarma.backend.core.repository;
+
+import java.util.UUID;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import net.miarma.backend.core.model.User;
+
+public interface UserRepository extends JpaRepository {
+
+}
diff --git a/core/src/main/java/net/miarma/backend/core/service/AuthService.java b/core/src/main/java/net/miarma/backend/core/service/AuthService.java
new file mode 100644
index 0000000..754aa82
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/service/AuthService.java
@@ -0,0 +1,46 @@
+package net.miarma.backend.core.service;
+
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import net.miarma.backend.core.dto.LoginRequest;
+import net.miarma.backend.core.dto.LoginResponse;
+import net.miarma.backend.core.dto.UserDto;
+import net.miarma.backend.core.model.Credential;
+
+@Service
+public class AuthService {
+
+ private final CredentialService credentialService;
+ private final JwtService jwtService;
+ private final PasswordEncoder passwordEncoder;
+
+ public AuthService(CredentialService credentialService, JwtService jwtService,
+ PasswordEncoder passwordEncoder) {
+ this.credentialService = credentialService;
+ this.jwtService = jwtService;
+ this.passwordEncoder = passwordEncoder;
+ }
+
+ public LoginResponse login(LoginRequest request) {
+ Credential cred = credentialService.getByUserIdAndService(request.getServiceId(), request.getUsername());
+
+ if (!passwordEncoder.matches(request.getPassword(), cred.getPassword())) {
+ throw new RuntimeException("Invalid credentials");
+ }
+
+ String token = jwtService.generateToken(cred.getUserId(), request.getServiceId());
+
+ UserDto userDto = new UserDto(
+ cred.getUser().getUserId(),
+ cred.getUser().getDisplayName(),
+ cred.getUser().getAvatar(),
+ cred.getUser().getGlobalStatus(),
+ cred.getUser().getGlobalRole(),
+ cred.getUser().getCreatedAt(),
+ cred.getUser().getUpdatedAt()
+ );
+
+ return new LoginResponse(token, request.getServiceId(), userDto);
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/service/CredentialService.java b/core/src/main/java/net/miarma/backend/core/service/CredentialService.java
new file mode 100644
index 0000000..7d16a68
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/service/CredentialService.java
@@ -0,0 +1,49 @@
+package net.miarma.backend.core.service;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import net.miarma.backend.core.model.Credential;
+import net.miarma.backend.core.repository.CredentialRepository;
+
+@Service
+@Transactional
+public class CredentialService {
+
+ private final CredentialRepository credentialRepository;
+
+ public CredentialService(CredentialRepository credentialRepository) {
+ this.credentialRepository = credentialRepository;
+ }
+
+ public Credential getById(UUID id) {
+ return credentialRepository.findById(id)
+ .orElseThrow(() -> new RuntimeException("Credential not found"));
+ }
+
+ public Credential create(Credential credential) {
+ // TODO: validate duplicates here
+ return credentialRepository.save(credential);
+ }
+
+ public List getByUserId(UUID userId) {
+ List creds = credentialRepository.findByUserId(userId);
+ if (creds.isEmpty()) {
+ throw new RuntimeException("User has no credentials");
+ }
+ return creds;
+ }
+
+ public Credential getByUserIdAndService(short serviceId, String username) {
+ return credentialRepository.findByServiceIdAndUsername(serviceId, username)
+ .orElseThrow(() -> new RuntimeException("Credential not found in this site"));
+ }
+
+ public Credential getForLogin(short serviceId, String username) {
+ return credentialRepository.findByServiceIdAndUsername(serviceId, username)
+ .orElseThrow(() -> new RuntimeException("Invalid credentials"));
+ }
+}
diff --git a/core/src/main/java/net/miarma/backend/core/service/FileService.java b/core/src/main/java/net/miarma/backend/core/service/FileService.java
new file mode 100644
index 0000000..91001a1
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/service/FileService.java
@@ -0,0 +1,46 @@
+package net.miarma.backend.core.service;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import net.miarma.backend.core.model.File;
+import net.miarma.backend.core.repository.FileRepository;
+
+@Service
+@Transactional
+public class FileService {
+
+ private final FileRepository fileRepository;
+
+ public FileService(FileRepository fileRepository) {
+ this.fileRepository = fileRepository;
+ }
+
+ public File get(UUID fileId) {
+ return fileRepository.findById(fileId)
+ .orElseThrow(() -> new RuntimeException("File not found"));
+ }
+
+ public List listByUser(UUID userId) {
+ return fileRepository.findByUploadedBy(userId);
+ }
+
+ public List listByContext(short context) {
+ return fileRepository.findByContext(context);
+ }
+
+ public File create(File file) {
+ return fileRepository.save(file);
+ }
+
+ public void delete(UUID fileId) {
+ if (!fileRepository.existsById(fileId)) {
+ throw new RuntimeException("File not found");
+ }
+ fileRepository.deleteById(fileId);
+ }
+}
+
diff --git a/core/src/main/java/net/miarma/backend/core/service/JwtService.java b/core/src/main/java/net/miarma/backend/core/service/JwtService.java
new file mode 100644
index 0000000..fa87a6e
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/service/JwtService.java
@@ -0,0 +1,56 @@
+package net.miarma.backend.core.service;
+
+import io.jsonwebtoken.*;
+import io.jsonwebtoken.security.Keys;
+import org.springframework.stereotype.Service;
+
+import java.security.Key;
+import java.util.Date;
+import java.util.UUID;
+
+@Service
+public class JwtService {
+
+ private final String secret = "miarma-esto-es-un-secreto-super-largo-para-jwt-1234567890";
+ private final Key key = Keys.hmacShaKeyFor(secret.getBytes());
+
+ private final long expiration = 3600_000;
+
+ public String generateToken(UUID userId, short serviceId) {
+ Date now = new Date();
+ Date exp = new Date(now.getTime() + expiration);
+
+ return Jwts.builder()
+ .setSubject(userId.toString())
+ .claim("service", serviceId)
+ .setIssuedAt(now)
+ .setExpiration(exp)
+ .signWith(key, SignatureAlgorithm.HS256)
+ .compact();
+ }
+
+ public boolean validateToken(String token) {
+ try {
+ Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token);
+ return true;
+ } catch (JwtException | IllegalArgumentException e) {
+ return false;
+ }
+ }
+
+ public UUID getUserId(String token) {
+ Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
+ return UUID.fromString(claims.getSubject());
+ }
+
+ public short getServiceId(String token) {
+ Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
+ return ((Number) claims.get("service")).shortValue();
+ }
+
+ public Date getExpiration(String token) {
+ Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody();
+ return claims.getExpiration();
+ }
+}
+
diff --git a/core/src/main/java/net/miarma/backend/core/service/UserService.java b/core/src/main/java/net/miarma/backend/core/service/UserService.java
new file mode 100644
index 0000000..a9b9626
--- /dev/null
+++ b/core/src/main/java/net/miarma/backend/core/service/UserService.java
@@ -0,0 +1,41 @@
+package net.miarma.backend.core.service;
+
+import java.util.UUID;
+
+import org.springframework.stereotype.Service;
+
+import jakarta.transaction.Transactional;
+import net.miarma.backend.core.model.User;
+import net.miarma.backend.core.repository.UserRepository;
+
+@Service
+@Transactional
+public class UserService {
+ private final UserRepository userRepository;
+
+ public UserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ public User getById(UUID userId) {
+ return userRepository.findById(userId)
+ .orElseThrow(() -> new RuntimeException("User not found"));
+ }
+
+ public User create(User user) {
+ // TODO: basic validation
+ return userRepository.save(user);
+ }
+
+ public User update(User user) {
+ if(!userRepository.existsById(user.getUserId()))
+ throw new RuntimeException("User not found");
+ return userRepository.save(user);
+ }
+
+ public void delete(UUID userId) {
+ if(!userRepository.existsById(userId))
+ throw new RuntimeException("User not found");
+ userRepository.deleteById(userId);
+ }
+}
diff --git a/core/src/main/resources/application.yml b/core/src/main/resources/application.yml
new file mode 100644
index 0000000..76c7404
--- /dev/null
+++ b/core/src/main/resources/application.yml
@@ -0,0 +1,12 @@
+spring:
+ datasource:
+ url: jdbc:mariadb://localhost:3306/miarma_v2
+ username: admin
+ password: ositovito
+ jpa:
+ hibernate:
+ ddl-auto: update
+ show-sql: true
+ properties:
+ hibernate:
+ format_sql: true
diff --git a/huertos/.classpath b/huertos/.classpath
new file mode 100644
index 0000000..f7e4a1d
--- /dev/null
+++ b/huertos/.classpath
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/huertos/.gitignore b/huertos/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/huertos/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/huertos/.project b/huertos/.project
new file mode 100644
index 0000000..85aa542
--- /dev/null
+++ b/huertos/.project
@@ -0,0 +1,23 @@
+
+
+ huertos
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/huertos/.settings/org.eclipse.jdt.core.prefs b/huertos/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/huertos/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/huertos/.settings/org.eclipse.m2e.core.prefs b/huertos/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/huertos/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/huertos/pom.xml b/huertos/pom.xml
new file mode 100644
index 0000000..54dd97b
--- /dev/null
+++ b/huertos/pom.xml
@@ -0,0 +1,51 @@
+
+ 4.0.0
+
+ net.miarma
+ backend
+ 1.0.0
+
+ huertos
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ runtime
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+
\ No newline at end of file
diff --git a/minecraft/.classpath b/minecraft/.classpath
new file mode 100644
index 0000000..f7e4a1d
--- /dev/null
+++ b/minecraft/.classpath
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/minecraft/.gitignore b/minecraft/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/minecraft/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/minecraft/.project b/minecraft/.project
new file mode 100644
index 0000000..b356ec0
--- /dev/null
+++ b/minecraft/.project
@@ -0,0 +1,23 @@
+
+
+ minecraft
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/minecraft/.settings/org.eclipse.jdt.core.prefs b/minecraft/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/minecraft/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/minecraft/.settings/org.eclipse.m2e.core.prefs b/minecraft/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/minecraft/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/minecraft/pom.xml b/minecraft/pom.xml
new file mode 100644
index 0000000..a72edf0
--- /dev/null
+++ b/minecraft/pom.xml
@@ -0,0 +1,51 @@
+
+ 4.0.0
+
+ net.miarma
+ backend
+ 1.0.0
+
+ minecraft
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ runtime
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+
\ No newline at end of file
diff --git a/mpaste/.classpath b/mpaste/.classpath
new file mode 100644
index 0000000..f7e4a1d
--- /dev/null
+++ b/mpaste/.classpath
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpaste/.gitignore b/mpaste/.gitignore
new file mode 100644
index 0000000..b83d222
--- /dev/null
+++ b/mpaste/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/mpaste/.project b/mpaste/.project
new file mode 100644
index 0000000..499668e
--- /dev/null
+++ b/mpaste/.project
@@ -0,0 +1,23 @@
+
+
+ mpaste
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/mpaste/.settings/org.eclipse.jdt.core.prefs b/mpaste/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/mpaste/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/mpaste/.settings/org.eclipse.m2e.core.prefs b/mpaste/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/mpaste/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/mpaste/pom.xml b/mpaste/pom.xml
new file mode 100644
index 0000000..4a8b476
--- /dev/null
+++ b/mpaste/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+
+ net.miarma
+ backend
+ 1.0.0
+
+ mpaste
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ runtime
+
+
+
+ io.jsonwebtoken
+ jjwt-api
+ 0.11.5
+
+
+ io.jsonwebtoken
+ jjwt-impl
+ 0.11.5
+ runtime
+
+
+ io.jsonwebtoken
+ jjwt-jackson
+ 0.11.5
+ runtime
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..4e76ab2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,50 @@
+
+ 4.0.0
+
+ net.miarma
+ backend
+ 1.0.0
+ pom
+
+
+ core
+ huertos
+ minecraft
+ cine
+ mpaste
+ websocket
+
+
+
+ 25
+ 4.0.1
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ ${spring.boot.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a5622f8
--- /dev/null
+++ b/target/classes/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Build-Jdk-Spec: 21
+Created-By: Maven Integration for Eclipse
+
diff --git a/target/classes/META-INF/maven/net.miarma/backend/pom.properties b/target/classes/META-INF/maven/net.miarma/backend/pom.properties
new file mode 100644
index 0000000..e27ed27
--- /dev/null
+++ b/target/classes/META-INF/maven/net.miarma/backend/pom.properties
@@ -0,0 +1,7 @@
+#Generated by Maven Integration for Eclipse
+#Fri Jan 16 02:26:12 CET 2026
+artifactId=backend
+groupId=net.miarma
+m2e.projectLocation=/home/jomaa/git/miarma-backend
+m2e.projectName=backend
+version=1.0.0
diff --git a/target/classes/META-INF/maven/net.miarma/backend/pom.xml b/target/classes/META-INF/maven/net.miarma/backend/pom.xml
new file mode 100644
index 0000000..3b1fee6
--- /dev/null
+++ b/target/classes/META-INF/maven/net.miarma/backend/pom.xml
@@ -0,0 +1,6 @@
+
+ 4.0.0
+ net.miarma
+ backend
+ 1.0.0
+
\ No newline at end of file