mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
@@ -22,22 +22,35 @@ export function AuthProvider({ children }) {
|
||||
_setAccessToken(token)
|
||||
}, [])
|
||||
|
||||
// Shared by verifyOTP, restoreSession, and login's trusted-device fast path
|
||||
// — anywhere the backend hands back a fully-authenticated session in one shot.
|
||||
const applySession = useCallback((data) => {
|
||||
setAccessToken(data.accessToken)
|
||||
setUser(data.user)
|
||||
setSessionId(data.session_id ?? null)
|
||||
}, [setAccessToken])
|
||||
|
||||
// ── Login ──────────────────────────────────────────────────────────────────
|
||||
// Credentials get you an OTP — unless this device already cleared one
|
||||
// recently and its trust window is still valid, in which case the backend
|
||||
// returns otpRequired:false along with a full session, same shape as
|
||||
// verifyOTP's response.
|
||||
const login = useCallback(async ({ email, password }) => {
|
||||
setAuthError(null)
|
||||
try {
|
||||
const { data } = await api.post('/auth/login', { email, password })
|
||||
setAccessToken(data.data.accessToken)
|
||||
setUser(data.data.user)
|
||||
setSessionId(data.data.session_id ?? null)
|
||||
return { success: true, user: data.data.user }
|
||||
if (data.data.otpRequired === false) {
|
||||
applySession(data.data)
|
||||
return { success: true, otpRequired: false, user: data.data.user }
|
||||
}
|
||||
return { success: true, otpRequired: true, email: data.data.email }
|
||||
} catch (err) {
|
||||
const message = err.response?.data?.message || 'Login failed. Please try again.'
|
||||
const errors = err.response?.data?.errors ?? null
|
||||
setAuthError(message)
|
||||
return { success: false, message, errors }
|
||||
}
|
||||
}, [])
|
||||
}, [applySession])
|
||||
|
||||
// ── Register ───────────────────────────────────────────────────────────────
|
||||
const register = useCallback(async (payload) => {
|
||||
@@ -57,16 +70,14 @@ export function AuthProvider({ children }) {
|
||||
setAuthError(null)
|
||||
try {
|
||||
const { data } = await api.post('/auth/verify-otp', { email, otp })
|
||||
setAccessToken(data.data.accessToken)
|
||||
setUser(data.data.user)
|
||||
setSessionId(data.data.session_id ?? null)
|
||||
applySession(data.data)
|
||||
return { success: true, user: data.data.user }
|
||||
} catch (err) {
|
||||
const message = err.response?.data?.message || 'OTP verification failed.'
|
||||
setAuthError(message)
|
||||
return { success: false, message }
|
||||
}
|
||||
}, [])
|
||||
}, [applySession])
|
||||
|
||||
// ── Resend OTP ─────────────────────────────────────────────────────────────
|
||||
const resendOTP = useCallback(async ({ email }) => {
|
||||
@@ -79,6 +90,28 @@ export function AuthProvider({ children }) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
// ── Forgot password (request OTP) ─────────────────────────────────────────
|
||||
const forgotPassword = useCallback(async ({ email }) => {
|
||||
try {
|
||||
const { data } = await api.post('/auth/forgot-password', { email })
|
||||
return { success: true, email: data.data.email }
|
||||
} catch (err) {
|
||||
const message = err.response?.data?.message || 'Could not process request.'
|
||||
return { success: false, message }
|
||||
}
|
||||
}, [])
|
||||
|
||||
// ── Reset password (OTP + new password in one step) ───────────────────────
|
||||
const resetPassword = useCallback(async ({ email, otp, new_password }) => {
|
||||
try {
|
||||
await api.post('/auth/reset-password', { email, otp, new_password })
|
||||
return { success: true }
|
||||
} catch (err) {
|
||||
const message = err.response?.data?.message || 'Password reset failed.'
|
||||
return { success: false, message }
|
||||
}
|
||||
}, [])
|
||||
|
||||
// ── Logout ─────────────────────────────────────────────────────────────────
|
||||
const logout = useCallback(async () => {
|
||||
try {
|
||||
@@ -94,23 +127,23 @@ export function AuthProvider({ children }) {
|
||||
|
||||
// ── Restore session ────────────────────────────────────────────────────────
|
||||
const restoreSession = useCallback(async () => {
|
||||
if (isRestoring.current) return
|
||||
if (isRestoring.current) return { success: false }
|
||||
isRestoring.current = true
|
||||
|
||||
try {
|
||||
if (accessTokenRef.current) return
|
||||
if (accessTokenRef.current) return { success: true }
|
||||
const { data } = await api.post('/auth/refresh')
|
||||
setAccessToken(data.data.accessToken)
|
||||
setUser(data.data.user)
|
||||
setSessionId(data.data.session_id ?? null)
|
||||
applySession(data.data)
|
||||
return { success: true, user: data.data.user }
|
||||
} catch (_) {
|
||||
setAccessToken(null)
|
||||
setUser(null)
|
||||
setSessionId(null)
|
||||
return { success: false }
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [])
|
||||
}, [applySession])
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={{
|
||||
@@ -124,6 +157,8 @@ export function AuthProvider({ children }) {
|
||||
register,
|
||||
verifyOTP,
|
||||
resendOTP,
|
||||
forgotPassword,
|
||||
resetPassword,
|
||||
logout,
|
||||
loading,
|
||||
sessionRestored,
|
||||
|
||||
Reference in New Issue
Block a user