Index: backend/pom.xml
===================================================================
--- backend/pom.xml	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ backend/pom.xml	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -98,4 +98,24 @@
 
 
+        <dependency>
+            <groupId>com.google.oauth-client</groupId>
+            <artifactId>google-oauth-client</artifactId>
+            <version>1.34.1</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.google.http-client</groupId>
+            <artifactId>google-http-client-gson</artifactId>
+            <version>1.42.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.api-client</groupId>
+            <artifactId>google-api-client</artifactId>
+            <version>2.2.0</version>
+        </dependency>
+
+
     </dependencies>
 
Index: backend/src/main/java/com/tradingmk/backend/controller/GoogleOAuthController.java
===================================================================
--- backend/src/main/java/com/tradingmk/backend/controller/GoogleOAuthController.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
+++ backend/src/main/java/com/tradingmk/backend/controller/GoogleOAuthController.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -0,0 +1,111 @@
+package com.tradingmk.backend.controller;
+
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.gson.GsonFactory;
+import com.tradingmk.backend.dto.GoogleAuthRequest;
+import com.tradingmk.backend.model.AuthProvider;
+import com.tradingmk.backend.model.Portfolio;
+import com.tradingmk.backend.model.Role;
+import com.tradingmk.backend.model.User;
+import com.tradingmk.backend.repository.PortfolioRepository;
+import com.tradingmk.backend.repository.UserRepository;
+import com.tradingmk.backend.service.UserService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
+import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
+import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+@RestController
+@RequestMapping("/api/auth/google")
+@RequiredArgsConstructor
+public class GoogleOAuthController {
+
+    private final UserRepository userRepository;
+    private final UserService userService;
+    private final PortfolioRepository portfolioRepository;
+
+    private final RestTemplate restTemplate = new RestTemplate();
+
+
+    private final String GOOGLE_CLIENT_ID = "72179147890-t9evep4qgldanqeosjp8bm30flq8bnkr.apps.googleusercontent.com";
+    private final String GOOGLE_CLIENT_SECRET = "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";
+    private final String GOOGLE_REDIRECT_URI = "http://localhost:5173";
+    private final String GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
+    private final String GOOGLE_USER_URL = "https://www.googleapis.com/oauth2/v2/userinfo";
+
+    @PostMapping
+    public ResponseEntity<?> googleLogin(@RequestBody Map<String, String> request) {
+        try {
+            String tokenString = request.get("credential"); // id token od frontend
+
+            GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(
+                    new NetHttpTransport(),
+                    GsonFactory.getDefaultInstance()
+            ).setAudience(Collections.singletonList(GOOGLE_CLIENT_ID)).build();
+
+            GoogleIdToken idToken = verifier.verify(tokenString);
+
+            if (idToken == null) {
+                return ResponseEntity.status(401).body("Invalid ID token");
+            }
+
+            GoogleIdToken.Payload payload = idToken.getPayload();
+            String email = payload.getEmail();
+            String name = (String) payload.get("name");
+
+
+            User user = userRepository.findByEmail(email).orElse(null);
+
+
+            // case A: email not found
+            if (user == null) {
+                User newUser = new User();
+                newUser.setEmail(email);
+                newUser.setUsername(email);
+                newUser.setFullName(name);
+                newUser.setRole(Role.USER);
+                newUser.setBalance(0.0);
+                newUser.setAuthProviders(Set.of(AuthProvider.GOOGLE));
+                userRepository.save(newUser);
+
+                Portfolio portfolio = new Portfolio();
+                portfolio.setUser(newUser);
+                portfolio.setBalance(BigDecimal.ZERO);
+                portfolioRepository.save(portfolio);
+
+                String jwt = userService.generateToken(newUser);
+                return ResponseEntity.ok(Collections.singletonMap("token", jwt));
+            }
+
+            // case B: email exists but ony intternal
+            if (user.getAuthProviders().contains(AuthProvider.INTERNAL) &&
+                    !user.getAuthProviders().contains(AuthProvider.GOOGLE)) {
+                return ResponseEntity.status(403).body(
+                        "Веќе имате акаунт со е-пошта и лозинка. Најавете се прво со вашата лозинка. " +
+                                "Потоа во профилот може да го поврзете Google."
+                );
+            }
+
+            // case c: already has google
+            if (user.getAuthProviders().contains(AuthProvider.GOOGLE)) {
+                String jwt = userService.generateToken(user);
+                return ResponseEntity.ok(Collections.singletonMap("token", jwt));
+            }
+
+            // fallback
+            return ResponseEntity.status(403).body("neuspesen login so google.");
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return ResponseEntity.status(500).body("server error: " + e.getMessage());
+        }
+    }
+
+}
Index: backend/src/main/java/com/tradingmk/backend/controller/PortfolioController.java
===================================================================
--- backend/src/main/java/com/tradingmk/backend/controller/PortfolioController.java	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ backend/src/main/java/com/tradingmk/backend/controller/PortfolioController.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -62,24 +62,24 @@
     }
 
