Files
web/apps/partner-sas/components/BookingFlowProviders.tsx
Joakim Jäderberg 291310e841 Merged in feature/curity-social-login (pull request #2963)
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
2025-10-16 12:47:12 +00:00

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
}