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:
13
apps/partner-sas/auth/scandic/config.ts
Normal file
13
apps/partner-sas/auth/scandic/config.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import "server-only"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
export const config = {
|
||||
issuer: env.CURITY_ISSUER_USER,
|
||||
client_id: "whitelabel-sas-social-login",
|
||||
client_secret: env.CURITY_CLIENT_SECRET_USER,
|
||||
redirect_uri: new URL("/api/web/auth/callback/curity", env.PUBLIC_URL).href,
|
||||
acr_values: "urn:com:scandichotels:sas-eb",
|
||||
scope: "openid profile availability availability_whitelabel_get",
|
||||
response_type: "code",
|
||||
} as const
|
||||
13
apps/partner-sas/auth/scandic/endpoints.ts
Normal file
13
apps/partner-sas/auth/scandic/endpoints.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import { config } from "@/auth/scandic/config"
|
||||
|
||||
export const endpoints = {
|
||||
authorization_endpoint: new URL(
|
||||
`/oauth/v2/authorize?allow=local&ui_locales=en&version=2&for_origin=${env.PUBLIC_URL}`,
|
||||
config.issuer
|
||||
),
|
||||
token_endpoint: new URL("/oauth/v2/token?allow=local", config.issuer),
|
||||
userinfo_endpoint: new URL("/oauth/v2/userinfo?allow=local", config.issuer),
|
||||
end_session_endpoint: new URL("/oauth/v2/logout?allow=local", config.issuer),
|
||||
} as const
|
||||
38
apps/partner-sas/auth/scandic/getToken.ts
Normal file
38
apps/partner-sas/auth/scandic/getToken.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { config } from "./config"
|
||||
import { endpoints } from "./endpoints"
|
||||
|
||||
export async function getToken({ code }: { code: string }) {
|
||||
const params = new URLSearchParams({
|
||||
grant_type: "authorization_code",
|
||||
code,
|
||||
redirect_uri: config.redirect_uri,
|
||||
client_id: config.client_id,
|
||||
client_secret: config.client_secret,
|
||||
})
|
||||
|
||||
const res = await fetch(endpoints.token_endpoint.toString(), {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Accept: "application/json",
|
||||
},
|
||||
body: params,
|
||||
signal: AbortSignal.timeout(15_000),
|
||||
})
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text()
|
||||
throw new Error(`Token endpoint returned ${res.status}: ${text}`)
|
||||
}
|
||||
|
||||
const payload = await res.json()
|
||||
|
||||
return payload as {
|
||||
access_token: string
|
||||
token_type?: string
|
||||
expires_in: number
|
||||
refresh_token?: string
|
||||
id_token?: string
|
||||
scope?: string
|
||||
}
|
||||
}
|
||||
46
apps/partner-sas/auth/scandic/session.ts
Normal file
46
apps/partner-sas/auth/scandic/session.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import "server-only"
|
||||
|
||||
import { getIronSession } from "iron-session"
|
||||
import { cookies } from "next/headers"
|
||||
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
export async function getSession() {
|
||||
return getIronSession<{
|
||||
access_token: string
|
||||
refresh_token: string | undefined
|
||||
expires_at: string
|
||||
}>(await cookies(), {
|
||||
password: env.IRON_SESSION_SECRET,
|
||||
cookieName: "scandic_session",
|
||||
})
|
||||
}
|
||||
|
||||
export async function createSession({
|
||||
access_token,
|
||||
refresh_token,
|
||||
expires_in,
|
||||
}: {
|
||||
access_token: string
|
||||
expires_in: number
|
||||
refresh_token?: string
|
||||
}) {
|
||||
const session = await getSession()
|
||||
|
||||
session.access_token = access_token
|
||||
session.refresh_token = refresh_token
|
||||
session.expires_at = dt()
|
||||
.add(expires_in * 1000)
|
||||
.toISOString()
|
||||
|
||||
await session.save()
|
||||
}
|
||||
|
||||
export async function destroySession() {
|
||||
const session = await getSession()
|
||||
if (!session) return
|
||||
|
||||
session.destroy()
|
||||
}
|
||||
Reference in New Issue
Block a user