mirror of
https://github.com/Sosokker/go-chi-oapi-codegen-todolist.git
synced 2025-12-19 05:54: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),
|
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)
|
h.logger.InfoContext(ctx, "Google OAuth login successful", "userId", user.ID, "email", user.Email, "redirectingTo", redirectURL)
|
||||||
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
http.Redirect(w, r, redirectURL, http.StatusTemporaryRedirect)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,14 +14,11 @@ import (
|
|||||||
|
|
||||||
// GoogleUserInfo holds user details fetched from Google.
|
// GoogleUserInfo holds user details fetched from Google.
|
||||||
type GoogleUserInfo struct {
|
type GoogleUserInfo struct {
|
||||||
ID string `json:"id"` // The unique Google ID
|
ID string `json:"sub"`
|
||||||
Email string `json:"email"` // The user's email address
|
Email string `json:"email"`
|
||||||
VerifiedEmail bool `json:"verified_email"` // Whether Google has verified the email
|
VerifiedEmail bool `json:"email_verified"`
|
||||||
Name string `json:"name"` // User's full name
|
Name string `json:"name"`
|
||||||
GivenName string `json:"given_name"` // First name
|
Picture string `json:"picture"`
|
||||||
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")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OAuthProvider defines the interface for OAuth operations.
|
// OAuthProvider defines the interface for OAuth operations.
|
||||||
|
|||||||
@ -16,6 +16,7 @@ type Config struct {
|
|||||||
OAuth OAuthConfig
|
OAuth OAuthConfig
|
||||||
Cache CacheConfig
|
Cache CacheConfig
|
||||||
Storage StorageConfig
|
Storage StorageConfig
|
||||||
|
Frontend FrontendConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServerConfig struct {
|
type ServerConfig struct {
|
||||||
@ -37,9 +38,9 @@ type LocalStorageConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GCSStorageConfig struct {
|
type GCSStorageConfig struct {
|
||||||
BucketName string `mapstructure:"bucketName"`
|
BucketName string `mapstructure:"bucketName"`
|
||||||
CredentialsFile string `mapstructure:"credentialsFile"`
|
CredentialsFile string `mapstructure:"credentialsFile"`
|
||||||
BaseDir string `mapstructure:"baseDir"`
|
BaseDir string `mapstructure:"baseDir"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DatabaseConfig struct {
|
type DatabaseConfig struct {
|
||||||
@ -79,6 +80,10 @@ type CacheConfig struct {
|
|||||||
CleanupInterval time.Duration `mapstructure:"cleanupInterval"`
|
CleanupInterval time.Duration `mapstructure:"cleanupInterval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FrontendConfig struct {
|
||||||
|
Url string `mapstructure:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
func LoadConfig(path string) (*Config, error) {
|
func LoadConfig(path string) (*Config, error) {
|
||||||
viper.SetConfigName("config") // name of config file (without extension)
|
viper.SetConfigName("config") // name of config file (without extension)
|
||||||
viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
|
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("cache.cleanupInterval", 10*time.Minute)
|
||||||
viper.SetDefault("storage.type", "local") // Default to local storage
|
viper.SetDefault("storage.type", "local") // Default to local storage
|
||||||
viper.SetDefault("storage.local.path", "./uploads")
|
viper.SetDefault("storage.local.path", "./uploads")
|
||||||
|
viper.SetDefault("frontend.url", "http://localhost:3000")
|
||||||
|
|
||||||
err := viper.ReadInConfig()
|
err := viper.ReadInConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -199,15 +199,17 @@ export default function LoginPage() {
|
|||||||
Or continue with
|
Or continue with
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 gap-4">
|
<div className="grid grid-cols-1 gap-4">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
|
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
toast.info("Google signup would be implemented here")
|
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" />
|
<Icons.google className="mr-2 h-4 w-4" />
|
||||||
Google
|
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
|
Or register with
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 gap-4">
|
<div className="grid grid-cols-1 gap-4">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
|
className="w-full border-gray-300 text-gray-900 hover:bg-gray-100"
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
toast.info("Google signup would be implemented here")
|
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" />
|
<Icons.google className="mr-2 h-4 w-4" />
|
||||||
Google
|
Google
|
||||||
|
|||||||
@ -28,7 +28,6 @@ export default function TodosLayout({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
router.push("/login");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user