added start backend

This commit is contained in:
SlimusMinus
2026-03-24 00:34:04 +03:00
commit 611b1c82ad
38 changed files with 715 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package com.krylov.refound;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ReFoundApplication {
public static void main(String[] args) {
SpringApplication.run(ReFoundApplication.class, args);
}
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.config;
public class SecurityConfig {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.controller;
public class AuthController {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.controller;
public class PostController {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.dto;
public class AuthRequest {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.dto;
public class AuthResponse {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.dto;
public class PostRequest {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.dto;
public class PostResponse {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.entity;
public class Image {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.entity;
public class Post {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.entity;
public class User {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.enums;
public enum ErrorCode {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.enums;
public enum PostStatus {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.enums;
public enum PostType {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.exception;
public class ApiException {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.exception;
public class ErrorResponse {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.exception;
public class GlobalExceptionHandler {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.mapper;
public class PostMapper {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.repository;
public interface PostRepository {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.repository;
public interface UserRepository {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.service;
public class PostService {
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.service;
public class UserService {
}

View File

@@ -0,0 +1,51 @@
package com.krylov.refound.service;
import com.krylov.refound.dto.AuthRequest;
import com.krylov.refound.dto.AuthResponse;
import com.krylov.refound.entity.User;
import com.krylov.refound.enums.ErrorCode;
import com.krylov.refound.exception.ApiException;
import com.krylov.refound.repository.UserRepository;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class AuthService {
private final UserRepository repository;
private final PasswordEncoder passwordEncoder;
private final JwtService jwtService;
public AuthResponse register(AuthRequest request) {
if (repository.findByEmail(request.getEmail()).isPresent()) {
throw new ApiException(ErrorCode.BAD_REQUEST, "Email already exists", HttpStatus.BAD_REQUEST);
}
User user = new User();
user.setEmail(request.getEmail());
user.setPassword(passwordEncoder.encode(request.getPassword()));
user.setCreatedAt(LocalDateTime.now());
repository.save(user);
String token = jwtService.generateToken(user.getEmail());
return new AuthResponse(token);
}
public AuthResponse login(AuthRequest request) {
User user = repository.findByEmail(request.getEmail())
.orElseThrow(() -> new ApiException(ErrorCode.NOT_FOUND, "User not found", HttpStatus.NOT_FOUND));
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
throw new ApiException(ErrorCode.BAD_REQUEST, "Invalid password", HttpStatus.BAD_REQUEST);
}
String token = jwtService.generateToken(user.getEmail());
return new AuthResponse(token);
}
}

View File

@@ -0,0 +1,27 @@
package com.krylov.refound.service;
import com.krylov.refound.entity.User;
import com.krylov.refound.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CustomUserDetailsService implements UserDetailsService {
private final UserRepository repository;
@Override
public UserDetails loadUserByUsername(String email) {
User user = repository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
return org.springframework.security.core.userdetails.User
.withUsername(user.getEmail())
.password(user.getPassword())
.authorities("USER")
.build();
}
}

View File

@@ -0,0 +1,55 @@
package com.krylov.refound.service;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
@Component
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
private final JwtService jwtService;
private final CustomUserDetailsService userDetailsService;
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
String token = header.substring(7);
String email = jwtService.extractEmail(token);
if (email != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(email);
UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
SecurityContextHolder.getContext().setAuthentication(auth);
}
filterChain.doFilter(request, response);
}
}

View File

@@ -0,0 +1,29 @@
package com.krylov.refound.service;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.util.Date;
import org.springframework.stereotype.Service;
@Service
public class JwtService {
private final String SECRET = "very_secret_key_123";
public String generateToken(String email) {
return Jwts.builder()
.setSubject(email)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 1 день
.signWith(Keys.hmacShaKeyFor(SECRET.getBytes()))
.compact();
}
public String extractEmail(String token) {
return Jwts.parserBuilder()
.setSigningKey(SECRET.getBytes())
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}

View File

@@ -0,0 +1,4 @@
package com.krylov.refound.util;
public class SecurityUtils {
}

View File

@@ -0,0 +1 @@
spring.application.name=ReFound