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
This commit is contained in:
Joakim Jäderberg
2025-10-16 12:47:12 +00:00
parent 1850cfd20d
commit 291310e841
24 changed files with 827 additions and 84 deletions

View File

@@ -0,0 +1,59 @@
"use client"
import React, { createContext, useContext } from "react"
import { useSocialSession } from "@/hooks/useSocialSession"
/* eslint-disable formatjs/no-literal-string-in-jsx */
type SocialLoginContextType = {
session: ReturnType<typeof useSocialSession>["session"]
refresh: ReturnType<typeof useSocialSession>["refresh"]
}
const SocialLoginContext = createContext<SocialLoginContextType | undefined>(
undefined
)
export function SocialLoginProvider({
children,
}: {
children: React.ReactNode
}) {
const { session: socialSession, refresh } = useSocialSession()
return (
<SocialLoginContext.Provider value={{ session: socialSession, refresh }}>
{process.env.NODE_ENV === "development" && (
<>
<span>Social login: </span>
{socialSession.data?.status}{" "}
{socialSession?.data?.status === "expired" && (
<>
<span>Expires@{socialSession?.data.expiresAt}</span>{" "}
<button onClick={() => refresh.mutate()}>Refresh</button>
</>
)}
{socialSession?.data?.status === "valid" && (
<>
<span>Expires@{socialSession?.data.expiresAt}</span>{" "}
<button onClick={() => refresh.mutate()}>Refresh</button>
</>
)}
</>
)}
{children}
</SocialLoginContext.Provider>
)
}
export function useSocialLogin() {
const ctx = useContext(SocialLoginContext)
if (!ctx) {
throw new Error(
"useSocialLogin must be used within SocialLoginContextProvider"
)
}
return ctx
}

View File

@@ -28,17 +28,13 @@ import { FontPreload } from "@/fonts/font-preloading"
import { getMessages } from "@/i18n"
import ClientIntlProvider from "@/i18n/Provider"
import { setLang } from "@/i18n/serverContext"
import { routeToScandicWeb } from "@/util"
import { BookingFlowProviders } from "../../components/BookingFlowProviders"
import { Footer } from "../../components/Footer/Footer"
import { Header } from "../../components/Header/Header"
import { SocialLoginProvider } from "./(auth)/SocialLogin"
import type { Metadata } from "next"
export const metadata: Metadata = {
description: "TODO This text should be updated.",
}
import type { LangRoute } from "@scandic-hotels/common/constants/routes/langRoute"
type LangParams = {
lang: Lang
@@ -74,7 +70,7 @@ export default async function RootLayout(props: RootLayoutProps) {
}
return (
<html lang="en">
<html lang={lang}>
<head>
<FontPreload />
<AdobeSDKScript />
@@ -95,21 +91,23 @@ export default async function RootLayout(props: RootLayoutProps) {
>
<NuqsAdapter>
<TrpcProvider>
<RACRouterProvider>
<BookingFlowConfig config={bookingFlowConfig}>
<BookingFlowProviders>
<RouteChange />
<SiteWideAlert />
<Header />
{props.bookingwidget}
<main>{children}</main>
<Footer />
<ToastHandler />
<CookieBotConsent />
<ReactQueryDevtools initialIsOpen={false} />
</BookingFlowProviders>
</BookingFlowConfig>
</RACRouterProvider>
<SocialLoginProvider>
<RACRouterProvider>
<BookingFlowConfig config={bookingFlowConfig}>
<BookingFlowProviders>
<RouteChange />
<SiteWideAlert />
<Header />
{props.bookingwidget}
<main>{children}</main>
<Footer />
<ToastHandler />
<CookieBotConsent />
<ReactQueryDevtools initialIsOpen={false} />
</BookingFlowProviders>
</BookingFlowConfig>
</RACRouterProvider>
</SocialLoginProvider>
</TrpcProvider>
</NuqsAdapter>
</ClientIntlProvider>
@@ -129,3 +127,11 @@ export default async function RootLayout(props: RootLayoutProps) {
</html>
)
}
function routeToScandicWeb(route: LangRoute) {
const url = `https://www.scandichotels.com`
return Object.entries(route).reduce((acc, [key, value]) => {
acc[key as Lang] = `${url}${value}`
return acc
}, {} as LangRoute)
}