diff --git a/walkguide-backend/demo/pom.xml b/walkguide-backend/demo/pom.xml
index 82bb89f..a381d17 100644
--- a/walkguide-backend/demo/pom.xml
+++ b/walkguide-backend/demo/pom.xml
@@ -65,7 +65,7 @@
org.projectlombok
lombok
- true
+ 1.18.36
@@ -137,6 +137,7 @@
org.projectlombok
lombok
+ 1.18.36
diff --git a/walkguide-backend/demo/src/main/java/com/walkguide/DemoApplication.java b/walkguide-backend/demo/src/main/java/com/walkguide/WalkGuideApplication.java
similarity index 53%
rename from walkguide-backend/demo/src/main/java/com/walkguide/DemoApplication.java
rename to walkguide-backend/demo/src/main/java/com/walkguide/WalkGuideApplication.java
index 2a650c0..960f41c 100644
--- a/walkguide-backend/demo/src/main/java/com/walkguide/DemoApplication.java
+++ b/walkguide-backend/demo/src/main/java/com/walkguide/WalkGuideApplication.java
@@ -4,10 +4,8 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
-public class DemoApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(DemoApplication.class, args);
- }
-
+public class WalkGuideApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(WalkGuideApplication.class, args);
+ }
}
diff --git a/walkguide-backend/demo/src/main/java/com/walkguide/config/DataSeeder.java b/walkguide-backend/demo/src/main/java/com/walkguide/config/DataSeeder.java
index 2fc4f89..e1f54ab 100644
--- a/walkguide-backend/demo/src/main/java/com/walkguide/config/DataSeeder.java
+++ b/walkguide-backend/demo/src/main/java/com/walkguide/config/DataSeeder.java
@@ -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.");
}
diff --git a/walkguide-backend/demo/src/main/java/com/walkguide/config/OpenApiConfig.java b/walkguide-backend/demo/src/main/java/com/walkguide/config/OpenApiConfig.java
index 6f0afc9..d012cfb 100644
--- a/walkguide-backend/demo/src/main/java/com/walkguide/config/OpenApiConfig.java
+++ b/walkguide-backend/demo/src/main/java/com/walkguide/config/OpenApiConfig.java
@@ -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")));
}
-}
\ No newline at end of file
+}
diff --git a/walkguide-backend/demo/src/main/java/com/walkguide/config/SecurityConfig.java b/walkguide-backend/demo/src/main/java/com/walkguide/config/SecurityConfig.java
index 1ece305..2f25ba7 100644
--- a/walkguide-backend/demo/src/main/java/com/walkguide/config/SecurityConfig.java
+++ b/walkguide-backend/demo/src/main/java/com/walkguide/config/SecurityConfig.java
@@ -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();
}
-}
\ No newline at end of file
+
+ @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;
+ }
+}
diff --git a/walkguide-backend/demo/src/main/java/com/walkguide/controller/AuthController.java b/walkguide-backend/demo/src/main/java/com/walkguide/controller/AuthController.java
index 3b9f2a2..1fbadd8 100644
--- a/walkguide-backend/demo/src/main/java/com/walkguide/controller/AuthController.java
+++ b/walkguide-backend/demo/src/main/java/com/walkguide/controller/AuthController.java
@@ -1,36 +1,57 @@
package com.walkguide.controller;
-import java.util.Map;
-
-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.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
import com.walkguide.dto.ApiResponse;
-import com.walkguide.dto.AuthRequest;
+import com.walkguide.dto.request.*;
+import com.walkguide.dto.response.AuthDataResponse;
+import com.walkguide.security.SecurityHelper;
import com.walkguide.service.AuthService;
-
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
@RestController
-@RequestMapping("/api/auth")
+@RequestMapping("/api/v1/auth")
@RequiredArgsConstructor
public class AuthController {
private final AuthService authService;
- @PostMapping("/login")
- public ResponseEntity>> login(@Valid @RequestBody AuthRequest request) {
-
- // Panggil service buat cek password dan bikin token
- Map tokenData = authService.login(request);
-
- // Bungkus pakai ApiResponse biar sesuai standar Dosen lu!
- ApiResponse