Files
web/apps/scandic-web/auth.dtmc.ts
Chuma Mcphoy (We Ahead) 6a0675525d Merged in fix/dtmc-debugging (pull request #2683)
Chore: DTMC Logging

* chore: DTMC debugging

* fix: prune dtmc logging

* fix: Add id's from azure in error logging


Approved-by: Linus Flood
Approved-by: Matilda Landström
2025-08-21 13:12:56 +00:00

122 lines
3.4 KiB
TypeScript

import NextAuth, { type NextAuthConfig } from "next-auth"
import MicrosoftEntraID from "next-auth/providers/microsoft-entra-id"
import { logger } from "@scandic-hotels/common/logger"
import { env } from "@/env/server"
const config = {
basePath: "/api/web/auth",
debug: env.NEXTAUTH_DEBUG,
cookies: {
sessionToken: {
name: "dtmc.session-token",
},
},
providers: [
MicrosoftEntraID({
clientId: env.DTMC_ENTRA_ID_CLIENT,
clientSecret: env.DTMC_ENTRA_ID_SECRET,
issuer: env.DTMC_ENTRA_ID_ISSUER,
authorization: {
params: {
scope: "openid profile email User.Read",
},
},
}),
],
redirectProxyUrl: env.NEXTAUTH_REDIRECT_PROXY_URL,
trustHost: true,
session: {
strategy: "jwt",
maxAge: 10 * 60, // 10 minutes
},
callbacks: {
async signIn() {
return true
},
async session({ session, token }) {
if (token && token.employeeId && typeof token.employeeId === "string") {
session.employeeId = token.employeeId
}
return session
},
async redirect({ baseUrl, url }) {
logger.debug(`[auth.dtmc] deciding redirect URL`, { baseUrl, url })
if (url.startsWith("/")) {
logger.debug(
`[auth.dtmc] 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\.(dk|de|com|fi|no|se)$/.test(parsedUrl.hostname)
) {
logger.debug(
`[auth.dtmc] 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
logger.debug(`[auth.dtmc] origin URL accepted, returning: ${url}`)
return url
}
} catch (e) {
logger.error(
`[auth.dtmc] error parsing incoming URL for redirection`,
e
)
}
}
logger.debug(`[auth.dtmc] URL denied, returning base URL: ${baseUrl}`)
return baseUrl
},
async authorized() {
return true
},
async jwt({ account, trigger, profile, token }) {
if (
trigger === "signIn" &&
account &&
account.provider === "microsoft-entra-id" &&
profile
) {
const employeeId = profile["user.employeeid"]
if (employeeId && typeof employeeId === "string") {
logger.info(
"[auth.dtmc] DTMC authentication successful - employeeId extracted"
)
return {
access_token: "", // JWT requires it, but DTMC does not need it, so save on cookie size by using empty string
loginType: "dtmc",
employeeId,
}
} else {
logger.error(
"[auth.dtmc] DTMC authentication failed - no employeeId found in Microsoft profile. Check Azure app registration optional claims configuration.",
{
userObjectId: profile.oid,
tenantId: profile.tid,
clientId: profile.aud,
}
)
}
}
return token
},
},
} satisfies NextAuthConfig
export const {
auth,
handlers: { GET, POST },
signIn,
signOut,
} = NextAuth(config)