Index: c/main/java/mk/ukim/finki/synergymed/config/ConfigProbe.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/config/ConfigProbe.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ 	(revision )
@@ -1,12 +1,0 @@
-package mk.ukim.finki.synergymed.config;
-
-import org.springframework.stereotype.Component;
-
-@Component
-class ConfigProbe {
-    ConfigProbe(org.springframework.core.env.Environment env) {
-        String present = env.containsProperty("security.jwt.secret") ? "YES" : "NO";
-        System.out.println(">> security.jwt.secret present? " + present);
-    }
-}
-
Index: c/main/java/mk/ukim/finki/synergymed/config/OpenApiConfig.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/config/OpenApiConfig.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ 	(revision )
@@ -1,29 +1,0 @@
-package mk.ukim.finki.synergymed.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 org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class OpenApiConfig {
-
-    @Bean
-    public OpenAPI api() {
-        final String BEARER = "bearerAuth";
-        return new OpenAPI()
-                .info(new Info().title("SynergyMed API").version("v1"))
-                .addSecurityItem(new SecurityRequirement().addList(BEARER))
-                .components(new io.swagger.v3.oas.models.Components()
-                        .addSecuritySchemes(BEARER,
-                                new SecurityScheme()
-                                        .name(BEARER)
-                                        .type(SecurityScheme.Type.HTTP)
-                                        .scheme("bearer")
-                                        .bearerFormat("JWT")
-                        )
-                );
-    }
-}
Index: src/main/java/mk/ukim/finki/synergymed/config/SecurityConfig.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/config/SecurityConfig.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ src/main/java/mk/ukim/finki/synergymed/config/SecurityConfig.java	(revision 5e1075dd0cd3bb015a3344da440769c15949a606)
@@ -1,10 +1,6 @@
 package mk.ukim.finki.synergymed.config;
 
-import mk.ukim.finki.synergymed.security.JwtAuthFilter;
-import org.springframework.boot.autoconfigure.security.reactive.PathRequest;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpMethod;
-import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -12,10 +8,4 @@
 import org.springframework.security.config.http.SessionCreationPolicy;
 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 java.util.List;
 
 @Configuration
@@ -23,52 +13,25 @@
 public class SecurityConfig {
 
-    private final JwtAuthFilter jwtAuthFilter;
-
-    public SecurityConfig(JwtAuthFilter jwtAuthFilter) {
-        this.jwtAuthFilter = jwtAuthFilter;
-    }
-
     @Bean
     public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
         http
-                .cors(Customizer.withDefaults()) // enable CORS using the bean below
                 .csrf(AbstractHttpConfigurer::disable)
-                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                 .authorizeHttpRequests(reg -> reg
-                        .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
-
-                        // Static resources in /static, /public, /resources, /META-INF/resources
-                        .requestMatchers(String.valueOf(PathRequest.toStaticResources().atCommonLocations())).permitAll()
-                        .requestMatchers("/", "/**", "/login", "/login.html", "/index.html", "/favicon.ico").permitAll()
-
-                        // Public API/docs
-                        .requestMatchers(
-                                "/auth/login",
-                                "/error",
-                                "/v3/api-docs/**", "/swagger-ui.html", "/swagger-ui/**",
-                                "/swagger-resources/**", "/webjars/**"
-                        ).permitAll()
-
-                        // Everything else requires JWT
+                        .requestMatchers("/", "/login", "/register", "/error", "/css/**", "/js/**", "/images/**").permitAll()
                         .anyRequest().authenticated()
                 )
-                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
+                .formLogin(login -> login
+                        .loginPage("/login")
+                        .defaultSuccessUrl("/profile", true)
+                        .permitAll()
+                )
+                .logout(logout -> logout
+                        .logoutUrl("/logout")
+                        .logoutSuccessUrl("/login?logout")
+                        .permitAll()
+                )
+                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED));
 
         return http.build();
     }
