content: package net.alex9849.cocktailpi.config.security;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.http.HttpMethod;
  import org.springframework.security.authentication.AuthenticationManager;
  import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
  import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
  import org.springframework.security.config.core.GrantedAuthorityDefaults;
  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 WebSecurityConfig {
      @Autowired
      UserDetailsServiceImpl userDetailsService;
  
      @Autowired
      private AuthEntryPointJwt unauthorizedHandler;
  
      @Bean
      public AuthTokenFilter authenticationJwtTokenFilter() {
          return new AuthTokenFilter();
      }
  
      @Bean
      GrantedAuthorityDefaults grantedAuthorityDefaults() {
          return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
      }
  
      @Bean
      public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration)
              throws Exception {
          return authenticationConfiguration.getAuthenticationManager();
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Bean
      public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
          http
                  .authorizeHttpRequests((authorizeHttpRequests) ->
                          authorizeHttpRequests
                                  .requestMatchers(HttpMethod.OPTIONS).permitAll()
                                  .requestMatchers("/websocket/**").permitAll()
                                  .requestMatchers("/api/auth/refreshToken").authenticated()
                                  .requestMatchers("/api/auth/**").permitAll()
                                  .requestMatchers("/api/recipe/*/image").permitAll()
                                  .requestMatchers("/api/collection/*/image").permitAll()
                                  .requestMatchers("/api/ingredient/*/image").permitAll()
                                  .requestMatchers(HttpMethod.GET, "/api/system/settings/appearance").permitAll()
                                  .requestMatchers(HttpMethod.GET, "/api/system/version").permitAll()
                                  .requestMatchers("/api/**").authenticated()
                                  .requestMatchers("/**").permitAll()
                  )
                  .exceptionHandling(eh -> eh.authenticationEntryPoint(unauthorizedHandler))
                  .sessionManagement(c -> c.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                  .csrf(AbstractHttpConfigurer::disable)
                  .cors(AbstractHttpConfigurer::disable)
                  .addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class)
                  .headers(c -> c.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable));
          return http.build();
      }
  }
  