Description
Issue: userContext
properties not accessible in Passwordless recipe email delivery override
Description
When passing custom properties in userContext
from the client to the server using the Passwordless recipe, these properties are not directly accessible in the sendEmail
override function.
The TypeScript type signature suggests userContext
should be a simple key-value object, but actual logs show it contains only SuperTokens internal structures without the custom properties we set from the client.
Versions
- supertokens-node: 21.1.0
- supertokens-web-js: 0.14.0
- Node.js: (running in Docker container)
Steps to Reproduce
Client-side configuration and code
// Client initialization in vue/src/services/supertokens.ts
SuperTokens.init({
appInfo: {
appName: window.location.host,
apiDomain: window.location.origin,
apiBasePath: "/node/auth"
},
recipeList: [
Passwordless.init()
]
});
// Client usage in vue/src/composables/useAuth.ts
const sendPasswordlessCode = async (email: string) => {
const response = await createCode({
email,
userContext: { someUserContextProperty: "someValue" }
});
};
Server-side configuration and code
// Server initialization in node/src/services/supertokens.ts
supertokens.init({
framework: "express",
supertokens: {
connectionURI: "http://supertokens:3567"
},
appInfo: {
appName: DOMAIN,
apiDomain: `https://${DOMAIN}`,
websiteDomain: `https://${DOMAIN}`
},
recipeList: [
Passwordless.init({
flowType: "MAGIC_LINK",
contactMethod: "EMAIL",
emailDelivery: {
override: (originalImplementation) => ({
...originalImplementation,
sendEmail: async (input) => {
console.log("input.userContext: ", input.userContext);
return originalImplementation.sendEmail(input);
}
})
}
})
]
});
Expected TypeScript Type
const input: {
type: "PASSWORDLESS_LOGIN";
isFirstFactor: boolean;
email: string;
userInputCode?: string;
urlWithLinkCode?: string;
codeLifetime: number;
preAuthSessionId: string;
tenantId: string;
userContext: UserContext; // Should contain our custom properties
}
Actual server logs
input.userContext: {
_default: {
request: ExpressRequest {
getFormData: [AsyncFunction (anonymous)],
getJSONBody: [AsyncFunction (anonymous)],
getBodyAsJSONOrFormData: [AsyncFunction (anonymous)],
wrapperUsed: true,
parsedJSONBody: [Object],
parsedUrlEncodedFormData: undefined,
getFormDataFromRequestBody: [AsyncFunction (anonymous)],
getJSONFromRequestBody: [AsyncFunction (anonymous)],
getKeyValueFromQuery: [Function (anonymous)],
getMethod: [Function (anonymous)],
getCookieValue: [Function (anonymous)],
getHeaderValue: [Function (anonymous)],
getOriginalURL: [Function (anonymous)],
original: [IncomingMessage],
request: [IncomingMessage]
},
keepCacheAlive: true,
coreCallCache: {},
globalCacheTag: 1746037333884
}
}
Issue Summary
The custom property someUserContextProperty
set on the client-side is completely missing in the server's input.userContext
. Instead, we only see internal SuperTokens structures like _default
with Express request information.
According to the TypeScript type definition, we should be able to directly access input.userContext.someUserContextProperty
, but this value is not being passed through to the server-side override function.