-
-    @Bean
-    public CorsConfigurationSource corsConfigurationSource() {
-        CorsConfiguration c = new CorsConfiguration();
-        // be strict in prod (e.g., setAllowedOrigins(List.of("http://localhost:8080")))
-        c.setAllowedOriginPatterns(List.of("*"));
-        c.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
-        c.setAllowedHeaders(List.of("Authorization", "Content-Type", "Accept", "Origin", "X-Requested-With"));
-        c.setExposedHeaders(List.of("Authorization"));
-        c.setAllowCredentials(true);
-
-        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
-        source.registerCorsConfiguration("/**", c);
-        return source;
-    }
 }
Index: c/main/java/mk/ukim/finki/synergymed/security/JwtAuthFilter.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/security/JwtAuthFilter.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ 	(revision )
@@ -1,89 +1,0 @@
-package mk.ukim.finki.synergymed.security;
-
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.Cookie;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import mk.ukim.finki.synergymed.service.jwt.JwtService;
-import mk.ukim.finki.synergymed.service.jwt.TokenBlacklistService;
-import org.springframework.lang.NonNull;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-
-@Component
-public class JwtAuthFilter extends OncePerRequestFilter {
-
-    private final JwtService jwtService;
-    private final UserDetailsService userDetailsService;
-    private final TokenBlacklistService tokenBlacklistService;
-
-    public JwtAuthFilter(JwtService jwtService,
-                         UserDetailsService userDetailsService,
-                         TokenBlacklistService tokenBlacklistService) {
-        this.jwtService = jwtService;
-        this.userDetailsService = userDetailsService;
-        this.tokenBlacklistService = tokenBlacklistService;
-    }
-
-    private String tokenFromHeader(HttpServletRequest req) {
-        String h = req.getHeader("Authorization");
-        return (h != null && h.startsWith("Bearer ")) ? h.substring(7) : null;
-    }
-
-    private String tokenFromCookie(HttpServletRequest req, String name) {
-        Cookie[] cookies = req.getCookies();
-        if (cookies == null) return null;
-        for (Cookie c : cookies) {
-            if (name.equals(c.getName())) return c.getValue();
-        }
-        return null;
-    }
-
-    @Override
-    protected void doFilterInternal(
-            @NonNull HttpServletRequest request,
-            @NonNull HttpServletResponse response,
-            @NonNull FilterChain chain
-    ) throws ServletException, IOException {
-
-        // If already authenticated, continue
-        if (SecurityContextHolder.getContext().getAuthentication() != null) {
-            chain.doFilter(request, response);
-            return;
-        }
-
-        String token = tokenFromHeader(request);
-        if (token == null) token = tokenFromCookie(request, "AUTH");
-
-        if (token != null) {
-            try {
-                var jws = jwtService.parse(token); // validates signature + exp
-                var claims = jws.getPayload();
-                String username = claims.getSubject();
-                String jti = claims.getId();
-
-                if (username != null && !tokenBlacklistService.contains(jti)) {
-                    UserDetails user = userDetailsService.loadUserByUsername(username);
-                    if (user != null) {
-                        UsernamePasswordAuthenticationToken auth =
-                                new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
-                        auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-                        SecurityContextHolder.getContext().setAuthentication(auth);
-                    }
-                }
-            } catch (Exception ignore) {
-                // invalid/expired/blacklisted → anonymous
-            }
-        }
-
-        chain.doFilter(request, response);
-    }
-}
Index: c/main/java/mk/ukim/finki/synergymed/service/jwt/JwtService.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/service/jwt/JwtService.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ 	(revision )
@@ -1,58 +1,0 @@
-package mk.ukim.finki.synergymed.service.jwt;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.userdetails.UserDetails;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jws;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.security.Keys;
-
-import javax.crypto.SecretKey;
-import java.nio.charset.StandardCharsets;
-import java.util.Date;
-import java.util.List;
-import java.util.UUID;
-
-@Component
-public class JwtService {
-    private final SecretKey key;     // <— SecretKey
-    private final long expMillis;
-
-    public JwtService(
-            @Value("${security.jwt.secret:${SECURITY_JWT_SECRET:}}") String secret,
-            @Value("${security.jwt.exp-min:${SECURITY_JWT_EXP_MIN:60}}") long expMin
-    ) {
-        if (secret == null || secret.length() < 32) {
-            throw new IllegalStateException("security.jwt.secret (or env SECURITY_JWT_SECRET) must be ≥ 32 chars");
-        }
-        this.key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
-        this.expMillis = expMin * 60_000;
-    }
-
-    public String generate(UserDetails ud) {
-        Date now = new Date();
-        Date exp = new Date(now.getTime() + expMillis);
-        List<String> roles = ud.getAuthorities().stream()
-                .map(GrantedAuthority::getAuthority)
-                .toList();
-
-        return Jwts.builder()
-                .subject(ud.getUsername())
-                .claim("roles", roles)
-                .id(UUID.randomUUID().toString())
-                .issuedAt(now)
-                .expiration(exp)
-                .signWith(key)
-                .compact();
-    }
-
-    public Jws<Claims> parse(String token) {
-        return Jwts.parser()               // 0.12.x
-                .verifyWith(key)
-                .build()
-                .parseSignedClaims(token);
-    }
-}
Index: c/main/java/mk/ukim/finki/synergymed/service/jwt/TokenBlacklistService.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/service/jwt/TokenBlacklistService.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ 	(revision )
@@ -1,26 +1,0 @@
-package mk.ukim.finki.synergymed.service.jwt;
-
-import lombok.RequiredArgsConstructor;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Component;
-
-import java.time.Duration;
-
-@Component
-@RequiredArgsConstructor
-public class TokenBlacklistService {
-
-    private final StringRedisTemplate redis;
-
-    public void add(String jti, long expirationMillis) {
-        redis.opsForValue().set(
-                "blacklist:" + jti,
-                "revoked",
-                Duration.ofMillis(expirationMillis)
-        );
-    }
-
-    public boolean contains(String jti) {
-        return redis.hasKey("blacklist:" + jti);
-    }
-}
Index: src/main/java/mk/ukim/finki/synergymed/web/LoginController.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/web/LoginController.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ src/main/java/mk/ukim/finki/synergymed/web/LoginController.java	(revision 5e1075dd0cd3bb015a3344da440769c15949a606)
@@ -1,66 +1,13 @@
 package mk.ukim.finki.synergymed.web;
 
