mirror of
https://github.com/Sosokker/go-chi-oapi-codegen-todolist.git
synced 2025-12-19 14:04:07 +01:00
fix: fix google oauth
This commit is contained in:
parent
8219c93ceb
commit
f4bc48c337
@ -390,7 +390,7 @@ func (h *ApiHandler) HandleGoogleCallback(w http.ResponseWriter, r *http.Request
|
||||
SameSite: parseSameSite(h.cfg.JWT.CookieSameSite),
|
||||
})
|
||||
|
||||
redirectURL := "/dashboard"
|
||||
redirectURL := fmt.Sprintf("%s/oauth/callback#access_token=%s", h.cfg.Frontend.Url, url.QueryEscape(token))
|
||||
h.logger.InfoContext(ctx, "Google OAuth login successful", "userId", user.ID, "email", user.Email, "redirectingTo", redirectURL)
|
||||
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
@ -14,14 +14,11 @@ import (
|
||||
|
||||
// GoogleUserInfo holds user details fetched from Google.
|
||||
type GoogleUserInfo struct {
|
||||
ID string `json:"id"` // The unique Google ID
|
||||
Email string `json:"email"` // The user's email address
|
||||
VerifiedEmail bool `json:"verified_email"` // Whether Google has verified the email
|
||||
Name string `json:"name"` // User's full name
|
||||
GivenName string `json:"given_name"` // First name
|
||||
FamilyName string `json:"family_name"` // Last name
|
||||
Picture string `json:"picture"` // URL to profile picture
|
||||
Locale string `json:"locale"` // User's locale (e.g., "en")
|
||||
ID string `json:"sub"`
|
||||
Email string `json:"email"`
|
||||
VerifiedEmail bool `json:"email_verified"`
|
||||
Name string `json:"name"`
|
||||
Picture string `json:"picture"`
|
||||
}
|
||||
|
||||
// OAuthProvider defines the interface for OAuth operations.
|
||||
|
||||
@ -16,6 +16,7 @@ type Config struct {
|
||||
OAuth OAuthConfig
|
||||
Cache CacheConfig
|
||||
Storage StorageConfig
|
||||
Frontend FrontendConfig
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
@ -37,9 +38,9 @@ type LocalStorageConfig struct {
|
||||
}
|
||||
|
||||
type GCSStorageConfig struct {
|
||||
BucketName string `mapstructure:"bucketName"`
|
||||
CredentialsFile string `mapstructure:"credentialsFile"`
|
||||
BaseDir string `mapstructure:"baseDir"`
|
||||
BucketName string `mapstructure:"bucketName"`
|
||||
CredentialsFile string `mapstructure:"credentialsFile"`
|
||||
BaseDir string `mapstructure:"baseDir"`
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
@ -79,6 +80,10 @@ type CacheConfig struct {
|
||||
CleanupInterval time.Duration `mapstructure:"cleanupInterval"`
|
||||
}
|
||||
|
||||
type FrontendConfig struct {
|
||||
Url string `mapstructure:"url"`
|
||||
}
|
||||
|
||||
func LoadConfig(path string) (*Config, error) {
|
||||
viper.SetConfigName("config") // name of config file (without extension)
|
||||
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
|
||||
@ -103,6 +108,7 @@ func LoadConfig(path string) (*Config, error) {
|
||||
viper.SetDefault("cache.cleanupInterval", 10*time.Minute)
|
||||
viper.SetDefault("storage.type", "local") // Default to local storage
|
||||
viper.SetDefault("storage.local.path", "./uploads")
|
||||
viper.SetDefault("frontend.url", "http://localhost:3000")
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
|
||||
@ -199,15 +199,17 @@ export default function LoginPage() {
|
||||
Or continue with
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
|
||||
onClick={() =>
|
||||
toast.info("Google signup would be implemented here")
|
||||
}
|
||||
onClick={() => {
|
||||
const apiBaseUrl =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ||
|
||||
"http://127.0.0.1:8080/api/v1";
|
||||
window.location.href = `${apiBaseUrl}/auth/google/login`;
|
||||
}}
|
||||
>
|
||||
<Icons.google className="mr-2 h-4 w-4" />
|
||||
Google
|
||||
|
||||
55
frontend/app/oauth/callback/page.tsx
Normal file
55
frontend/app/oauth/callback/page.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { getCurrentUser } from "@/services/api-auth";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export default function OAuthCallbackPage() {
|
||||
const router = useRouter();
|
||||
const { login } = useAuth();
|
||||
|
||||
useEffect(() => {
|
||||
let token: string | null = null;
|
||||
if (typeof window !== "undefined") {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
token = urlParams.get("access_token");
|
||||
|
||||
// If not in query, check hash fragment
|
||||
if (!token && window.location.hash) {
|
||||
const hashParams = new URLSearchParams(
|
||||
window.location.hash.substring(1)
|
||||
);
|
||||
token = hashParams.get("access_token");
|
||||
}
|
||||
}
|
||||
|
||||
if (token) {
|
||||
localStorage.setItem("access_token", token);
|
||||
|
||||
async function fetchUser() {
|
||||
try {
|
||||
const user = await getCurrentUser(token!);
|
||||
login(token!, user);
|
||||
toast.success("Logged in with Google!");
|
||||
router.replace("/todos");
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toast.error("Google login failed");
|
||||
router.replace("/login");
|
||||
}
|
||||
}
|
||||
fetchUser();
|
||||
} else {
|
||||
toast.error("No access token found");
|
||||
router.replace("/login");
|
||||
}
|
||||
}, [login, router]);
|
||||
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-screen">
|
||||
<span>Logging you in...</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -218,15 +218,17 @@ export default function SignupPage() {
|
||||
Or register with
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
|
||||
onClick={() =>
|
||||
toast.info("Google signup would be implemented here")
|
||||
}
|
||||
onClick={() => {
|
||||
const apiBaseUrl =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL ||
|
||||
"http://127.0.0.1:8080/api/v1";
|
||||
window.location.href = `${apiBaseUrl}/auth/google/login`;
|
||||
}}
|
||||
>
|
||||
<Icons.google className="mr-2 h-4 w-4" />
|
||||
Google
|
||||
|
||||
@ -28,7 +28,6 @@ export default function TodosLayout({
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
router.push("/login");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user