update backend

This commit is contained in:
Wowieee4
2026-05-04 11:20:53 +07:00
parent c8d9eefa74
commit feb8e78b0c
103 changed files with 3107 additions and 304 deletions
@@ -18,29 +18,22 @@ public class DataSeeder implements CommandLineRunner {
public void run(String... args) throws Exception {
if (userRepository.count() == 0) {
// 1. Buat Guardian (tanpa connected_to dulu)
User guardian = User.builder()
.email("guardian@walkguide.com")
.password(passwordEncoder.encode("guardian123"))
.role("ROLE_GUARDIAN")
.build();
guardian = userRepository.save(guardian);
userRepository.save(guardian);
// 2. Buat User Tunanetra, langsung sambungkan ke Guardian
User user = User.builder()
.email("user@walkguide.com")
.password(passwordEncoder.encode("user123"))
.role("ROLE_USER")
.connectedTo(guardian)
.build();
user = userRepository.save(user);
// 3. Update Guardian -> sambungkan balik ke User yang dijaganya
guardian.setConnectedTo(user);
userRepository.save(guardian);
userRepository.save(user);
System.out.println("DataSeeder: Guardian (" + guardian.getId()
+ ") <-> User (" + user.getId() + ") berhasil dihubungkan!");
+ ") dan User (" + user.getId() + ") berhasil dibuat!");
} else {
System.out.println("DataSeeder: Database sudah ada data, skip seeding.");
}
@@ -2,6 +2,9 @@ package com.walkguide.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.Components;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -12,8 +15,16 @@ public class OpenApiConfig {
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Walk Guide API")
.version("1.0")
.description("API Documentation for Walk Guide Application (Final Exam)"));
.title("WalkGuide API")
.version("1.0")
.description("API Documentation for WalkGuide Application - Final Exam"))
.addSecurityItem(new SecurityRequirement().addList("Bearer Auth"))
.components(new Components()
.addSecuritySchemes("Bearer Auth",
new SecurityScheme()
.name("Bearer Auth")
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")));
}
}
}
@@ -1,5 +1,7 @@
package com.walkguide.config;
import com.walkguide.security.JwtAuthFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -8,43 +10,64 @@ 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;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import com.walkguide.security.JwtAuthFilter;
import java.util.List;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
// MESIN HASHING PASSWORD: Biar password yang disimpan di database gak bisa dibaca langsung, kita enkripsi dulu pake BCrypt
private final JwtAuthFilter jwtAuthFilter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// Aturan jalan masuk ke API kita:
// Jangan lupa inject filter-nya di atas (tambahin parameter JwtAuthFilter jwtAuthFilter)
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, JwtAuthFilter jwtAuthFilter) throws Exception {
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.cors(cors -> cors.configurationSource(request -> {
var corsConfig = new org.springframework.web.cors.CorsConfiguration();
corsConfig.setAllowedOriginPatterns(java.util.List.of("http://localhost:*", "http://127.0.0.1:*"));
corsConfig.setAllowedMethods(java.util.List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
corsConfig.setAllowedHeaders(java.util.List.of("*"));
corsConfig.setAllowCredentials(true);
return corsConfig;
}))
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/**", "/swagger-ui/**", "/v3/api-docs/**").permitAll() // Login & Swagger bebas
.requestMatchers("/api/guardian/**").hasRole("GUARDIAN") // Khusus Guardian
.requestMatchers("/api/user/**").hasRole("USER") // Khusus Tunanetra
// Public routes
.requestMatchers(
"/api/v1/auth/**",
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**",
"/ws/**"
).permitAll()
// Guardian only
.requestMatchers("/api/v1/guardian/**").hasRole("GUARDIAN")
// User only
.requestMatchers("/api/v1/user/**").hasRole("USER")
// Both roles (authenticated)
.requestMatchers("/api/v1/shared/**").authenticated()
.anyRequest().authenticated()
)
// TARUH SATPAM DI SINI
.addFilterBefore(jwtAuthFilter, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.class);
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
// Allow semua origin untuk testing dengan HP berbeda di jaringan yang sama
config.setAllowedOriginPatterns(List.of("*"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
config.setAllowedHeaders(List.of("*"));
config.setAllowCredentials(false); // false agar bisa pakai wildcard origin
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}