-import lombok.RequiredArgsConstructor;
-import mk.ukim.finki.synergymed.models.User;
-import mk.ukim.finki.synergymed.repositories.UserRepository;
-import mk.ukim.finki.synergymed.service.jwt.JwtService;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.*;
-
-import jakarta.servlet.http.HttpSession;
+import org.springframework.web.bind.annotation.GetMapping;
 
 @Controller
-@RequestMapping("/login")
-@RequiredArgsConstructor
 public class LoginController {
 
-    private final AuthenticationManager authenticationManager;
-    private final JwtService jwtService;
-    private final UserRepository userRepository; // Add this
-
-    @GetMapping
+    @GetMapping("/login")
     public String getLoginPage() {
         return "login";
     }
-
-    @PostMapping
-    public String login(@RequestParam String username,
-                        @RequestParam String password,
-                        HttpSession session,
-                        Model model) {
-        try {
-            var authentication = authenticationManager.authenticate(
-                    new UsernamePasswordAuthenticationToken(username, password)
-            );
-
-            var userDetails = (UserDetails) authentication.getPrincipal();
-            String token = jwtService.generate(userDetails);
-
-            // Fetch your custom User entity from database
-            User user = userRepository.findByUsername(username)
-                    .orElseThrow(() -> new RuntimeException("User not found"));
-
-            // Store both UserDetails and your custom User entity
-            session.setAttribute("jwt_token", token);
-            session.setAttribute("username", username);
-            session.setAttribute("userDetails", userDetails); // Spring Security UserDetails
-            session.setAttribute("user", user); // Your custom User entity
-
-            return "redirect:/profile";
-
-        } catch (BadCredentialsException e) {
-            model.addAttribute("error", "Invalid username or password");
-            model.addAttribute("username", username);
-            return "login";
-        } catch (Exception e) {
-            model.addAttribute("error", "An error occurred during login");
-            model.addAttribute("username", username);
-            return "login";
-        }
-    }
 }
