Compare commits

...

1 Commits

Author SHA1 Message Date
Piyush Gupta
5fd1cd65d1 chore: adds debug logs 2025-06-05 09:57:02 +05:30
17 changed files with 87 additions and 10 deletions

View File

@@ -0,0 +1,3 @@
import { GET } from "@/modules/ee/auth/saml/api/well-known/cert/route";
export { GET };

View File

@@ -0,0 +1,3 @@
import { GET } from "@/modules/ee/auth/saml/api/well-known/sp-metadata/route";
export { GET };

View File

@@ -597,7 +597,6 @@
"contact_deleted_successfully": "Kontakt erfolgreich gelöscht",
"contact_not_found": "Kein solcher Kontakt gefunden",
"contacts_table_refresh": "Kontakte aktualisieren",
"contacts_table_refresh_error": "Beim Aktualisieren der Kontakte ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.",
"contacts_table_refresh_success": "Kontakte erfolgreich aktualisiert",
"first_name": "Vorname",
"last_name": "Nachname",

View File

@@ -597,7 +597,6 @@
"contact_deleted_successfully": "Contact deleted successfully",
"contact_not_found": "No such contact found",
"contacts_table_refresh": "Refresh contacts",
"contacts_table_refresh_error": "Something went wrong while refreshing contacts, please try again",
"contacts_table_refresh_success": "Contacts refreshed successfully",
"first_name": "First Name",
"last_name": "Last Name",

View File

@@ -597,7 +597,6 @@
"contact_deleted_successfully": "Contact supprimé avec succès",
"contact_not_found": "Aucun contact trouvé",
"contacts_table_refresh": "Rafraîchir les contacts",
"contacts_table_refresh_error": "Une erreur s'est produite lors de la mise à jour des contacts. Veuillez réessayer.",
"contacts_table_refresh_success": "Contacts rafraîchis avec succès",
"first_name": "Prénom",
"last_name": "Nom de famille",

View File

@@ -597,7 +597,6 @@
"contact_deleted_successfully": "Contato excluído com sucesso",
"contact_not_found": "Nenhum contato encontrado",
"contacts_table_refresh": "Atualizar contatos",
"contacts_table_refresh_error": "Ocorreu um erro ao atualizar os contatos. Por favor, tente novamente.",
"contacts_table_refresh_success": "Contatos atualizados com sucesso",
"first_name": "Primeiro Nome",
"last_name": "Sobrenome",

View File

@@ -597,7 +597,6 @@
"contact_deleted_successfully": "Contacto eliminado com sucesso",
"contact_not_found": "Nenhum contacto encontrado",
"contacts_table_refresh": "Atualizar contactos",
"contacts_table_refresh_error": "Algo correu mal ao atualizar os contactos, por favor, tente novamente",
"contacts_table_refresh_success": "Contactos atualizados com sucesso",
"first_name": "Primeiro Nome",
"last_name": "Apelido",

View File

@@ -597,7 +597,6 @@
"contact_deleted_successfully": "聯絡人已成功刪除",
"contact_not_found": "找不到此聯絡人",
"contacts_table_refresh": "重新整理聯絡人",
"contacts_table_refresh_error": "重新整理聯絡人時發生錯誤,請再試一次",
"contacts_table_refresh_success": "聯絡人已成功重新整理",
"first_name": "名字",
"last_name": "姓氏",

View File

