= Други Развојни Активности = == Анализа на перформанси == ---- == Безбедност и заштита == === JWT Token Authorization (Spring Security) === JWT е stateless начин на автентикација - серверот НЕ чува информации за активни сесии во база, туку сите потребни податоци се енкодирани во самиот токен кој корисникот го чува локално. JWT содржи енкодирани информации: user_id, email, role, expiry. Имплементацијата во `SecurityConfig.java` дефинира кои endpoints се јавни и кои бараат автентикација, со посебни правила за ADMIN: {{{ // SecurityConfig.java @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .cors(cors -> cors.configurationSource(corsConfigurationSource())) .csrf(csrf -> csrf.disable()) .authorizeHttpRequests(auth -> auth // Public endpoints - no token required .requestMatchers("/api/auth/**").permitAll() .requestMatchers("/api/stocks/**").permitAll() .requestMatchers("/ws/**", "/topic/**").permitAll() .requestMatchers("/api/history/**").permitAll() // Admin only - role-based access control .requestMatchers("/api/trades/*/approve").hasAuthority("ADMIN") .requestMatchers("/api/trades/*/decline").hasAuthority("ADMIN") .requestMatchers("/api/trades/pending").hasAuthority("ADMIN") // Authenticated users .requestMatchers("/api/trades/**").authenticated() .requestMatchers("/api/watchlist/**").authenticated() .requestMatchers("/api/transactions/**").authenticated() .anyRequest().authenticated() ) .sessionManagement(s -> s .sessionCreationPolicy(SessionCreationPolicy.STATELESS) ) .authenticationProvider(authenticationProvider) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }}} Секој HTTP барање поминува низ `JwtAuthenticationFilter` пред да стигне до контролерот. Филтерот го верификува потписот на токенот, го проверува expiry и го вчитува корисникот. Корисник без валиден JWT токен добива HTTP 401 Unauthorized. === Хеширање на лозинки (BCrypt) === Лозинките на корисниците се чуваат во базата во хеширана форма преку BCrypt алгоритам, а никогаш како plain text. Во базата колоната `users.password` содржи BCrypt hash со формат `$2a$10$...`. === CORS Конфигурација === CORS е безбеден механизам кој ги ограничува HTTP барањата само од дозволени домени. Апликацијата има двојна CORS конфигурација: {{{ // SecurityConfig.java - CORS на Spring Security ниво @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(List.of( "http://localhost:5173", "http://localhost:5174", "http://localhost:5175", "http://localhost:5176", "http://localhost:3000" )); config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")); config.setAllowedHeaders(List.of("*")); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", source); return source; } }}} {{{ // WebConfig.java - CORS на Spring MVC ниво @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins( "http://localhost:5173", "http://localhost:5174", "http://localhost:5175", "http://localhost:3000" ) .allowedMethods("*") .allowedHeaders("*") .allowCredentials(true); } } }}} Само барања кои потекнуваат од дозволените localhost портови ќе бидат прифатени. Секое барање од непознат домен добива HTTP 403 уште на ниво на CORS preflight проверката. === Заштита на податоци на ниво на база === На ниво на базата на податоци, безбедноста е обезбедена преку: * '''Role-based CHECK constraints''' - `users.role CHECK (role IN ('USER','ADMIN'))` спречува внесување на невалидни улоги директно во базата * '''Enum CHECK constraints''' - `transactions.origin CHECK (origin IN ('INTERNAL','EXTERNAL'))` и `user_auth_providers.auth_providers CHECK (auth_providers IN ('INTERNAL','GOOGLE'))` обезбедуваат интегритет на enum вредностите * '''Foreign key constraints''' - сите референцијални правила се дефинирани на ниво на база, не само на апликациско ниво * '''UNIQUE constraints''' - `users.email UNIQUE`, `users.username UNIQUE`, `stock.symbol UNIQUE` и `portfolios.user_id UNIQUE` спречуваат дупликати кои би можеле да доведат до безбедносни пропусти ... ----