Index: c/main/java/mk/ukim/finki/synergymed/web/LogoutController.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/web/LogoutController.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ 	(revision )
@@ -1,36 +1,0 @@
-package mk.ukim.finki.synergymed.web;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jws;
-import mk.ukim.finki.synergymed.service.jwt.JwtService;
-import mk.ukim.finki.synergymed.service.jwt.TokenBlacklistService;
-import org.springframework.web.bind.annotation.*;
-
-@RestController
-@RequestMapping("/logout")
-public class LogoutController {
-
-    private final JwtService jwtService;
-    private final TokenBlacklistService tokenBlacklistService;
-
-    public LogoutController(JwtService jwtService, TokenBlacklistService tokenBlacklistService) {
-        this.jwtService = jwtService;
-        this.tokenBlacklistService = tokenBlacklistService;
-    }
-
-    @PostMapping()
-    public String logout(@RequestHeader("Authorization") String authHeader) {
-        if (authHeader != null && authHeader.startsWith("Bearer ")) {
-            String token = authHeader.substring(7);
-
-            Jws<Claims> jws = jwtService.parse(token);
-            Claims claims = jws.getPayload();
-
-            long expirationMillis = claims.getExpiration().getTime() - System.currentTimeMillis();
-            if (expirationMillis > 0) {
-                tokenBlacklistService.add(claims.getId(), expirationMillis);
-            }
-        }
-        return "redirect:/login";
-    }
-}
Index: src/main/java/mk/ukim/finki/synergymed/web/ProfileController.java
===================================================================
--- src/main/java/mk/ukim/finki/synergymed/web/ProfileController.java	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ src/main/java/mk/ukim/finki/synergymed/web/ProfileController.java	(revision 5e1075dd0cd3bb015a3344da440769c15949a606)
@@ -1,10 +1,13 @@
 package mk.ukim.finki.synergymed.web;
 
-import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
 import mk.ukim.finki.synergymed.models.Contactinformation;
 import mk.ukim.finki.synergymed.models.Healthprofile;
 import mk.ukim.finki.synergymed.models.User;
