From 291310e841fd84bf67096339e724297e75d1f530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20J=C3=A4derberg?= Date: Thu, 16 Oct 2025 12:47:12 +0000 Subject: [PATCH] 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 --- .../app/[lang]/(auth)/SocialLogin.tsx | 59 ++++++ apps/partner-sas/app/[lang]/layout.tsx | 50 ++--- .../app/api/web/auth/callback/curity/route.ts | 51 +++++ .../app/api/web/auth/scandic/login/route.ts | 53 +++++ .../app/api/web/auth/scandic/logout/route.ts | 12 ++ .../app/api/web/auth/scandic/refresh/route.ts | 122 ++++++++++++ .../app/api/web/auth/scandic/session/route.ts | 66 +++++++ apps/partner-sas/auth.ts | 11 ++ apps/partner-sas/auth/scandic/config.ts | 13 ++ apps/partner-sas/auth/scandic/endpoints.ts | 13 ++ apps/partner-sas/auth/scandic/getToken.ts | 38 ++++ apps/partner-sas/auth/scandic/session.ts | 46 +++++ .../components/BookingFlowProviders.tsx | 10 +- apps/partner-sas/env/server.ts | 12 +- apps/partner-sas/hooks/useSocialSession.ts | 184 ++++++++++++++++++ apps/partner-sas/package.json | 2 + apps/partner-sas/server/errors/next.ts | 21 ++ apps/partner-sas/tsconfig.json | 8 +- apps/scandic-web/utils/clientSession.ts | 3 +- .../SelectRate/SelectRateContext/index.tsx | 23 ++- .../partners/sas/getEuroBonusProfile.ts | 72 +++---- .../trpc/lib/utils/getUserPointsBalance.ts | 9 +- packages/trpc/package.json | 2 + yarn.lock | 31 ++- 24 files changed, 827 insertions(+), 84 deletions(-) create mode 100644 apps/partner-sas/app/[lang]/(auth)/SocialLogin.tsx create mode 100644 apps/partner-sas/app/api/web/auth/callback/curity/route.ts create mode 100644 apps/partner-sas/app/api/web/auth/scandic/login/route.ts create mode 100644 apps/partner-sas/app/api/web/auth/scandic/logout/route.ts create mode 100644 apps/partner-sas/app/api/web/auth/scandic/refresh/route.ts create mode 100644 apps/partner-sas/app/api/web/auth/scandic/session/route.ts create mode 100644 apps/partner-sas/auth/scandic/config.ts create mode 100644 apps/partner-sas/auth/scandic/endpoints.ts create mode 100644 apps/partner-sas/auth/scandic/getToken.ts create mode 100644 apps/partner-sas/auth/scandic/session.ts create mode 100644 apps/partner-sas/hooks/useSocialSession.ts diff --git a/apps/partner-sas/app/[lang]/(auth)/SocialLogin.tsx b/apps/partner-sas/app/[lang]/(auth)/SocialLogin.tsx new file mode 100644 index 000000000..257f3ecaf --- /dev/null +++ b/apps/partner-sas/app/[lang]/(auth)/SocialLogin.tsx @@ -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["session"] + refresh: ReturnType["refresh"] +} + +const SocialLoginContext = createContext( + undefined +) + +export function SocialLoginProvider({ + children, +}: { + children: React.ReactNode +}) { + const { session: socialSession, refresh } = useSocialSession() + + return ( + + {process.env.NODE_ENV === "development" && ( + <> + Social login: + {socialSession.data?.status}{" "} + {socialSession?.data?.status === "expired" && ( + <> + Expires@{socialSession?.data.expiresAt}{" "} + + + )} + {socialSession?.data?.status === "valid" && ( + <> + Expires@{socialSession?.data.expiresAt}{" "} + + + )} + + )} + + {children} + + ) +} + +export function useSocialLogin() { + const ctx = useContext(SocialLoginContext) + if (!ctx) { + throw new Error( + "useSocialLogin must be used within SocialLoginContextProvider" + ) + } + return ctx +} diff --git a/apps/partner-sas/app/[lang]/layout.tsx b/apps/partner-sas/app/[lang]/layout.tsx index 888a27ff8..1ea0429aa 100644 --- a/apps/partner-sas/app/[lang]/layout.tsx +++ b/apps/partner-sas/app/[lang]/layout.tsx @@ -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 ( - + @@ -95,21 +91,23 @@ export default async function RootLayout(props: RootLayoutProps) { > - - - - - -
- {props.bookingwidget} -
{children}
-