auth media
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState, FormEvent } from "react";
|
import { useEffect, useState} from "react";
|
||||||
import { useSearchParams, Link } from "react-router-dom";
|
import { useSearchParams, Link } from "react-router-dom";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
function saveTokensAndRedirect(token: string, refreshToken: string, redirect: string) {
|
function saveTokensAndRedirect(token: string, refreshToken: string, redirect: string) {
|
||||||
localStorage.setItem("token", token);
|
localStorage.setItem("token", token);
|
||||||
@@ -25,7 +26,7 @@ export default function LoginPage() {
|
|||||||
}
|
}
|
||||||
}, [searchParams, redirect]);
|
}, [searchParams, redirect]);
|
||||||
|
|
||||||
async function handleSubmit(e: FormEvent) {
|
async function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setError("");
|
setError("");
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class OAuth2AuthenticationSuccessHandler implements ServerAuthenticationS
|
|||||||
private final RefreshTokenRepository refreshTokenRepository;
|
private final RefreshTokenRepository refreshTokenRepository;
|
||||||
private final JwtTokenProvider jwtTokenProvider;
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
|
||||||
@Value("${oauth2.redirect-uri:https://balexvic.com/login}")
|
@Value("${oauth2.redirect-uri:https://balexvic.com/auth/login}")
|
||||||
private String redirectUri;
|
private String redirectUri;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -46,19 +46,9 @@ public class OAuth2AuthenticationSuccessHandler implements ServerAuthenticationS
|
|||||||
String email = extractEmail(oAuth2User, registrationId);
|
String email = extractEmail(oAuth2User, registrationId);
|
||||||
String name = extractName(oAuth2User, registrationId);
|
String name = extractName(oAuth2User, registrationId);
|
||||||
|
|
||||||
return userRepository.findByAuthProviderAndProviderId(provider, providerId)
|
log.info("OAuth2 login attempt: provider={}, providerId={}, email={}", provider, providerId, email);
|
||||||
.switchIfEmpty(
|
|
||||||
email != null
|
return findOrCreateUser(provider, providerId, email, name)
|
||||||
? userRepository.findByEmail(email)
|
|
||||||
.flatMap(existingUser -> {
|
|
||||||
existingUser.setAuthProvider(provider);
|
|
||||||
existingUser.setProviderId(providerId);
|
|
||||||
existingUser.setUpdated(LocalDateTime.now());
|
|
||||||
return userRepository.save(existingUser);
|
|
||||||
})
|
|
||||||
.switchIfEmpty(Mono.defer(() -> createNewUser(provider, providerId, email, name)))
|
|
||||||
: Mono.defer(() -> createNewUser(provider, providerId, email, name))
|
|
||||||
)
|
|
||||||
.flatMap(user -> {
|
.flatMap(user -> {
|
||||||
user.setLastLogin(LocalDateTime.now());
|
user.setLastLogin(LocalDateTime.now());
|
||||||
user.setUpdated(LocalDateTime.now());
|
user.setUpdated(LocalDateTime.now());
|
||||||
@@ -66,12 +56,44 @@ public class OAuth2AuthenticationSuccessHandler implements ServerAuthenticationS
|
|||||||
})
|
})
|
||||||
.flatMap(this::generateTokensAndRedirect)
|
.flatMap(this::generateTokensAndRedirect)
|
||||||
.flatMap(redirectUrl -> {
|
.flatMap(redirectUrl -> {
|
||||||
|
log.info("OAuth2 redirect to: {}", redirectUrl);
|
||||||
webFilterExchange.getExchange().getResponse().setStatusCode(HttpStatus.FOUND);
|
webFilterExchange.getExchange().getResponse().setStatusCode(HttpStatus.FOUND);
|
||||||
webFilterExchange.getExchange().getResponse().getHeaders().setLocation(URI.create(redirectUrl));
|
webFilterExchange.getExchange().getResponse().getHeaders().setLocation(URI.create(redirectUrl));
|
||||||
return webFilterExchange.getExchange().getResponse().setComplete();
|
return webFilterExchange.getExchange().getResponse().setComplete();
|
||||||
|
})
|
||||||
|
.onErrorResume(e -> {
|
||||||
|
log.error("OAuth2 authentication failed", e);
|
||||||
|
webFilterExchange.getExchange().getResponse().setStatusCode(HttpStatus.FOUND);
|
||||||
|
webFilterExchange.getExchange().getResponse().getHeaders()
|
||||||
|
.setLocation(URI.create(redirectUri + "?error=auth_failed"));
|
||||||
|
return webFilterExchange.getExchange().getResponse().setComplete();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Mono<User> findOrCreateUser(AuthProvider provider, String providerId, String email, String name) {
|
||||||
|
// 1. Find by provider + providerId (returning OAuth2 user)
|
||||||
|
return userRepository.findByAuthProviderAndProviderId(provider, providerId)
|
||||||
|
.doOnNext(u -> log.info("Found user by provider: id={}, email={}", u.getId(), u.getEmail()))
|
||||||
|
.switchIfEmpty(Mono.defer(() -> {
|
||||||
|
// 2. Find by email (link existing LOCAL account)
|
||||||
|
if (email == null) {
|
||||||
|
return createNewUser(provider, providerId, null, name);
|
||||||
|
}
|
||||||
|
return userRepository.findByEmail(email)
|
||||||
|
.doOnNext(u -> log.info("Found existing user by email: id={}, provider={}", u.getId(), u.getAuthProvider()))
|
||||||
|
.flatMap(existingUser -> linkAccount(existingUser, provider, providerId))
|
||||||
|
.switchIfEmpty(Mono.defer(() -> createNewUser(provider, providerId, email, name)));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<User> linkAccount(User existingUser, AuthProvider provider, String providerId) {
|
||||||
|
existingUser.setAuthProvider(provider);
|
||||||
|
existingUser.setProviderId(providerId);
|
||||||
|
existingUser.setUpdated(LocalDateTime.now());
|
||||||
|
return userRepository.save(existingUser)
|
||||||
|
.doOnNext(u -> log.info("Linked account: id={}, newProvider={}", u.getId(), u.getAuthProvider()));
|
||||||
|
}
|
||||||
|
|
||||||
private Mono<User> createNewUser(AuthProvider provider, String providerId, String email, String name) {
|
private Mono<User> createNewUser(AuthProvider provider, String providerId, String email, String name) {
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setAuthProvider(provider);
|
user.setAuthProvider(provider);
|
||||||
@@ -105,6 +127,7 @@ public class OAuth2AuthenticationSuccessHandler implements ServerAuthenticationS
|
|||||||
}))
|
}))
|
||||||
.map(refreshToken -> {
|
.map(refreshToken -> {
|
||||||
String accessToken = jwtTokenProvider.generateToken(user, refreshToken.getSessionId());
|
String accessToken = jwtTokenProvider.generateToken(user, refreshToken.getSessionId());
|
||||||
|
log.info("Generated tokens for user: id={}, email={}", user.getId(), user.getEmail());
|
||||||
return redirectUri + "?token=" + accessToken + "&refreshToken=" + refreshToken.getToken();
|
return redirectUri + "?token=" + accessToken + "&refreshToken=" + refreshToken.getToken();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user