import SuperTokens from "supertokens-node"; import Session from "supertokens-node/recipe/session"; import Dashboard from "supertokens-node/recipe/dashboard"; import UserRoles from "supertokens-node/recipe/userroles"; import { appInfo } from "./config"; import PasswordlessDevelopmentMode from "./recipes/passwordless-development-mode"; import PasswordlessTwilioVerify from "./recipes/passwordless-twilio-verify"; import { logger } from "./"; import type { TypeInput } from "supertokens-node/types"; export const backendConfig = (): TypeInput => { return { framework: "custom", supertokens: { connectionURI: process.env.SUPERTOKENS_URI || "https://try.supertokens.io", apiKey: process.env.SUPERTOKENS_API_KEY || undefined, }, appInfo, recipeList: [ process.env.NODE_ENV === 'production' ? PasswordlessTwilioVerify.init() : PasswordlessDevelopmentMode.init(), Session.init({ cookieSameSite: "lax", cookieSecure: process.env.NODE_ENV === "production", cookieDomain: process.env.COOKIE_DOMAIN || undefined, olderCookieDomain: undefined, antiCsrf: process.env.NODE_ENV === "production" ? "VIA_TOKEN" : "NONE", sessionExpiredStatusCode: 440, invalidClaimStatusCode: 403, override: { functions: (originalImplementation) => ({ ...originalImplementation, refreshSession: async (input) => { logger.info('Backend: Refresh session attempt'); try { const result = await originalImplementation.refreshSession(input); logger.info('Backend: Refresh session successful'); return result; } catch (error) { logger.error('Backend: Refresh session failed:', error); throw error; } }, }), }, // Debug only exposeAccessTokenToFrontendInCookieBasedAuth: process.env.NODE_ENV !== "production", }), Dashboard.init(), UserRoles.init(), ], telemetry: process.env.NODE_ENV !== "production", }; }; let initialized = false; export function ensureSuperTokensBackend() { if (!initialized && typeof window === 'undefined') { SuperTokens.init(backendConfig()); initialized = true; logger.simple("Backend initialized"); } }