-    @PostMapping("/buy")
-    public ResponseEntity<String> buyStock(@RequestBody BuyStockRequest request, Principal principal) {
-        System.out.println("Principal: " + principal);
-        //geting user
-        var user = userRepository.findByUsername(principal.getName())
-                .orElseThrow(() -> new RuntimeException("user not found"));
-
-        //portfolio gett
-        var portfolio = portfolioRepository.findByUserId(user.getId())
-                .orElseThrow(() -> new RuntimeException("portfolio not found"));
-
-        portfolioService.buyStock(
-                portfolio.getId(),
-                request.getStockSymbol(),
-                request.getQuantity(),
-                request.getPricePerUnit()
-        );
-
-        return ResponseEntity.ok("stock purchased successfuly");
-    }
+//    @PostMapping("/buy")
+//    public ResponseEntity<String> buyStock(@RequestBody BuyStockRequest request, Principal principal) {
+//        System.out.println("Principal: " + principal);
+//        //geting user
+//        var user = userRepository.findByUsername(principal.getName())
+//                .orElseThrow(() -> new RuntimeException("user not found"));
+//
+//        //portfolio gett
+//        var portfolio = portfolioRepository.findByUserId(user.getId())
+//                .orElseThrow(() -> new RuntimeException("portfolio not found"));
+//
+//        portfolioService.buyStock(
+//                portfolio.getId(),
+//                request.getStockSymbol(),
+//                request.getQuantity(),
+//                request.getPricePerUnit()
+//        );
+//
+//        return ResponseEntity.ok("stock purchased successfuly");
+//    }
 
     @PostMapping("/sell")
Index: backend/src/main/java/com/tradingmk/backend/dto/GoogleAuthRequest.java
===================================================================
--- backend/src/main/java/com/tradingmk/backend/dto/GoogleAuthRequest.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
+++ backend/src/main/java/com/tradingmk/backend/dto/GoogleAuthRequest.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -0,0 +1,8 @@
+package com.tradingmk.backend.dto;
+
+import lombok.Data;
+
+@Data
+public class GoogleAuthRequest {
+    private String code;
+}
Index: backend/src/main/java/com/tradingmk/backend/model/AuthProvider.java
===================================================================
--- backend/src/main/java/com/tradingmk/backend/model/AuthProvider.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
+++ backend/src/main/java/com/tradingmk/backend/model/AuthProvider.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -0,0 +1,7 @@
+package com.tradingmk.backend.model;
+
+public enum AuthProvider {
+    INTERNAL,
+    GOOGLE,
+    FACEBOOK
+}
Index: backend/src/main/java/com/tradingmk/backend/model/User.java
===================================================================
--- backend/src/main/java/com/tradingmk/backend/model/User.java	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ backend/src/main/java/com/tradingmk/backend/model/User.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -12,5 +12,7 @@
 
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 @Entity
@@ -32,4 +34,11 @@
     private Double balance;
     private String email;
+
+    @ElementCollection(fetch = FetchType.EAGER)
+    @CollectionTable(name = "user_auth_providers", joinColumns = @JoinColumn(name = "user_id"))
+    @Enumerated(EnumType.STRING)
+    private Set<AuthProvider> authProviders = new HashSet<>();
+
+
 
 
Index: backend/src/main/java/com/tradingmk/backend/repository/UserRepository.java
===================================================================
--- backend/src/main/java/com/tradingmk/backend/repository/UserRepository.java	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ backend/src/main/java/com/tradingmk/backend/repository/UserRepository.java	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -10,3 +10,4 @@
     boolean existsByUsername(String username);
     boolean existsByEmail(String email);
+    Optional<User> findByEmail(String email);
 }
Index: frontend/package-lock.json
===================================================================
--- frontend/package-lock.json	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ frontend/package-lock.json	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -9,4 +9,5 @@
       "version": "0.0.0",
       "dependencies": {
+        "@react-oauth/google": "^0.12.2",
         "@stomp/stompjs": "^7.1.1",
         "@tailwindcss/vite": "^4.1.10",
@@ -1031,4 +1032,14 @@
         "@jridgewell/resolve-uri": "^3.1.0",
         "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@react-oauth/google": {
+      "version": "0.12.2",
+      "resolved": "https://registry.npmjs.org/@react-oauth/google/-/google-0.12.2.tgz",
+      "integrity": "sha512-d1GVm2uD4E44EJft2RbKtp8Z1fp/gK8Lb6KHgs3pHlM0PxCXGLaq8LLYQYENnN4xPWO1gkL4apBtlPKzpLvZwg==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": ">=16.8.0",
+        "react-dom": ">=16.8.0"
       }
     },
