feat(SW-3541): Do social login after login to SAS * feat(auth): wip social login via curity * Setup social login auth flow * Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/curity-social-login * Added support for getting scandic tokens and refresh them * feat: Enhance social login and session management with auto-refresh and improved error handling * Merge branch 'master' of bitbucket.org:scandic-swap/web into feature/curity-social-login * wrap layout in suspense * revert app/layout.tsx * fix import * cleanup * merge * merge * dont pass client_secret in the url to curity * add state validation when doing social login through /authorize * remove debug logging Approved-by: Anton Gunnarsson
88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
"use client"
|
|
|
|
import { useSession } from "next-auth/react"
|
|
|
|
import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider"
|
|
import { dt } from "@scandic-hotels/common/dt"
|
|
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
|
|
import { trpc } from "@scandic-hotels/trpc/client"
|
|
|
|
import type { Session } from "next-auth"
|
|
import type { ComponentProps, ReactNode } from "react"
|
|
|
|
const logger = createLogger("BookingFlowProviders")
|
|
|
|
export function BookingFlowProviders({ children }: { children: ReactNode }) {
|
|
const user = useBookingFlowUser()
|
|
|
|
return (
|
|
<BookingFlowContextProvider
|
|
data={{
|
|
isLoggedIn: user.state === "loaded" && !!user.data,
|
|
user,
|
|
}}
|
|
>
|
|
{children}
|
|
</BookingFlowContextProvider>
|
|
)
|
|
}
|
|
|
|
type BookingFlowContextData = ComponentProps<
|
|
typeof BookingFlowContextProvider
|
|
>["data"]
|
|
type BookingFlowUser = BookingFlowContextData["user"]
|
|
|
|
function useBookingFlowUser(): BookingFlowUser {
|
|
const { data: session } = useSession()
|
|
const hasValidSession = isValidClientSession(session)
|
|
|
|
const {
|
|
data: euroBonusProfile,
|
|
isError,
|
|
isLoading,
|
|
} = trpc.partner.sas.getEuroBonusProfile.useQuery(undefined, {
|
|
enabled: hasValidSession,
|
|
})
|
|
|
|
if (isLoading) {
|
|
return { state: "loading", data: undefined }
|
|
}
|
|
|
|
if (isError || !euroBonusProfile) {
|
|
return { state: "error", data: undefined }
|
|
}
|
|
|
|
return {
|
|
state: "loaded",
|
|
data: {
|
|
type: "partner-sas",
|
|
partnerLoyaltyNumber: `EB${euroBonusProfile.eurobonusNumber}`,
|
|
firstName: euroBonusProfile.firstName || null,
|
|
lastName: euroBonusProfile.lastName || null,
|
|
email: euroBonusProfile.email,
|
|
},
|
|
}
|
|
}
|
|
|
|
function isValidClientSession(session: Session | null) {
|
|
if (!session) {
|
|
return false
|
|
}
|
|
if (session.error) {
|
|
logger.error(`Session error: ${session.error}`)
|
|
return false
|
|
}
|
|
|
|
if (session.token.error) {
|
|
logger.error(`Session token error: ${session.token.error}`)
|
|
return false
|
|
}
|
|
const expiresAt = dt(session.token.expires_at)
|
|
if (session.token.expires_at && expiresAt.isBefore(dt())) {
|
|
logger.warn(`Session expired: ${expiresAt.toISOString()}`)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|