Skip to content

Commit

Permalink
Add changes to support unknown type in formField values
Browse files Browse the repository at this point in the history
  • Loading branch information
deepjyoti30-st committed Sep 25, 2024
1 parent e57cda4 commit b546d49
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ app.get("/sessioninfo", (c) => {

app.get("/", (c) => {
return c.json({
"message": "Hello from Supertokens"
})
})
message: "Hello from Supertokens",
});
});

export default app;
62 changes: 55 additions & 7 deletions lib/build/recipe/emailpassword/api/implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,16 @@ function getAPIImplementation() {
};
},
generatePasswordResetTokenPOST: async function ({ formFields, tenantId, options, userContext }) {
const email = formFields.filter((f) => f.id === "email")[0].value;
// NOTE: Check for email being a non-string value. This check will likely
// never evaluate to `true` as there is an upper-level check for the type
// in validation but kept here to be safe.
const emailAsUnknown = formFields.filter((f) => f.id === "email")[0].value;
if (typeof emailAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "email value needs to be a string",
};
const email = emailAsUnknown;
// this function will be reused in different parts of the flow below..
async function generateAndSendPasswordResetToken(primaryUserId, recipeUserId) {
// the user ID here can be primary or recipe level.
Expand Down Expand Up @@ -355,7 +364,16 @@ function getAPIImplementation() {
};
}
}
let newPassword = formFields.filter((f) => f.id === "password")[0].value;
// NOTE: Check for password being a non-string value. This check will likely
// never evaluate to `true` as there is an upper-level check for the type
// in validation but kept here to be safe.
const newPasswordAsUnknown = formFields.filter((f) => f.id === "password")[0].value;
if (typeof newPasswordAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "password value needs to be a string",
};
let newPassword = newPasswordAsUnknown;
let tokenConsumptionResponse = await options.recipeImplementation.consumePasswordResetToken({
token,
tenantId,
Expand All @@ -371,7 +389,7 @@ function getAPIImplementation() {
// This should happen only cause of a race condition where the user
// might be deleted before token creation and consumption.
// Also note that this being undefined doesn't mean that the email password
// user does not exist, but it means that there is no reicpe or primary user
// user does not exist, but it means that there is no recipe or primary user
// for whom the token was generated.
return {
status: "RESET_PASSWORD_INVALID_TOKEN_ERROR",
Expand Down Expand Up @@ -496,8 +514,23 @@ function getAPIImplementation() {
"Cannot sign in / up due to security reasons. Please contact support. (ERR_CODE_012)",
},
};
let email = formFields.filter((f) => f.id === "email")[0].value;
let password = formFields.filter((f) => f.id === "password")[0].value;
const emailAsUnknown = formFields.filter((f) => f.id === "email")[0].value;
const passwordAsUnknown = formFields.filter((f) => f.id === "password")[0].value;
// NOTE: Following checks will likely never throw an error as the
// check for type is done in a parent function but they are kept
// here to be on the safe side.
if (typeof emailAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "email value needs to be a string",
};
if (typeof passwordAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "password value needs to be a string",
};
let email = emailAsUnknown;
let password = passwordAsUnknown;
const recipeId = "emailpassword";
const checkCredentialsOnTenant = async (tenantId) => {
return (
Expand Down Expand Up @@ -619,8 +652,23 @@ function getAPIImplementation() {
"Cannot sign in / up due to security reasons. Please contact support. (ERR_CODE_016)",
},
};
let email = formFields.filter((f) => f.id === "email")[0].value;
let password = formFields.filter((f) => f.id === "password")[0].value;
const emailAsUnknown = formFields.filter((f) => f.id === "email")[0].value;
const passwordAsUnknown = formFields.filter((f) => f.id === "password")[0].value;
// NOTE: Following checks will likely never throw an error as the
// check for type is done in a parent function but they are kept
// here to be on the safe side.
if (typeof emailAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "email value needs to be a string",
};
if (typeof passwordAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "password value needs to be a string",
};
let email = emailAsUnknown;
let password = passwordAsUnknown;
const preAuthCheckRes = await authUtils_1.AuthUtils.preAuthChecks({
authenticatingAccountInfo: {
recipeId: "emailpassword",
Expand Down
2 changes: 1 addition & 1 deletion lib/build/recipe/emailpassword/api/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export declare function validateFormFieldsOrThrowError(
): Promise<
{
id: string;
value: string;
value: unknown;
}[]
>;
4 changes: 3 additions & 1 deletion lib/build/recipe/emailpassword/api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ async function validateFormFieldsOrThrowError(configFormFields, formFieldsRaw, t
// we trim the email: https://github.com/supertokens/supertokens-core/issues/99
formFields = formFields.map((field) => {
if (field.id === constants_1.FORM_FIELD_EMAIL_ID) {
return Object.assign(Object.assign({}, field), { value: field.value.trim() });
return Object.assign(Object.assign({}, field), {
value: typeof field.value === "string" ? field.value.trim() : field.value,
});
}
return field;
});
Expand Down
8 changes: 4 additions & 4 deletions lib/build/recipe/emailpassword/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export declare type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
options: APIOptions;
Expand All @@ -245,7 +245,7 @@ export declare type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
token: string;
tenantId: string;
Expand All @@ -271,7 +271,7 @@ export declare type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
session: SessionContainerInterface | undefined;
Expand All @@ -297,7 +297,7 @@ export declare type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
session: SessionContainerInterface | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default async function generatePasswordResetToken(
// step 1
let formFields: {
id: string;
value: string;
value: unknown;
}[] = await validateFormFieldsOrThrowError(
options.config.resetPasswordUsingTokenFeature.formFieldsForGenerateTokenForm,
requestBody.formFields,
Expand Down
74 changes: 64 additions & 10 deletions lib/ts/recipe/emailpassword/api/implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,16 @@ export default function getAPIImplementation(): APIInterface {
| { status: "PASSWORD_RESET_NOT_ALLOWED"; reason: string }
| GeneralErrorResponse
> {
const email = formFields.filter((f) => f.id === "email")[0].value;
// NOTE: Check for email being a non-string value. This check will likely
// never evaluate to `true` as there is an upper-level check for the type
// in validation but kept here to be safe.
const emailAsUnknown = formFields.filter((f) => f.id === "email")[0].value;
if (typeof emailAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "email value needs to be a string",
};
const email: string = emailAsUnknown;

// this function will be reused in different parts of the flow below..
async function generateAndSendPasswordResetToken(
Expand Down Expand Up @@ -322,7 +331,7 @@ export default function getAPIImplementation(): APIInterface {
}: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
token: string;
tenantId: string;
Expand Down Expand Up @@ -451,7 +460,16 @@ export default function getAPIImplementation(): APIInterface {
}
}

let newPassword = formFields.filter((f) => f.id === "password")[0].value;
// NOTE: Check for password being a non-string value. This check will likely
// never evaluate to `true` as there is an upper-level check for the type
// in validation but kept here to be safe.
const newPasswordAsUnknown = formFields.filter((f) => f.id === "password")[0].value;
if (typeof newPasswordAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "password value needs to be a string",
};
let newPassword: string = newPasswordAsUnknown;

let tokenConsumptionResponse = await options.recipeImplementation.consumePasswordResetToken({
token,
Expand All @@ -472,7 +490,7 @@ export default function getAPIImplementation(): APIInterface {
// This should happen only cause of a race condition where the user
// might be deleted before token creation and consumption.
// Also note that this being undefined doesn't mean that the email password
// user does not exist, but it means that there is no reicpe or primary user
// user does not exist, but it means that there is no recipe or primary user
// for whom the token was generated.
return {
status: "RESET_PASSWORD_INVALID_TOKEN_ERROR",
Expand Down Expand Up @@ -596,7 +614,7 @@ export default function getAPIImplementation(): APIInterface {
}: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
session?: SessionContainerInterface;
Expand Down Expand Up @@ -631,8 +649,26 @@ export default function getAPIImplementation(): APIInterface {
"Cannot sign in / up due to security reasons. Please contact support. (ERR_CODE_012)",
},
};
let email = formFields.filter((f) => f.id === "email")[0].value;
let password = formFields.filter((f) => f.id === "password")[0].value;
const emailAsUnknown = formFields.filter((f) => f.id === "email")[0].value;
const passwordAsUnknown = formFields.filter((f) => f.id === "password")[0].value;

// NOTE: Following checks will likely never throw an error as the
// check for type is done in a parent function but they are kept
// here to be on the safe side.
if (typeof emailAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "email value needs to be a string",
};

if (typeof passwordAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "password value needs to be a string",
};

let email: string = emailAsUnknown;
let password: string = passwordAsUnknown;

const recipeId = "emailpassword";

Expand Down Expand Up @@ -745,7 +781,7 @@ export default function getAPIImplementation(): APIInterface {
}: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
session?: SessionContainerInterface;
Expand Down Expand Up @@ -780,8 +816,26 @@ export default function getAPIImplementation(): APIInterface {
"Cannot sign in / up due to security reasons. Please contact support. (ERR_CODE_016)",
},
};
let email = formFields.filter((f) => f.id === "email")[0].value;
let password = formFields.filter((f) => f.id === "password")[0].value;
const emailAsUnknown = formFields.filter((f) => f.id === "email")[0].value;
const passwordAsUnknown = formFields.filter((f) => f.id === "password")[0].value;

// NOTE: Following checks will likely never throw an error as the
// check for type is done in a parent function but they are kept
// here to be on the safe side.
if (typeof emailAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "email value needs to be a string",
};

if (typeof passwordAsUnknown !== "string")
return {
status: "GENERAL_ERROR",
message: "password value needs to be a string",
};

let email: string = emailAsUnknown;
let password: string = passwordAsUnknown;

const preAuthCheckRes = await AuthUtils.preAuthChecks({
authenticatingAccountInfo: {
Expand Down
2 changes: 1 addition & 1 deletion lib/ts/recipe/emailpassword/api/passwordReset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default async function passwordReset(
// a password that meets the password policy.
let formFields: {
id: string;
value: string;
value: unknown;
}[] = await validateFormFieldsOrThrowError(
options.config.resetPasswordUsingTokenFeature.formFieldsForPasswordResetForm,
requestBody.formFields,
Expand Down
2 changes: 1 addition & 1 deletion lib/ts/recipe/emailpassword/api/signin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default async function signInAPI(
// step 1
let formFields: {
id: string;
value: string;
value: unknown;
}[] = await validateFormFieldsOrThrowError(
options.config.signInFeature.formFields,
(await options.req.getJSONBody()).formFields,
Expand Down
2 changes: 1 addition & 1 deletion lib/ts/recipe/emailpassword/api/signup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default async function signUpAPI(
// step 1
let formFields: {
id: string;
value: string;
value: unknown;
}[] = await validateFormFieldsOrThrowError(
options.config.signUpFeature.formFields,
requestBody.formFields,
Expand Down
6 changes: 3 additions & 3 deletions lib/ts/recipe/emailpassword/api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function validateFormFieldsOrThrowError(
): Promise<
{
id: string;
value: string;
value: unknown;
}[]
> {
// first we check syntax ----------------------------
Expand All @@ -39,7 +39,7 @@ export async function validateFormFieldsOrThrowError(

let formFields: {
id: string;
value: string;
value: unknown;
}[] = [];

for (let i = 0; i < formFieldsRaw.length; i++) {
Expand All @@ -63,7 +63,7 @@ export async function validateFormFieldsOrThrowError(
if (field.id === FORM_FIELD_EMAIL_ID) {
return {
...field,
value: field.value.trim(),
value: typeof field.value === "string" ? field.value.trim() : field.value,
};
}
return field;
Expand Down
8 changes: 4 additions & 4 deletions lib/ts/recipe/emailpassword/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ export type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
options: APIOptions;
Expand All @@ -249,7 +249,7 @@ export type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
token: string;
tenantId: string;
Expand All @@ -273,7 +273,7 @@ export type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
session: SessionContainerInterface | undefined;
Expand All @@ -300,7 +300,7 @@ export type APIInterface = {
| ((input: {
formFields: {
id: string;
value: string;
value: unknown;
}[];
tenantId: string;
session: SessionContainerInterface | undefined;
Expand Down
Loading

0 comments on commit b546d49

Please sign in to comment.