Index: frontend/package.json
===================================================================
--- frontend/package.json	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ frontend/package.json	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -11,4 +11,5 @@
   },
   "dependencies": {
+    "@react-oauth/google": "^0.12.2",
     "@stomp/stompjs": "^7.1.1",
     "@tailwindcss/vite": "^4.1.10",
Index: frontend/src/main.jsx
===================================================================
--- frontend/src/main.jsx	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ frontend/src/main.jsx	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -16,20 +16,25 @@
 import Settings from "./pages/Settings/Settings.jsx";
 import AdminTrades from "./pages/AdminTrades/AdminTrades.jsx";
+import {GoogleOAuthProvider} from "@react-oauth/google";
+
+
 
 createRoot(document.getElementById('root')).render(
-
-        <BrowserRouter>
-            <Routes>
-                <Route path="/dashboard" element={<Dashboard/>}></Route>
-                <Route path="/" element={<LandingPage/>}></Route>
-                <Route path="/detailed/:symbol" element={<DetailedStockView/>}></Route>
-                <Route path="/signup" element={<SignupPage />} />
-                <Route path="/login" element={<LoginPage />} />
-                <Route path="/portfolio" element={<Portfolio />} />
-                <Route path="/education" element={<Education/>} />
-                <Route path="/settings" element={<Settings/>} />
-                <Route path="/admin" element={<AdminTrades/>} />
-            </Routes>
-        </BrowserRouter>
-
+    <StrictMode>
+        <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>
+            <BrowserRouter>
+                <Routes>
+                    <Route path="/dashboard" element={<Dashboard />} />
+                    <Route path="/" element={<LandingPage />} />
+                    <Route path="/detailed/:symbol" element={<DetailedStockView />} />
+                    <Route path="/signup" element={<SignupPage />} />
+                    <Route path="/login" element={<LoginPage />} />
+                    <Route path="/portfolio" element={<Portfolio />} />
+                    <Route path="/education" element={<Education />} />
+                    <Route path="/settings" element={<Settings />} />
+                    <Route path="/admin" element={<AdminTrades />} />
+                </Routes>
+            </BrowserRouter>
+        </GoogleOAuthProvider>
+    </StrictMode>
 )
Index: frontend/src/pages/Signup-Login/LoginPage.jsx
===================================================================
--- frontend/src/pages/Signup-Login/LoginPage.jsx	(revision 7225770ddd7224c0a5fcd6c23394f2d0c2035c48)
+++ frontend/src/pages/Signup-Login/LoginPage.jsx	(revision 4c3dc5a1f8b831c6cade3197c701ca91379202a5)
@@ -1,4 +1,5 @@
 import React, {useState} from 'react';
 import {useNavigate} from "react-router-dom";
+import {GoogleLogin} from "@react-oauth/google";
 
 const LoginPage = () => {
@@ -61,4 +62,34 @@
     };
 
+
+
+
+
+
+    const handleGoogleLogin = async (credentialResponse) => {
+        try {
+            const token = credentialResponse.credential; // ID token
+            const res = await fetch('http://localhost:8080/api/auth/google', {
+                method: 'POST',
+                headers: { 'Content-Type': 'application/json' },
+                body: JSON.stringify({ credential: token })
+            });
+
+            if (!res.ok) {
+                const msg = await res.text();
+                alert(msg);
+                return;
+            }
+
+            const data = await res.json();
+            localStorage.setItem('accessToken', data.token);
+            alert('Google login successful!');
+            navigate('/dashboard');
+        } catch (err) {
+            console.error(err);
+            alert('Login failed');
+        }
+    };
+
     return (
 
@@ -103,5 +134,18 @@
                 {error && <p className="text-red-600 mt-4">{error}</p>}
                 {success && <p className="text-green-600 mt-4">{success}</p>}
+
+                    <div className="max-w-md mx-auto mt-10 p-6 bg-white rounded shadow text-center">
+                        <h2 className="text-2xl mb-4 font-semibold">Login with Google</h2>
+                        <GoogleLogin
+                            onSuccess={handleGoogleLogin}
+                            onError={() => {
+                                console.log('Login Failed');
+                            }}
+                        />
+                    </div>
             </div>
+
+
+
         </div>
     );