@@ -187,6 +187,7 @@ export const authOptions: NextAuthOptions = {
},
callbacks: {
async jwt({ token }) {
console.log("jwt: token", token);
const existingUser = await getUserByEmail(token?.email!);
if (!existingUser) {
@@ -200,6 +201,8 @@ export const authOptions: NextAuthOptions = {
};
},
async session({ session, token }) {
console.log("session: session", session);
console.log("session: token", token);
// @ts-expect-error
session.user.id = token?.id;
// @ts-expect-error
@@ -223,6 +226,9 @@ export const authOptions: NextAuthOptions = {
return true;
}
if (ENTERPRISE_LICENSE_KEY) {
console.log("signIn: user", user);
console.log("signIn: account", account);
console.log("signIn: callbackUrl", callbackUrl);
const result = await handleSsoCallback({ user, account, callbackUrl });
if (result) {

View File

@@ -20,10 +20,13 @@ export const GET = async (req: NextRequest) => {
try {
const { redirect_url } = await oauthController.authorize(searchParams as OAuthReq);
console.log("saml/authorize", redirect_url);
if (!redirect_url) {
return responses.internalServerErrorResponse("Failed to get redirect URL");
}
console.log("saml/authorize: reached to return redirect url", redirect_url);
return NextResponse.redirect(redirect_url);
} catch (err: unknown) {
const errorMessage = err instanceof Error ? err.message : "An unknown error occurred";

View File

@@ -15,18 +15,24 @@ export const POST = async (req: Request) => {
const { oauthController } = jacksonInstance;
const formData = await req.formData();
console.log("saml/callback: formData", formData);
const body = Object.fromEntries(formData.entries());
const { RelayState, SAMLResponse } = body as unknown as SAMLCallbackBody;
console.log("saml/callback: RelayState", RelayState);
console.log("saml/callback: SAMLResponse", SAMLResponse);
const { redirect_url } = await oauthController.samlResponse({
RelayState,
SAMLResponse,
});
console.log("saml/callback: redirect_url", redirect_url);
if (!redirect_url) {
return responses.internalServerErrorResponse("Failed to get redirect URL");
}
console.log("saml/callback: redirecting to", redirect_url);
return redirect(redirect_url);
};

View File

@@ -10,9 +10,13 @@ export const POST = async (req: Request) => {
const { oauthController } = jacksonInstance;
const body = await req.formData();
console.log("saml/token: body", body);
const formData = Object.fromEntries(body.entries());
console.log("saml/token: formData", formData);
const response = await oauthController.token(formData as unknown as OAuthTokenReq);
console.log("saml/token: response", response);
return Response.json(response);
};

View File

@@ -9,8 +9,8 @@ export const GET = async (req: Request) => {
}
const { oauthController } = jacksonInstance;
const token = extractAuthToken(req);
console.log("saml/userinfo: token", token);
const user = await oauthController.userInfo(token);
console.log("saml/userinfo: user", user);
return Response.json(user);
};

View File

@@ -0,0 +1,20 @@
import { responses } from "@/app/lib/api/response";
import jackson from "@/modules/ee/auth/saml/lib/jackson";
export async function GET() {
const jacksonInstance = await jackson();
if (!jacksonInstance) {
return responses.forbiddenResponse("SAML SSO is not enabled in your Formbricks license");
}
const { spConfig } = jacksonInstance;
const config = await spConfig.get();
return new Response(config.publicKey, {
status: 200,
headers: {
"Content-Type": "application/x-x509-ca-cert",
},
});
}

View File

@@ -0,0 +1,22 @@
import { responses } from "@/app/lib/api/response";
import jackson from "@/modules/ee/auth/saml/lib/jackson";
import { NextRequest } from "next/server";
export const GET = async (req: NextRequest) => {
const { searchParams } = new URL(req.url);
const encryption = searchParams.get("encryption") === "true";
const jacksonInstance = await jackson();
if (!jacksonInstance) {
return responses.forbiddenResponse("SAML SSO is not enabled in your Formbricks license");
}
const { spConfig } = jacksonInstance;
const xml = await spConfig.toXMLMetadata(encryption);
return new Response(xml, {
status: 200,
headers: {
"Content-Type": "text/xml",
},
});
};

View File

@@ -3,7 +3,12 @@
import { SAML_AUDIENCE, SAML_DATABASE_URL, SAML_PATH, WEBAPP_URL } from "@/lib/constants";
import { preloadConnection } from "@/modules/ee/auth/saml/lib/preload-connection";
import { getIsSamlSsoEnabled } from "@/modules/ee/license-check/lib/utils";
import type { IConnectionAPIController, IOAuthController, JacksonOption } from "@boxyhq/saml-jackson";
import type {
IConnectionAPIController,
IOAuthController,
ISPSSOConfig,
JacksonOption,
} from "@boxyhq/saml-jackson";
const opts: JacksonOption = {
externalUrl: WEBAPP_URL,
@@ -19,12 +24,13 @@ const opts: JacksonOption = {
declare global {
var oauthController: IOAuthController | undefined;
var connectionController: IConnectionAPIController | undefined;
var spConfig: ISPSSOConfig | undefined;
}
const g = global;
export default async function init() {
if (!g.oauthController || !g.connectionController) {
if (!g.oauthController || !g.connectionController || !g.spConfig) {
const isSamlSsoEnabled = await getIsSamlSsoEnabled();
if (!isSamlSsoEnabled) return;
@@ -34,10 +40,12 @@ export default async function init() {
g.oauthController = ret.oauthController;
g.connectionController = ret.connectionAPIController;
g.spConfig = ret.spConfig;
}
return {
oauthController: g.oauthController,
connectionController: g.connectionController,
spConfig: g.spConfig,
};
}

View File

@@ -403,6 +403,14 @@ const nextConfig = {
source: "/api/v1/management/attribute-classes/:id*",
destination: "/api/v1/management/contact-attribute-keys/:id*",
},
{
source: "/.well-known/saml.cer",
destination: "/api/auth/saml/well-known/cert",
},
{
source: "/.well-known/sp-metadata",
destination: "/api/auth/saml/well-known/sp-metadata",
},
];
},
env: {