Skip to content

Commit

Permalink
feat(mfa): finish todo list (#782)
Browse files Browse the repository at this point in the history
* feat: updated when we ask for contact info based slack discussion

* fix: make sure change email address shows up at the right time

* docs: update emailverification-with-otp example to use MFA

* test: add test cases that check if redirectToPath is respected in mfa

* fix: small fixes and updates for the updated node impl

* test: update tests to match new behaviour/utils

* docs: reset dependencies to latest
  • Loading branch information
porcellus authored Dec 24, 2023
1 parent 7a0810c commit aaae5c3
Show file tree
Hide file tree
Showing 45 changed files with 399 additions and 1,137 deletions.
74 changes: 13 additions & 61 deletions examples/with-emailverification-with-otp/api-server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import supertokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword";
import EmailVerification from "supertokens-node/recipe/emailverification";
import MultiFactorAuth from "supertokens-node/recipe/multifactorauth";
import Passwordless from "supertokens-node/recipe/passwordless";
import { middleware, errorHandler } from "supertokens-node/framework/express";
import cors from "cors";
import { generateOtpAndMapToToken, mailTransporter, getMessageBody } from "./utils";
import Dashboard from "supertokens-node/recipe/dashboard";

import dotenv from "dotenv";
Expand Down Expand Up @@ -34,69 +35,20 @@ supertokens.init({
recipeList: [
EmailVerification.init({
mode: "REQUIRED",
emailDelivery: {
service: {
sendEmail: async ({ user, emailVerifyLink: url }) => {
// retrieve the token from the url
const token = new URL(url).searchParams.get("token");

if (token !== null) {
// generate a 6 digit otp
let otp = generateOtpAndMapToToken(token, otpToTokenMapping);
console.log(otp, user.email);
try {
/**
* This will not work if you have not set up your email credentials in the .env file. Refer to .env.example
* in this example app to know which environment variables you need to set.
*/
await mailTransporter.sendMail({
from: process.env.NODEMAILER_USER,
to: user.email,
subject: "SuperTokens Demo OTP",
html: getMessageBody(otp, user.email),
});
} catch {
// We ignore this in the example so the example is still usable by getting the otp from the console
}
}
},
},
},
}),
MultiFactorAuth.init({
firstFactors: ["thirdparty", "emailpassword"], // This is basically disallows using passwordless to sign in
override: {
apis: (oI) => {
return {
...oI,
verifyEmailPOST: async (input) => {
if (oI.verifyEmailPOST === undefined) {
throw Error("should not come here");
}

// retrieve the otp from input
let otp = input.token;

// retrieve the token mapped to the otp if it exists
let superTokensToken = otpToTokenMapping.get(otp);
console.log(superTokensToken);
if (superTokensToken !== undefined) {
// if the mapping exists set the token value in the input object to the retrieved token.
input.token = superTokensToken;

// remove the otp and token from the mapping
otpToTokenMapping.delete(otp);
} else {
// If the mapping does not exist return an invalid token error
return {
status: "EMAIL_VERIFICATION_INVALID_TOKEN_ERROR",
};
}

let response = await oI.verifyEmailPOST(input);
return response;
},
};
},
functions: (oI) => ({
...oI,
getMFARequirementsForAuth: async () => ["otp-email"],
}),
},
}),
Passwordless.init({
contactMethod: "EMAIL",
flowType: "USER_INPUT_CODE",
}),
ThirdPartyEmailPassword.init({
providers: [
// We have provided you with development keys which you can use for testing.
Expand Down
Loading

0 comments on commit aaae5c3

Please sign in to comment.