Files
web/apps/partner-sas/auth.ts
Joakim Jäderberg 8ebc48b138 Merged in feat/SW-3461-setup-auth-with-sas-eurobonus (pull request #2825)
Feat/SW-3461 setup auth with sas eurobonus

* feat(SW-3461): Setup auth for sas eurobonus

* .

* feat: setup auth towards SAS

* Fix auth via SAS and add logout route

* .

* merge

* auth via SAS

* fix powered by scandic logo

* Merge branch 'master' of bitbucket.org:scandic-swap/web into feat/SW-3461-setup-auth-with-sas-eurobonus

* Include access_token in jwt after successful login

* merge


Approved-by: Anton Gunnarsson
2025-09-22 09:30:36 +00:00

128 lines
3.2 KiB
TypeScript

import NextAuth, { type NextAuthConfig } from "next-auth"
import Auth0Provider from "next-auth/providers/auth0"
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
import { env } from "@/env/server"
const authLogger = createLogger("auth")
/*
TODO: Get info for SAS token timeout and accordingly adjust pre-refresh time move to common/contants
Do we need to handle refresh tokens at all, isn't that handled by the Auth0 provider?
Needs to be verified
*/
const sasProvider = Auth0Provider({
id: "sas",
name: "SAS",
clientId: env.SAS_AUTH_CLIENTID,
issuer: env.SAS_AUTH_ENDPOINT,
checks: ["state"],
authorization: {
params: {
audience: "eb-partner-api",
},
},
client: {
token_endpoint_auth_method: "none",
},
})
const config: NextAuthConfig = {
basePath: "/api/web/auth",
providers: [sasProvider],
session: {
strategy: "jwt",
},
cookies: {
sessionToken: {
name: "sas-session",
},
},
callbacks: {
async signIn() {
return true
},
async jwt(params) {
if (params.trigger === "signIn") {
const accessToken = params.account?.access_token
const expiresAt = params.account?.expires_at
if (!accessToken) {
throw new Error("AuthError: Missing access token")
}
if (!expiresAt) {
throw new Error("AuthError: Missing expiry time")
}
return {
...params.token,
loginType: "sas",
access_token: accessToken,
expires_at: expiresAt,
}
}
return params.token
},
async session({ session, token }) {
return {
...session,
error: token.error,
user: session.user
? {
...session.user,
id: token.sub,
}
: undefined,
token: {
access_token: token.access_token,
expires_at: token.expires_at,
error: token.error,
},
}
},
async redirect({ baseUrl, url }) {
authLogger.debug(`[auth] deciding redirect URL`, { baseUrl, url })
if (url.startsWith("/")) {
authLogger.debug(
`[auth] relative URL accepted, returning: ${baseUrl}${url}`
)
// Allows relative callback URLs
return `${baseUrl}${url}`
} else {
// Assume absolute URL
try {
const parsedUrl = new URL(url)
if (/\.scandichotels\.com$/.test(parsedUrl.hostname)) {
authLogger.debug(`[auth] subdomain URL accepted, returning: ${url}`)
// Allows any subdomains on all top level domains above
return url
} else if (parsedUrl.origin === baseUrl) {
// Allows callback URLs on the same origin
authLogger.debug(`[auth] origin URL accepted, returning: ${url}`)
return url
}
} catch (e) {
authLogger.error(
`[auth] error parsing incoming URL for redirection`,
e
)
}
}
authLogger.debug(`[auth] URL denied, returning base URL: ${baseUrl}`)
return baseUrl
},
},
}
export const {
handlers: { GET, POST },
signIn,
signOut,
} = NextAuth(config)
export const { auth } = NextAuth(config)