start backend

This commit is contained in:
SlimusMinus
2026-03-26 00:21:30 +03:00
parent 611b1c82ad
commit 263242e469
56 changed files with 1524 additions and 23 deletions

View File

@@ -0,0 +1,46 @@
package com.krylov.refound.util;
import java.util.List;
import java.util.Map;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
public class JwtHandshakeInterceptor implements HandshakeInterceptor {
@Override
public boolean beforeHandshake(
ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map<String, Object> attributes
) throws Exception {
List<String> auth = request.getHeaders().get("Authorization");
if (auth == null || auth.isEmpty()) {
return false; // запретить подключение
}
String token = auth.get(0).replace("Bearer ", "");
// 🔥 проверяем JWT
String userEmail = JwtUtils.validateTokenAndGetEmail(token);
if (userEmail == null) {
return false;
}
attributes.put("userEmail", userEmail);
return true;
}
@Override
public void afterHandshake(
ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Exception exception
) { }
}

View File

@@ -0,0 +1,23 @@
package com.krylov.refound.util;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.stereotype.Component;
@Component
public class JwtUtils {
private static final String SECRET = "SECRET_KEY"; // заменить на env var
public static String validateTokenAndGetEmail(String token) {
try {
return Jwts.parserBuilder()
.setSigningKey(Keys.hmacShaKeyFor(SECRET.getBytes()))
.build()
.parseClaimsJws(token)
.getBody()
.getSubject();
} catch (Exception e) {
return null;
}
}
}

View File

@@ -0,0 +1,58 @@
package com.krylov.refound.util;
import com.krylov.refound.dto.PostFilter;
import com.krylov.refound.entity.Post;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import org.springframework.data.jpa.domain.Specification;
public class PostSpecification {
public static Specification<Post> withFilter(PostFilter filter) {
return (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (filter.getType() != null) {
predicates.add(cb.equal(root.get("type"), filter.getType()));
}
if (filter.getCity() != null) {
predicates.add(cb.equal(root.get("city"), filter.getCity()));
}
if (filter.getCategory() != null) {
predicates.add(cb.equal(root.get("category"), filter.getCategory()));
}
if (filter.getDistrict() != null) {
predicates.add(cb.equal(root.get("district"), filter.getDistrict()));
}
if (filter.getSearch() != null && !filter.getSearch().isBlank()) {
String search = "%" + filter.getSearch().toLowerCase() + "%";
predicates.add(cb.or(
cb.like(cb.lower(root.get("title")), search),
cb.like(cb.lower(root.get("description")), search)
));
}
if (filter.getLat() != null && filter.getLng() != null && filter.getRadius() != null) {
Expression<Double> distance = cb.function(
"6371 * acos(cos(radians(?1)) * cos(radians(latitude)) * " +
"cos(radians(longitude) - radians(?2)) + sin(radians(?1)) * sin(radians(latitude)))",
Double.class,
cb.literal(filter.getLat()),
cb.literal(filter.getLng())
);
predicates.add(cb.lessThanOrEqualTo(distance, filter.getRadius()));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
}
}

View File

@@ -1,4 +1,11 @@
package com.krylov.refound.util;
import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityUtils {
public static String getCurrentUserEmail() {
return SecurityContextHolder.getContext()
.getAuthentication()
.getName();
}
}