+import mk.ukim.finki.synergymed.repositories.UserRepository;
 import mk.ukim.finki.synergymed.service.*;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -19,4 +22,5 @@
 public class ProfileController {
 
+    private final UserRepository userRepository;
     private final HealthProfileService healthProfileService;
     private final ContactInformationService contactInformationService;
@@ -25,11 +29,24 @@
     private final ClientService clientService;
 
+    private User getCurrentUser() {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+        Object principal = auth.getPrincipal();
+        String username;
+
+        if (principal instanceof UserDetails ud) {
+            username = ud.getUsername();
+        } else {
+            username = principal.toString();
+        }
+
+        return userRepository.findByUsername(username)
+                .orElseThrow(() -> new RuntimeException("User not found: " + username));
+    }
+
     @GetMapping
-    public String getProfilePage(HttpSession session, Model model) {
-        User user = (User) session.getAttribute("user");
-        String username = (String) session.getAttribute("username");
-        if (user == null || username == null) return "redirect:/login";
+    public String getProfilePage(Model model) {
+        User user = getCurrentUser();
         model.addAttribute("user", user);
-        model.addAttribute("username", username);
+        model.addAttribute("username", user.getUsername());
 
         try {
@@ -44,9 +61,7 @@
     }
 
-    // Contact Info tab
     @GetMapping("/contacts")
-    public String profileContacts(HttpSession session, Model model) {
-        User user = (User) session.getAttribute("user");
-        if (user == null) return "redirect:/login";
+    public String profileContacts(Model model) {
+        User user = getCurrentUser();
         List<Contactinformation> list = contactInformationService.listForUser(user.getId());
         Contactinformation contact = list.isEmpty() ? null : list.get(0);
@@ -57,7 +72,6 @@
 
     @GetMapping("/contacts/new")
-    public String newProfileContact(HttpSession session, Model model) {
-        User user = (User) session.getAttribute("user");
-        if (user == null) return "redirect:/login";
+    public String newProfileContact(Model model) {
+        getCurrentUser(); // just to ensure authenticated
         model.addAttribute("context", "profile");
         model.addAttribute("postUrl", "/profile/contacts/save");
@@ -69,8 +83,6 @@
     public String saveProfileContact(@RequestParam(required = false) Integer id,
                                      @RequestParam(required = false) String phone,
-                                     @RequestParam(required = false) String address,
-                                     HttpSession session) {
-        User user = (User) session.getAttribute("user");
-        if (user == null) return "redirect:/login";
+                                     @RequestParam(required = false) String address) {
+        User user = getCurrentUser();
         if (id == null) {
             contactInformationService.createForUser(user.getId(), phone, address);
@@ -82,7 +94,6 @@
 
     @PostMapping("/contacts/delete")
-    public String deleteProfileContact(@RequestParam Integer id, HttpSession session) {
-        User user = (User) session.getAttribute("user");
-        if (user == null) return "redirect:/login";
+    public String deleteProfileContact(@RequestParam Integer id) {
+        User user = getCurrentUser();
         contactInformationService.deleteForUser(id, user.getId());
         return "redirect:/profile/contacts";
@@ -93,11 +104,8 @@
     }
 
-    /* GET /profile/prescriptions */
     @GetMapping("/prescriptions")
-    public String prescriptions(jakarta.servlet.http.HttpSession session,
-                                org.springframework.ui.Model model) {
-        var user = (mk.ukim.finki.synergymed.models.User) session.getAttribute("user");
-        if (user == null) return "redirect:/login";
-        Integer clientId = user.getId(); // Client.id == User.id via @MapsId
+    public String prescriptions(Model model) {
+        User user = getCurrentUser();
+        Integer clientId = user.getId();
 
         boolean verified = isVerified(clientId);
@@ -106,5 +114,5 @@
                 .orElse(false);
 
-        var rx = verified ? prescriptionService.listForClient(clientId) : java.util.List.of();
+        var rx = verified ? prescriptionService.listForClient(clientId) : List.of();
 
         model.addAttribute("activeTab", "prescriptions");
Index: src/main/resources/application.properties
===================================================================
--- src/main/resources/application.properties	(revision a2fc3d8fd7c3365edd220ed4fa0e7e857b76899e)
+++ src/main/resources/application.properties	(revision 5e1075dd0cd3bb015a3344da440769c15949a606)
@@ -8,22 +8,4 @@
 spring.datasource.driver-class-name=org.postgresql.Driver
 
-# ==========================
-# Redis connection
-# ==========================
-spring.data.redis.host=localhost
-spring.data.redis.port=6379
-# spring.data.redis.password=yourStrongPassword   # only if configured
-
-# Logical DB index
-spring.data.redis.database=0
-
-# Connection timeout (must be a duration, not raw ms)
-spring.data.redis.timeout=60s
-
-# ==========================
-# JWT (inject into @Value)
-# ==========================
-security.jwt.secret=ThisIsASuperSecretJwtKeyWith32CharsOrMore!
-security.jwt.exp-min=15
 
 spring.datasource.hikari.maximum-pool-size=5
