diff --git a/examples/for-tests/src/App.js b/examples/for-tests/src/App.js
index 58b8b2df1..9238f7013 100644
--- a/examples/for-tests/src/App.js
+++ b/examples/for-tests/src/App.js
@@ -173,7 +173,7 @@ const testContext = getTestContext();
let recipeList = [
MultiFactorAuth.init({
- firstFactors: ["otp-phone", "otp-email", "thirdparty"],
+ firstFactors: testContext.firstFactors,
}),
Multitenancy.init({
override: {
@@ -484,6 +484,10 @@ export function DashboardHelper({ redirectOnLogout, ...props } = {}) {
session context userID: {sessionContext.userId}
{JSON.stringify(sessionContext.invalidClaims, undefined, 2)}
+ MultiFactorAuth.redirectToFactorChooser(true, props.history)}>MFA chooser
+ MultiFactorAuth.redirectToFactor("totp", true, props.history)}>TOTP
+ MultiFactorAuth.redirectToFactor("otp-email", true, props.history)}>OTP-Email
+ MultiFactorAuth.redirectToFactor("otp-phone", true, props.history)}>OTP-Phone
);
}
diff --git a/examples/for-tests/src/testContext.js b/examples/for-tests/src/testContext.js
index ab1e6e3c5..21c43c304 100644
--- a/examples/for-tests/src/testContext.js
+++ b/examples/for-tests/src/testContext.js
@@ -14,6 +14,7 @@ export function getTestContext() {
staticProviderList: localStorage.getItem("staticProviderList"),
mockTenantId: localStorage.getItem("mockTenantId"),
clientType: localStorage.getItem("clientType") || undefined,
+ firstFactors: localStorage.getItem("firstFactors")?.split(", "),
};
return ret;
}
diff --git a/lib/build/authRecipe-shared2.js b/lib/build/authRecipe-shared2.js
index e03259ffa..25c539965 100644
--- a/lib/build/authRecipe-shared2.js
+++ b/lib/build/authRecipe-shared2.js
@@ -4,7 +4,7 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext
var jsxRuntime = require("react/jsx-runtime");
var React = require("react");
var uiEntry = require("./index2.js");
-var session = require("./session-shared3.js");
+var session = require("./session-shared.js");
var recipe = require("./session-shared2.js");
/**
diff --git a/lib/build/emailpasswordprebuiltui.js b/lib/build/emailpasswordprebuiltui.js
index d973d6318..58e98cf2d 100644
--- a/lib/build/emailpasswordprebuiltui.js
+++ b/lib/build/emailpasswordprebuiltui.js
@@ -26,8 +26,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("./session-shared2.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared3.js");
require("./session-shared.js");
+require("./session-shared3.js");
require("./translations.js");
require("./emailverification-shared2.js");
require("./emailpassword-shared7.js");
diff --git a/lib/build/emailverificationprebuiltui.js b/lib/build/emailverificationprebuiltui.js
index c35b9f47a..c5be31f23 100644
--- a/lib/build/emailverificationprebuiltui.js
+++ b/lib/build/emailverificationprebuiltui.js
@@ -4,7 +4,7 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext
var jsxRuntime = require("react/jsx-runtime");
var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath");
var uiEntry = require("./index2.js");
-var session = require("./session-shared3.js");
+var session = require("./session-shared.js");
var recipe$1 = require("./emailverification-shared.js");
var React = require("react");
var recipe = require("./session-shared2.js");
@@ -29,7 +29,7 @@ require("supertokens-web-js/recipe/multifactorauth");
require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared.js");
+require("./session-shared3.js");
require("supertokens-web-js/recipe/emailverification");
function _interopDefault(e) {
diff --git a/lib/build/index2.js b/lib/build/index2.js
index 8a6c1eddd..b916ff404 100644
--- a/lib/build/index2.js
+++ b/lib/build/index2.js
@@ -388,6 +388,7 @@ var DynamicLoginMethodsSpinner = function () {
};
// The related ADR: https://supertokens.com/docs/contribute/decisions/multitenancy/0006
+// TODO: This could be by the recipes registering what factors they provide (at least partially)
var priorityOrder = [
{
rid: "thirdpartyemailpassword",
@@ -437,7 +438,7 @@ function chooseComponentBasedOnFirstFactors(firstFactors, routeComponents) {
var providedByCurrent = factorsProvided.filter(function (id) {
return firstFactors.includes(id);
}).length;
- if (providedByCurrent >= maxProvided) {
+ if (providedByCurrent > maxProvided) {
var matchingComp = routeComponents.find(function (comp) {
return comp.recipeID === rid;
});
@@ -448,12 +449,15 @@ function chooseComponentBasedOnFirstFactors(firstFactors, routeComponents) {
}
};
// We find the component that provides the most factors
- for (var _b = 0, _c = priorityOrder.reverse(); _b < _c.length; _b++) {
- var _d = _c[_b],
- rid = _d.rid,
- factorsProvided = _d.factorsProvided;
+ for (var _b = 0, priorityOrder_2 = priorityOrder; _b < priorityOrder_2.length; _b++) {
+ var _c = priorityOrder_2[_b],
+ rid = _c.rid,
+ factorsProvided = _c.factorsProvided;
_loop_2(rid, factorsProvided);
}
+ if (component === undefined) {
+ throw new Error("No enabled recipes overlap with the requested firstFactors: " + firstFactors);
+ }
return component;
}
var RecipeRouter = /** @class */ (function () {
@@ -578,8 +582,8 @@ var RecipeRouter = /** @class */ (function () {
}
};
// We first try to find an exact match
- for (var _i = 0, priorityOrder_2 = priorityOrder; _i < priorityOrder_2.length; _i++) {
- var _b = priorityOrder_2[_i],
+ for (var _i = 0, priorityOrder_3 = priorityOrder; _i < priorityOrder_3.length; _i++) {
+ var _b = priorityOrder_3[_i],
rid = _b.rid,
includes = _b.includes;
var state_2 = _loop_3(rid, includes);
@@ -600,8 +604,8 @@ var RecipeRouter = /** @class */ (function () {
}
};
// We try to find a partial match
- for (var _c = 0, priorityOrder_3 = priorityOrder; _c < priorityOrder_3.length; _c++) {
- var _d = priorityOrder_3[_c],
+ for (var _c = 0, priorityOrder_4 = priorityOrder; _c < priorityOrder_4.length; _c++) {
+ var _d = priorityOrder_4[_c],
rid = _d.rid,
includes = _d.includes;
var state_3 = _loop_4(rid, includes);
diff --git a/lib/build/multifactorauth-shared.js b/lib/build/multifactorauth-shared.js
index 825426998..4058003e0 100644
--- a/lib/build/multifactorauth-shared.js
+++ b/lib/build/multifactorauth-shared.js
@@ -2,6 +2,7 @@
var genericComponentOverrideContext = require("./genericComponentOverrideContext.js");
var MultiFactorAuthWebJS = require("supertokens-web-js/recipe/multifactorauth");
+var utils = require("supertokens-web-js/utils");
var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath");
var postSuperTokensInitCallbacks = require("supertokens-web-js/utils/postSuperTokensInitCallbacks");
var sessionClaimValidatorStore = require("supertokens-web-js/utils/sessionClaimValidatorStore");
@@ -199,7 +200,7 @@ var MultiFactorAuth = /** @class */ (function (_super) {
var _this = _super.call(this, config) || this;
_this.webJSRecipe = webJSRecipe;
_this.recipeID = MultiFactorAuth.RECIPE_ID;
- _this.firstFactors = [];
+ _this.firstFactors = new Set();
_this.secondaryFactors = [];
_this.getDefaultRedirectionURL = function (context) {
return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () {
@@ -209,19 +210,21 @@ var MultiFactorAuth = /** @class */ (function (_super) {
chooserPath = new NormalisedURLPath__default.default(DEFAULT_FACTOR_CHOOSER_PATH);
return [
2 /*return*/,
- "".concat(
- this.config.appInfo.websiteBasePath.appendPath(chooserPath).getAsStringDangerous()
- ),
+ this.config.appInfo.websiteBasePath.appendPath(chooserPath).getAsStringDangerous(),
];
} else if (context.action === "GO_TO_FACTOR") {
redirectInfo = this.getSecondaryFactors().find(function (f) {
return f.id === context.factorId;
});
if (redirectInfo !== undefined) {
- return [2 /*return*/, redirectInfo.path];
+ return [
+ 2 /*return*/,
+ this.config.appInfo.websiteBasePath
+ .appendPath(redirectInfo.path)
+ .getAsStringDangerous(),
+ ];
}
- // TODO: access denied screen if not defined?
- return [2 /*return*/, "/"];
+ throw new Error("Requested redirect to unknown factor id");
} else {
return [2 /*return*/, "/"];
}
@@ -280,45 +283,96 @@ var MultiFactorAuth = /** @class */ (function (_super) {
}
return MultiFactorAuth.instance;
};
- MultiFactorAuth.prototype.getDefaultFirstFactors = function () {
- return this.firstFactors;
- };
MultiFactorAuth.prototype.addMFAFactors = function (firstFactors, secondaryFactors) {
- var _b, _c;
- (_b = this.firstFactors).push.apply(_b, firstFactors);
- (_c = this.secondaryFactors).push.apply(_c, secondaryFactors);
+ for (var _i = 0, firstFactors_1 = firstFactors; _i < firstFactors_1.length; _i++) {
+ var fact = firstFactors_1[_i];
+ this.firstFactors.add(fact);
+ }
+ this.secondaryFactors = genericComponentOverrideContext.__spreadArray(
+ genericComponentOverrideContext.__spreadArray(
+ [],
+ this.secondaryFactors.filter(function (factor) {
+ return secondaryFactors.every(function (newFactor) {
+ return factor.id !== newFactor.id;
+ });
+ }),
+ true
+ ),
+ secondaryFactors,
+ true
+ );
};
MultiFactorAuth.prototype.getFirstFactors = function () {
var _b;
- return (_b = this.config.firstFactors) !== null && _b !== void 0 ? _b : this.firstFactors;
+ return (_b = this.config.firstFactors) !== null && _b !== void 0 ? _b : Array.from(this.firstFactors);
};
MultiFactorAuth.prototype.getSecondaryFactors = function () {
return this.config.getFactorInfo(this.secondaryFactors);
};
- MultiFactorAuth.prototype.redirectToFactor = function (factorId, history) {
+ MultiFactorAuth.prototype.redirectToFactor = function (factorId, redirectBack, history) {
+ if (redirectBack === void 0) {
+ redirectBack = false;
+ }
return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- var _b, _c;
- return genericComponentOverrideContext.__generator(this, function (_d) {
- switch (_d.label) {
+ var url, redirectUrl, redirectUrl;
+ return genericComponentOverrideContext.__generator(this, function (_b) {
+ switch (_b.label) {
case 0:
- _c = (_b = genericComponentOverrideContext.SuperTokens.getInstanceOrThrow()).redirectToUrl;
return [4 /*yield*/, this.getRedirectUrl({ action: "GO_TO_FACTOR", factorId: factorId })];
case 1:
- return [2 /*return*/, _c.apply(_b, [_d.sent(), history])];
+ url = _b.sent();
+ if (redirectBack) {
+ redirectUrl = genericComponentOverrideContext
+ .getCurrentNormalisedUrlPath()
+ .getAsStringDangerous();
+ url = utils.appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ } else {
+ redirectUrl = genericComponentOverrideContext.getRedirectToPathFromURL();
+ if (redirectUrl) {
+ url = utils.appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ }
+ }
+ return [
+ 2 /*return*/,
+ genericComponentOverrideContext.SuperTokens.getInstanceOrThrow().redirectToUrl(
+ url,
+ history
+ ),
+ ];
}
});
});
};
- MultiFactorAuth.prototype.redirectToFactorChooser = function (history) {
+ MultiFactorAuth.prototype.redirectToFactorChooser = function (redirectBack, history) {
+ if (redirectBack === void 0) {
+ redirectBack = false;
+ }
return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- var _b, _c;
- return genericComponentOverrideContext.__generator(this, function (_d) {
- switch (_d.label) {
+ var url, redirectUrl, redirectUrl;
+ return genericComponentOverrideContext.__generator(this, function (_b) {
+ switch (_b.label) {
case 0:
- _c = (_b = genericComponentOverrideContext.SuperTokens.getInstanceOrThrow()).redirectToUrl;
return [4 /*yield*/, this.getRedirectUrl({ action: "FACTOR_CHOOSER" })];
case 1:
- return [2 /*return*/, _c.apply(_b, [_d.sent(), history])];
+ url = _b.sent();
+ if (redirectBack) {
+ redirectUrl = genericComponentOverrideContext
+ .getCurrentNormalisedUrlPath()
+ .getAsStringDangerous();
+ url = utils.appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ } else {
+ redirectUrl = genericComponentOverrideContext.getRedirectToPathFromURL();
+ if (redirectUrl) {
+ url = utils.appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ }
+ }
+ return [
+ 2 /*return*/,
+ genericComponentOverrideContext.SuperTokens.getInstanceOrThrow().redirectToUrl(
+ url,
+ history
+ ),
+ ];
}
});
});
diff --git a/lib/build/multifactorauth-shared2.js b/lib/build/multifactorauth-shared2.js
index 1f8eafe1c..26dfa980a 100644
--- a/lib/build/multifactorauth-shared2.js
+++ b/lib/build/multifactorauth-shared2.js
@@ -35,12 +35,26 @@ var Wrapper = /** @class */ (function () {
})
);
};
+ Wrapper.redirectToFactor = function (factorId, redirectBack, history) {
+ if (redirectBack === void 0) {
+ redirectBack = true;
+ }
+ return recipe.MultiFactorAuth.getInstanceOrThrow().redirectToFactor(factorId, redirectBack, history);
+ };
+ Wrapper.redirectToFactorChooser = function (redirectBack, history) {
+ if (redirectBack === void 0) {
+ redirectBack = true;
+ }
+ return recipe.MultiFactorAuth.getInstanceOrThrow().redirectToFactorChooser(redirectBack, history);
+ };
Wrapper.MultiFactorAuthClaim = recipe.MultiFactorAuth.MultiFactorAuthClaim;
Wrapper.ComponentsOverrideProvider = Provider;
return Wrapper;
})();
var init = Wrapper.init;
var getMFAInfo = Wrapper.getMFAInfo;
+var redirectToFactor = Wrapper.redirectToFactor;
+var redirectToFactorChooser = Wrapper.redirectToFactorChooser;
var MultiFactorAuthComponentsOverrideProvider = Wrapper.ComponentsOverrideProvider;
var MultiFactorAuthClaim = recipe.MultiFactorAuth.MultiFactorAuthClaim;
@@ -49,4 +63,6 @@ exports.MultiFactorAuthComponentsOverrideProvider = MultiFactorAuthComponentsOve
exports.Wrapper = Wrapper;
exports.getMFAInfo = getMFAInfo;
exports.init = init;
+exports.redirectToFactor = redirectToFactor;
+exports.redirectToFactorChooser = redirectToFactorChooser;
exports.useContext = useContext;
diff --git a/lib/build/multifactorauth.js b/lib/build/multifactorauth.js
index 20275f881..222349531 100644
--- a/lib/build/multifactorauth.js
+++ b/lib/build/multifactorauth.js
@@ -24,3 +24,5 @@ exports.MultiFactorAuthComponentsOverrideProvider = multifactorauth.MultiFactorA
exports.default = multifactorauth.Wrapper;
exports.getMFAInfo = multifactorauth.getMFAInfo;
exports.init = multifactorauth.init;
+exports.redirectToFactor = multifactorauth.redirectToFactor;
+exports.redirectToFactorChooser = multifactorauth.redirectToFactorChooser;
diff --git a/lib/build/multifactorauthprebuiltui.js b/lib/build/multifactorauthprebuiltui.js
index 161168736..cf8cce440 100644
--- a/lib/build/multifactorauthprebuiltui.js
+++ b/lib/build/multifactorauthprebuiltui.js
@@ -4,7 +4,7 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext
var jsxRuntime = require("react/jsx-runtime");
var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath");
var uiEntry = require("./index2.js");
-var session = require("./session-shared3.js");
+var session = require("./session-shared.js");
var multifactorauth = require("./multifactorauth-shared2.js");
var React = require("react");
var windowHandler = require("supertokens-web-js/utils/windowHandler");
@@ -12,8 +12,9 @@ var recipe$1 = require("./session-shared2.js");
var recipe = require("./multifactorauth-shared.js");
var SuperTokensBranding = require("./SuperTokensBranding.js");
var translations = require("./translations.js");
-var arrowLeftIcon = require("./arrowLeftIcon.js");
var translationContext = require("./translationContext.js");
+var sessionprebuiltui = require("./sessionprebuiltui.js");
+var arrowLeftIcon = require("./arrowLeftIcon.js");
var backButton = require("./emailpassword-shared7.js");
require("supertokens-web-js");
require("supertokens-web-js/utils/cookieHandler");
@@ -24,7 +25,7 @@ require("supertokens-web-js/utils/normalisedURLDomain");
require("react-dom");
require("./multitenancy-shared.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared.js");
+require("./session-shared3.js");
require("./recipeModule-shared.js");
require("supertokens-web-js/recipe/multifactorauth");
require("supertokens-web-js/utils/sessionClaimValidatorStore");
@@ -224,6 +225,13 @@ var FactorList = uiEntry.withOverride("MultiFactorAuthFactorList", function Mult
});
function FactorChooserTheme(props) {
+ var t = translationContext.useTranslation();
+ if (props.availableFactors.length === 0) {
+ return jsxRuntime.jsx(sessionprebuiltui.AccessDeniedScreen, {
+ useShadowDom: props.config.useShadowDom,
+ error: props.showBackButton ? t("MFA_NO_AVAILABLE_OPTIONS") : t("MFA_NO_AVAILABLE_OPTIONS_LOGIN"),
+ });
+ }
return jsxRuntime.jsxs(
"div",
genericComponentOverrideContext.__assign(
@@ -239,7 +247,7 @@ function FactorChooserTheme(props) {
mfaInfo: props.mfaInfo,
navigateToFactor: props.navigateToFactor,
}),
- jsxRuntime.jsx(FactorChooserFooter, { logout: props.logout }),
+ jsxRuntime.jsx(FactorChooserFooter, { logout: props.onLogoutClicked }),
jsxRuntime.jsx(SuperTokensBranding.SuperTokensBranding, {}),
],
}
@@ -276,7 +284,13 @@ function FactorChooserThemeWrapper(props) {
var defaultTranslationsMultiFactorAuth = {
en: genericComponentOverrideContext.__assign(
genericComponentOverrideContext.__assign({}, translations.defaultTranslationsCommon.en),
- { MULTI_FACTOR_CHOOSER_HEADER_TITLE: "Please select a second factor", MULTI_FACTOR_AUTH_LOGOUT: "Logout" }
+ {
+ MULTI_FACTOR_CHOOSER_HEADER_TITLE: "Please select a second factor",
+ MULTI_FACTOR_AUTH_LOGOUT: "Logout",
+ MFA_NO_AVAILABLE_OPTIONS: "You have no available secondary factors.",
+ MFA_NO_AVAILABLE_OPTIONS_LOGIN:
+ "You have no available secondary factors and cannot complete the sign-in process. Please contact support.",
+ }
),
};
@@ -339,11 +353,14 @@ var FactorChooser$1 = function (props) {
var id = _a.id;
return mfaClaimValue.value.n.length === 0 || mfaClaimValue.value.n.includes(id);
});
- if (availableFactors.length === 1) {
+ // If we got here when the next array is not empty, that means that the user redirected here intentionally
+ // In this case we do not want to automatically redirect away but show the chooser screen.
+ if (mfaClaimValue.value.n.length !== 0 && availableFactors.length === 1) {
return [
2 /*return*/,
recipe.MultiFactorAuth.getInstanceOrThrow().redirectToFactor(
availableFactors[0].id,
+ false,
props.history
),
];
@@ -452,7 +469,7 @@ var FactorChooser$1 = function (props) {
showBackButton: ((_a = mfaClaimValue.value) === null || _a === void 0 ? void 0 : _a.n.length) === 0,
mfaInfo: mfaInfo,
availableFactors: availableFactors,
- logout: signOut,
+ onLogoutClicked: signOut,
navigateToFactor: navigateToFactor,
};
return jsxRuntime.jsx(
diff --git a/lib/build/passwordless-shared2.js b/lib/build/passwordless-shared2.js
index d85b31118..65ce53dd3 100644
--- a/lib/build/passwordless-shared2.js
+++ b/lib/build/passwordless-shared2.js
@@ -2,6 +2,7 @@
var genericComponentOverrideContext = require("./genericComponentOverrideContext.js");
var PasswordlessWebJS = require("supertokens-web-js/recipe/passwordless");
+var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath");
var postSuperTokensInitCallbacks = require("supertokens-web-js/utils/postSuperTokensInitCallbacks");
var jsxRuntime = require("react/jsx-runtime");
var utils = require("./authRecipe-shared.js");
@@ -13,6 +14,7 @@ function _interopDefault(e) {
}
var PasswordlessWebJS__default = /*#__PURE__*/ _interopDefault(PasswordlessWebJS);
+var NormalisedURLPath__default = /*#__PURE__*/ _interopDefault(NormalisedURLPath);
var OTPIcon = function () {
return jsxRuntime.jsxs(
@@ -557,31 +559,16 @@ var Passwordless = /** @class */ (function (_super) {
id: "otp-phone",
name: "SMS based OTP",
description: "Get an OTP code on your phone to complete the authentication request",
- path: "/auth/mfa/otp-phone",
+ path: new NormalisedURLPath__default.default("/check-auth/otp-phone"),
logo: OTPIcon,
},
- // {
- // id: "link-phone",
- // name: "SMS based Magic link",
- // description: "Get a magic link on your phone to complete the authentication request",
- // path: "/auth/mfa/link-phone",
- // logo: LinkIcon,
- // },
{
id: "otp-email",
name: "Email based OTP",
description: "Get an OTP code on your email address to complete the authentication request",
- path: "/auth/mfa/otp-email",
+ path: new NormalisedURLPath__default.default("/check-auth/otp-email"),
logo: OTPIcon,
},
- // {
- // id: "link-email",
- // name: "SMS based Magic link",
- // description:
- // "Get a magic link on your email address to complete the authentication request",
- // path: "/auth/mfa/link-email",
- // logo: LinkIcon,
- // },
]
);
}
diff --git a/lib/build/passwordless-shared3.js b/lib/build/passwordless-shared3.js
index 4ec0dabed..5b574b913 100644
--- a/lib/build/passwordless-shared3.js
+++ b/lib/build/passwordless-shared3.js
@@ -5,7 +5,7 @@ var jsxRuntime = require("react/jsx-runtime");
var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath");
var uiEntry = require("./index2.js");
var authWidgetWrapper = require("./authRecipe-shared2.js");
-var session = require("./session-shared3.js");
+var session = require("./session-shared.js");
var componentOverrideContext = require("./passwordless-shared.js");
var React = require("react");
var STGeneralError = require("supertokens-web-js/utils/error");
diff --git a/lib/build/passwordlessprebuiltui.js b/lib/build/passwordlessprebuiltui.js
index 52bf1ab3a..86d6b0a67 100644
--- a/lib/build/passwordlessprebuiltui.js
+++ b/lib/build/passwordlessprebuiltui.js
@@ -5,7 +5,7 @@ require("react/jsx-runtime");
require("supertokens-web-js/utils/normalisedURLPath");
require("./index2.js");
require("./authRecipe-shared2.js");
-require("./session-shared3.js");
+require("./session-shared.js");
require("./passwordless-shared.js");
var passwordlessprebuiltui = require("./passwordless-shared3.js");
require("./passwordless-shared2.js");
@@ -26,7 +26,7 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("./session-shared2.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared.js");
+require("./session-shared3.js");
require("supertokens-web-js/utils/error");
require("./translations.js");
require("./emailpassword-shared2.js");
diff --git a/lib/build/recipe/multifactorauth/components/themes/translations.d.ts b/lib/build/recipe/multifactorauth/components/themes/translations.d.ts
index 93a4eab89..0979f7608 100644
--- a/lib/build/recipe/multifactorauth/components/themes/translations.d.ts
+++ b/lib/build/recipe/multifactorauth/components/themes/translations.d.ts
@@ -2,6 +2,8 @@ export declare const defaultTranslationsMultiFactorAuth: {
en: {
MULTI_FACTOR_CHOOSER_HEADER_TITLE: string;
MULTI_FACTOR_AUTH_LOGOUT: string;
+ MFA_NO_AVAILABLE_OPTIONS: string;
+ MFA_NO_AVAILABLE_OPTIONS_LOGIN: string;
BRANDING_POWERED_BY_START: string;
BRANDING_POWERED_BY_END: string;
SOMETHING_WENT_WRONG_ERROR: string;
diff --git a/lib/build/recipe/multifactorauth/index.d.ts b/lib/build/recipe/multifactorauth/index.d.ts
index 3b28cd3c9..02c7496be 100644
--- a/lib/build/recipe/multifactorauth/index.d.ts
+++ b/lib/build/recipe/multifactorauth/index.d.ts
@@ -19,6 +19,8 @@ export default class Wrapper {
factors: MFAFactorInfo;
fetchResponse: Response;
}>;
+ static redirectToFactor(factorId: string, redirectBack?: boolean, history?: any): Promise;
+ static redirectToFactorChooser(redirectBack?: boolean, history?: any): Promise;
static ComponentsOverrideProvider: import("react").FC<
import("react").PropsWithChildren<{
components: import("./types").ComponentOverrideMap;
@@ -27,6 +29,8 @@ export default class Wrapper {
}
declare const init: typeof Wrapper.init;
declare const getMFAInfo: typeof Wrapper.getMFAInfo;
+declare const redirectToFactor: typeof Wrapper.redirectToFactor;
+declare const redirectToFactorChooser: typeof Wrapper.redirectToFactorChooser;
declare const MultiFactorAuthComponentsOverrideProvider: import("react").FC<
import("react").PropsWithChildren<{
components: import("./types").ComponentOverrideMap;
@@ -36,6 +40,8 @@ declare const MultiFactorAuthClaim: import("./multiFactorAuthClaim").MultiFactor
export {
init,
getMFAInfo,
+ redirectToFactor,
+ redirectToFactorChooser,
MultiFactorAuthComponentsOverrideProvider,
GetRedirectionURLContext,
PreAPIHookContext as PreAPIHookContext,
diff --git a/lib/build/recipe/multifactorauth/recipe.d.ts b/lib/build/recipe/multifactorauth/recipe.d.ts
index e25e74e95..bc4f9cc8e 100644
--- a/lib/build/recipe/multifactorauth/recipe.d.ts
+++ b/lib/build/recipe/multifactorauth/recipe.d.ts
@@ -22,7 +22,7 @@ export default class MultiFactorAuth extends RecipeModule<
static MultiFactorAuthClaim: MultiFactorAuthClaimClass;
recipeID: string;
private readonly firstFactors;
- private readonly secondaryFactors;
+ private secondaryFactors;
constructor(
config: NormalisedConfigWithAppInfoAndRecipeID,
webJSRecipe?: WebJSRecipeInterface
@@ -33,10 +33,9 @@ export default class MultiFactorAuth extends RecipeModule<
static getInstance(): MultiFactorAuth | undefined;
static getInstanceOrThrow(): MultiFactorAuth;
getDefaultRedirectionURL: (context: GetRedirectionURLContext) => Promise;
- getDefaultFirstFactors(): string[];
addMFAFactors(firstFactors: string[], secondaryFactors: SecondaryFactorRedirectionInfo[]): void;
getFirstFactors(): string[];
getSecondaryFactors(): SecondaryFactorRedirectionInfo[];
- redirectToFactor(factorId: string, history?: any): Promise;
- redirectToFactorChooser(history?: any): Promise;
+ redirectToFactor(factorId: string, redirectBack?: boolean, history?: any): Promise;
+ redirectToFactorChooser(redirectBack?: boolean, history?: any): Promise;
}
diff --git a/lib/build/recipe/multifactorauth/types.d.ts b/lib/build/recipe/multifactorauth/types.d.ts
index 9f9b9b027..93d7086d8 100644
--- a/lib/build/recipe/multifactorauth/types.d.ts
+++ b/lib/build/recipe/multifactorauth/types.d.ts
@@ -7,6 +7,7 @@ import type {
} from "../recipeModule/types";
import type { FC } from "react";
import type { OverrideableBuilder } from "supertokens-js-override";
+import type NormalisedURLPath from "supertokens-web-js/lib/build/normalisedURLPath";
import type { RecipeInterface } from "supertokens-web-js/recipe/multifactorauth";
import type { MFAFactorInfo } from "supertokens-web-js/recipe/multifactorauth/types";
export declare type ComponentOverrideMap = {
@@ -63,7 +64,7 @@ export declare type FactorChooserThemeProps = {
showBackButton: boolean;
onBackButtonClicked: () => void;
navigateToFactor: (factorId: string) => void;
- logout: () => void;
+ onLogoutClicked: () => void;
config: NormalisedConfig;
userContext?: any;
};
@@ -72,5 +73,5 @@ export declare type SecondaryFactorRedirectionInfo = {
name: string;
description: string;
logo: FC;
- path: string;
+ path: NormalisedURLPath;
};
diff --git a/lib/build/recipe/session/components/features/accessDeniedScreen/index.d.ts b/lib/build/recipe/session/components/features/accessDeniedScreen/index.d.ts
index 8e9166177..98add6532 100644
--- a/lib/build/recipe/session/components/features/accessDeniedScreen/index.d.ts
+++ b/lib/build/recipe/session/components/features/accessDeniedScreen/index.d.ts
@@ -6,6 +6,8 @@ declare const AccessDeniedScreen: React.FC<
FeatureBaseProps & {
recipe: Recipe;
useComponentOverrides: () => ComponentOverrideMap;
+ useShadowDom?: boolean;
+ error?: string;
}
>;
export default AccessDeniedScreen;
diff --git a/lib/build/recipe/session/prebuiltui.d.ts b/lib/build/recipe/session/prebuiltui.d.ts
index 01aacb148..cc68f20d5 100644
--- a/lib/build/recipe/session/prebuiltui.d.ts
+++ b/lib/build/recipe/session/prebuiltui.d.ts
@@ -13,7 +13,7 @@ export declare class SessionPreBuiltUI extends RecipeRouter {
static getFeatureComponent(
componentName: "accessDenied",
props: FeatureBaseProps & {
- redirectOnSessionExists?: boolean;
+ error?: string;
userContext?: any;
},
useComponentOverrides?: () => GenericComponentOverrideMap
@@ -22,6 +22,8 @@ export declare class SessionPreBuiltUI extends RecipeRouter {
getFeatureComponent: (
componentName: "accessDenied",
props: FeatureBaseProps & {
+ useShadowDom?: boolean;
+ error?: string;
userContext?: any;
},
useComponentOverrides?: () => GenericComponentOverrideMap
@@ -29,6 +31,8 @@ export declare class SessionPreBuiltUI extends RecipeRouter {
static reset(): void;
static AccessDeniedScreen: (
prop?: PropsWithChildren<{
+ useShadowDom?: boolean;
+ error?: string;
userContext?: any;
}>
) => ReactElement;
@@ -36,6 +40,8 @@ export declare class SessionPreBuiltUI extends RecipeRouter {
}
declare const AccessDeniedScreen: (
prop?: PropsWithChildren<{
+ useShadowDom?: boolean;
+ error?: string;
userContext?: any;
}>
) => ReactElement;
diff --git a/lib/build/recipe/session/types.d.ts b/lib/build/recipe/session/types.d.ts
index f244200f8..409bfce83 100644
--- a/lib/build/recipe/session/types.d.ts
+++ b/lib/build/recipe/session/types.d.ts
@@ -11,11 +11,13 @@ export declare type RecipeEventWithSessionContext = RecipeEvent & {
sessionContext: SessionContextUpdate;
};
export declare type InputType = WebJSInputType & {
+ useShadowDom?: boolean;
style?: string;
accessDeniedScreen?: SessionFeatureBaseConfig;
onHandleEvent?: (event: RecipeEventWithSessionContext) => void;
};
export declare type NormalisedSessionConfig = NormalisedConfig & {
+ useShadowDom: boolean;
accessDeniedScreen: NormalisedBaseConfig;
override: {
functions: (
@@ -43,6 +45,7 @@ export declare type SessionContextType =
export declare type AccessDeniedThemeProps = {
recipe: Session;
history: any;
+ error?: string;
config: NormalisedSessionConfig;
};
export declare type ComponentOverrideMap = {
diff --git a/lib/build/session-shared.js b/lib/build/session-shared.js
index bd3b554b5..e19b2d6c0 100644
--- a/lib/build/session-shared.js
+++ b/lib/build/session-shared.js
@@ -1,10 +1,304 @@
"use strict";
var genericComponentOverrideContext = require("./genericComponentOverrideContext.js");
+var WebJSSessionRecipe = require("supertokens-web-js/recipe/session");
+var componentOverrideContext = require("./session-shared3.js");
+var recipe = require("./session-shared2.js");
+var uiEntry = require("./index2.js");
+var React = require("react");
-var _a = genericComponentOverrideContext.createGenericComponentsOverrideContext(),
- useContext = _a[0],
- Provider = _a[1];
+function _interopDefault(e) {
+ return e && e.__esModule ? e : { default: e };
+}
-exports.Provider = Provider;
-exports.useContext = useContext;
+var React__default = /*#__PURE__*/ _interopDefault(React);
+
+var BooleanClaim = /** @class */ (function (_super) {
+ genericComponentOverrideContext.__extends(BooleanClaim, _super);
+ function BooleanClaim(config) {
+ var _this = _super.call(this, config) || this;
+ var validatorsWithCallbacks = genericComponentOverrideContext.__assign({}, _this.validators);
+ var _loop_1 = function (key) {
+ var validator = validatorsWithCallbacks[key];
+ validatorsWithCallbacks[key] = function () {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+ return genericComponentOverrideContext.__assign(
+ genericComponentOverrideContext.__assign({}, validator.apply(void 0, args)),
+ {
+ onFailureRedirection: config.onFailureRedirection,
+ showAccessDeniedOnFailure: config.showAccessDeniedOnFailure,
+ }
+ );
+ };
+ };
+ for (var key in validatorsWithCallbacks) {
+ _loop_1(key);
+ }
+ _this.validators = validatorsWithCallbacks;
+ return _this;
+ }
+ return BooleanClaim;
+})(WebJSSessionRecipe.BooleanClaim);
+
+var PrimitiveArrayClaim = /** @class */ (function (_super) {
+ genericComponentOverrideContext.__extends(PrimitiveArrayClaim, _super);
+ function PrimitiveArrayClaim(config) {
+ var _this = _super.call(this, config) || this;
+ var validatorsWithCallbacks = genericComponentOverrideContext.__assign({}, _this.validators);
+ var _loop_1 = function (key) {
+ var validator = validatorsWithCallbacks[key];
+ validatorsWithCallbacks[key] = function () {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+ return genericComponentOverrideContext.__assign(
+ genericComponentOverrideContext.__assign({}, validator.apply(void 0, args)),
+ {
+ onFailureRedirection: config.onFailureRedirection,
+ showAccessDeniedOnFailure: config.showAccessDeniedOnFailure,
+ }
+ );
+ };
+ };
+ for (var key in validatorsWithCallbacks) {
+ _loop_1(key);
+ }
+ _this.validators = validatorsWithCallbacks;
+ return _this;
+ }
+ return PrimitiveArrayClaim;
+})(WebJSSessionRecipe.PrimitiveArrayClaim);
+
+var PrimitiveClaim = /** @class */ (function (_super) {
+ genericComponentOverrideContext.__extends(PrimitiveClaim, _super);
+ function PrimitiveClaim(config) {
+ var _this = _super.call(this, config) || this;
+ var validatorsWithCallbacks = genericComponentOverrideContext.__assign({}, _this.validators);
+ var _loop_1 = function (key) {
+ var validator = validatorsWithCallbacks[key];
+ validatorsWithCallbacks[key] = function () {
+ var args = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ args[_i] = arguments[_i];
+ }
+ return genericComponentOverrideContext.__assign(
+ genericComponentOverrideContext.__assign({}, validator.apply(void 0, args)),
+ {
+ onFailureRedirection: config.onFailureRedirection,
+ showAccessDeniedOnFailure: config.showAccessDeniedOnFailure,
+ }
+ );
+ };
+ };
+ for (var key in validatorsWithCallbacks) {
+ _loop_1(key);
+ }
+ _this.validators = validatorsWithCallbacks;
+ return _this;
+ }
+ return PrimitiveClaim;
+})(WebJSSessionRecipe.PrimitiveClaim);
+
+var useSessionContext$1 = function () {
+ var ctx = React__default.default.useContext(uiEntry.SessionContext);
+ if (ctx.isDefault === true) {
+ throw new Error("Cannot use useSessionContext outside auth wrapper components.");
+ }
+ return ctx;
+};
+
+var useClaimValue$1 = function (claim) {
+ var ctx = useSessionContext$1();
+ if (ctx.loading) {
+ return {
+ loading: true,
+ };
+ }
+ if (ctx.doesSessionExist === false) {
+ return {
+ loading: false,
+ doesSessionExist: false,
+ value: undefined,
+ };
+ }
+ return {
+ loading: false,
+ doesSessionExist: true,
+ value: claim.getValueFromPayload(ctx.accessTokenPayload),
+ };
+};
+
+/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
+ *
+ * This software is licensed under the Apache License, Version 2.0 (the
+ * "License") as published by the Apache Software Foundation.
+ *
+ * You may not use this file except in compliance with the License. You may
+ * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+var SessionAPIWrapper = /** @class */ (function () {
+ function SessionAPIWrapper() {}
+ SessionAPIWrapper.init = function (config) {
+ return recipe.Session.init(config);
+ };
+ SessionAPIWrapper.getUserId = function (input) {
+ return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
+ return genericComponentOverrideContext.__generator(this, function (_a) {
+ return [
+ 2 /*return*/,
+ recipe.Session.getInstanceOrThrow().getUserId({
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ }),
+ ];
+ });
+ });
+ };
+ SessionAPIWrapper.getAccessToken = function (input) {
+ return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
+ return genericComponentOverrideContext.__generator(this, function (_a) {
+ return [
+ 2 /*return*/,
+ recipe.Session.getInstanceOrThrow().getAccessToken({
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ }),
+ ];
+ });
+ });
+ };
+ SessionAPIWrapper.getAccessTokenPayloadSecurely = function (input) {
+ return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
+ return genericComponentOverrideContext.__generator(this, function (_a) {
+ return [
+ 2 /*return*/,
+ recipe.Session.getInstanceOrThrow().getAccessTokenPayloadSecurely({
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ }),
+ ];
+ });
+ });
+ };
+ SessionAPIWrapper.attemptRefreshingSession = function () {
+ return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
+ return genericComponentOverrideContext.__generator(this, function (_a) {
+ return [2 /*return*/, recipe.Session.getInstanceOrThrow().attemptRefreshingSession()];
+ });
+ });
+ };
+ SessionAPIWrapper.doesSessionExist = function (input) {
+ return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
+ return genericComponentOverrideContext.__generator(this, function (_a) {
+ return [
+ 2 /*return*/,
+ recipe.Session.getInstanceOrThrow().doesSessionExist({
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ }),
+ ];
+ });
+ });
+ };
+ /**
+ * @deprecated
+ */
+ SessionAPIWrapper.addAxiosInterceptors = function (axiosInstance, userContext) {
+ return recipe.Session.addAxiosInterceptors(
+ axiosInstance,
+ genericComponentOverrideContext.getNormalisedUserContext(userContext)
+ );
+ };
+ SessionAPIWrapper.signOut = function (input) {
+ return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
+ return genericComponentOverrideContext.__generator(this, function (_a) {
+ return [
+ 2 /*return*/,
+ recipe.Session.getInstanceOrThrow().signOut({
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ }),
+ ];
+ });
+ });
+ };
+ SessionAPIWrapper.validateClaims = function (input) {
+ return recipe.Session.getInstanceOrThrow().validateClaims({
+ overrideGlobalClaimValidators:
+ input === null || input === void 0 ? void 0 : input.overrideGlobalClaimValidators,
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ });
+ };
+ SessionAPIWrapper.getInvalidClaimsFromResponse = function (input) {
+ return recipe.Session.getInstanceOrThrow().getInvalidClaimsFromResponse(input);
+ };
+ SessionAPIWrapper.getClaimValue = function (input) {
+ return recipe.Session.getInstanceOrThrow().getClaimValue({
+ claim: input.claim,
+ userContext: genericComponentOverrideContext.getNormalisedUserContext(
+ input === null || input === void 0 ? void 0 : input.userContext
+ ),
+ });
+ };
+ SessionAPIWrapper.useSessionContext = useSessionContext$1;
+ SessionAPIWrapper.useClaimValue = useClaimValue$1;
+ SessionAPIWrapper.SessionAuth = uiEntry.SessionAuthWrapper;
+ SessionAPIWrapper.ComponentsOverrideProvider = componentOverrideContext.Provider;
+ return SessionAPIWrapper;
+})();
+var useSessionContext = SessionAPIWrapper.useSessionContext;
+var useClaimValue = SessionAPIWrapper.useClaimValue;
+var SessionAuth = SessionAPIWrapper.SessionAuth;
+var init = SessionAPIWrapper.init;
+var getUserId = SessionAPIWrapper.getUserId;
+var getAccessToken = SessionAPIWrapper.getAccessToken;
+var getAccessTokenPayloadSecurely = SessionAPIWrapper.getAccessTokenPayloadSecurely;
+var attemptRefreshingSession = SessionAPIWrapper.attemptRefreshingSession;
+var doesSessionExist = SessionAPIWrapper.doesSessionExist;
+/**
+ * @deprecated
+ */
+var addAxiosInterceptors = SessionAPIWrapper.addAxiosInterceptors;
+var signOut = SessionAPIWrapper.signOut;
+var validateClaims = SessionAPIWrapper.validateClaims;
+var getInvalidClaimsFromResponse = SessionAPIWrapper.getInvalidClaimsFromResponse;
+var getClaimValue = SessionAPIWrapper.getClaimValue;
+var SessionComponentsOverrideProvider = SessionAPIWrapper.ComponentsOverrideProvider;
+
+exports.BooleanClaim = BooleanClaim;
+exports.PrimitiveArrayClaim = PrimitiveArrayClaim;
+exports.PrimitiveClaim = PrimitiveClaim;
+exports.SessionAPIWrapper = SessionAPIWrapper;
+exports.SessionAuth = SessionAuth;
+exports.SessionComponentsOverrideProvider = SessionComponentsOverrideProvider;
+exports.addAxiosInterceptors = addAxiosInterceptors;
+exports.attemptRefreshingSession = attemptRefreshingSession;
+exports.doesSessionExist = doesSessionExist;
+exports.getAccessToken = getAccessToken;
+exports.getAccessTokenPayloadSecurely = getAccessTokenPayloadSecurely;
+exports.getClaimValue = getClaimValue;
+exports.getInvalidClaimsFromResponse = getInvalidClaimsFromResponse;
+exports.getUserId = getUserId;
+exports.init = init;
+exports.signOut = signOut;
+exports.useClaimValue = useClaimValue;
+exports.useSessionContext = useSessionContext$1;
+exports.useSessionContext$1 = useSessionContext;
+exports.validateClaims = validateClaims;
diff --git a/lib/build/session-shared3.js b/lib/build/session-shared3.js
index c9e7ddfa8..bd3b554b5 100644
--- a/lib/build/session-shared3.js
+++ b/lib/build/session-shared3.js
@@ -1,304 +1,10 @@
"use strict";
var genericComponentOverrideContext = require("./genericComponentOverrideContext.js");
-var WebJSSessionRecipe = require("supertokens-web-js/recipe/session");
-var componentOverrideContext = require("./session-shared.js");
-var recipe = require("./session-shared2.js");
-var uiEntry = require("./index2.js");
-var React = require("react");
-function _interopDefault(e) {
- return e && e.__esModule ? e : { default: e };
-}
+var _a = genericComponentOverrideContext.createGenericComponentsOverrideContext(),
+ useContext = _a[0],
+ Provider = _a[1];
-var React__default = /*#__PURE__*/ _interopDefault(React);
-
-var BooleanClaim = /** @class */ (function (_super) {
- genericComponentOverrideContext.__extends(BooleanClaim, _super);
- function BooleanClaim(config) {
- var _this = _super.call(this, config) || this;
- var validatorsWithCallbacks = genericComponentOverrideContext.__assign({}, _this.validators);
- var _loop_1 = function (key) {
- var validator = validatorsWithCallbacks[key];
- validatorsWithCallbacks[key] = function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- return genericComponentOverrideContext.__assign(
- genericComponentOverrideContext.__assign({}, validator.apply(void 0, args)),
- {
- onFailureRedirection: config.onFailureRedirection,
- showAccessDeniedOnFailure: config.showAccessDeniedOnFailure,
- }
- );
- };
- };
- for (var key in validatorsWithCallbacks) {
- _loop_1(key);
- }
- _this.validators = validatorsWithCallbacks;
- return _this;
- }
- return BooleanClaim;
-})(WebJSSessionRecipe.BooleanClaim);
-
-var PrimitiveArrayClaim = /** @class */ (function (_super) {
- genericComponentOverrideContext.__extends(PrimitiveArrayClaim, _super);
- function PrimitiveArrayClaim(config) {
- var _this = _super.call(this, config) || this;
- var validatorsWithCallbacks = genericComponentOverrideContext.__assign({}, _this.validators);
- var _loop_1 = function (key) {
- var validator = validatorsWithCallbacks[key];
- validatorsWithCallbacks[key] = function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- return genericComponentOverrideContext.__assign(
- genericComponentOverrideContext.__assign({}, validator.apply(void 0, args)),
- {
- onFailureRedirection: config.onFailureRedirection,
- showAccessDeniedOnFailure: config.showAccessDeniedOnFailure,
- }
- );
- };
- };
- for (var key in validatorsWithCallbacks) {
- _loop_1(key);
- }
- _this.validators = validatorsWithCallbacks;
- return _this;
- }
- return PrimitiveArrayClaim;
-})(WebJSSessionRecipe.PrimitiveArrayClaim);
-
-var PrimitiveClaim = /** @class */ (function (_super) {
- genericComponentOverrideContext.__extends(PrimitiveClaim, _super);
- function PrimitiveClaim(config) {
- var _this = _super.call(this, config) || this;
- var validatorsWithCallbacks = genericComponentOverrideContext.__assign({}, _this.validators);
- var _loop_1 = function (key) {
- var validator = validatorsWithCallbacks[key];
- validatorsWithCallbacks[key] = function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- return genericComponentOverrideContext.__assign(
- genericComponentOverrideContext.__assign({}, validator.apply(void 0, args)),
- {
- onFailureRedirection: config.onFailureRedirection,
- showAccessDeniedOnFailure: config.showAccessDeniedOnFailure,
- }
- );
- };
- };
- for (var key in validatorsWithCallbacks) {
- _loop_1(key);
- }
- _this.validators = validatorsWithCallbacks;
- return _this;
- }
- return PrimitiveClaim;
-})(WebJSSessionRecipe.PrimitiveClaim);
-
-var useSessionContext$1 = function () {
- var ctx = React__default.default.useContext(uiEntry.SessionContext);
- if (ctx.isDefault === true) {
- throw new Error("Cannot use useSessionContext outside auth wrapper components.");
- }
- return ctx;
-};
-
-var useClaimValue$1 = function (claim) {
- var ctx = useSessionContext$1();
- if (ctx.loading) {
- return {
- loading: true,
- };
- }
- if (ctx.doesSessionExist === false) {
- return {
- loading: false,
- doesSessionExist: false,
- value: undefined,
- };
- }
- return {
- loading: false,
- doesSessionExist: true,
- value: claim.getValueFromPayload(ctx.accessTokenPayload),
- };
-};
-
-/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
- *
- * This software is licensed under the Apache License, Version 2.0 (the
- * "License") as published by the Apache Software Foundation.
- *
- * You may not use this file except in compliance with the License. You may
- * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-var SessionAPIWrapper = /** @class */ (function () {
- function SessionAPIWrapper() {}
- SessionAPIWrapper.init = function (config) {
- return recipe.Session.init(config);
- };
- SessionAPIWrapper.getUserId = function (input) {
- return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- return genericComponentOverrideContext.__generator(this, function (_a) {
- return [
- 2 /*return*/,
- recipe.Session.getInstanceOrThrow().getUserId({
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- }),
- ];
- });
- });
- };
- SessionAPIWrapper.getAccessToken = function (input) {
- return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- return genericComponentOverrideContext.__generator(this, function (_a) {
- return [
- 2 /*return*/,
- recipe.Session.getInstanceOrThrow().getAccessToken({
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- }),
- ];
- });
- });
- };
- SessionAPIWrapper.getAccessTokenPayloadSecurely = function (input) {
- return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- return genericComponentOverrideContext.__generator(this, function (_a) {
- return [
- 2 /*return*/,
- recipe.Session.getInstanceOrThrow().getAccessTokenPayloadSecurely({
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- }),
- ];
- });
- });
- };
- SessionAPIWrapper.attemptRefreshingSession = function () {
- return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- return genericComponentOverrideContext.__generator(this, function (_a) {
- return [2 /*return*/, recipe.Session.getInstanceOrThrow().attemptRefreshingSession()];
- });
- });
- };
- SessionAPIWrapper.doesSessionExist = function (input) {
- return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- return genericComponentOverrideContext.__generator(this, function (_a) {
- return [
- 2 /*return*/,
- recipe.Session.getInstanceOrThrow().doesSessionExist({
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- }),
- ];
- });
- });
- };
- /**
- * @deprecated
- */
- SessionAPIWrapper.addAxiosInterceptors = function (axiosInstance, userContext) {
- return recipe.Session.addAxiosInterceptors(
- axiosInstance,
- genericComponentOverrideContext.getNormalisedUserContext(userContext)
- );
- };
- SessionAPIWrapper.signOut = function (input) {
- return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () {
- return genericComponentOverrideContext.__generator(this, function (_a) {
- return [
- 2 /*return*/,
- recipe.Session.getInstanceOrThrow().signOut({
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- }),
- ];
- });
- });
- };
- SessionAPIWrapper.validateClaims = function (input) {
- return recipe.Session.getInstanceOrThrow().validateClaims({
- overrideGlobalClaimValidators:
- input === null || input === void 0 ? void 0 : input.overrideGlobalClaimValidators,
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- });
- };
- SessionAPIWrapper.getInvalidClaimsFromResponse = function (input) {
- return recipe.Session.getInstanceOrThrow().getInvalidClaimsFromResponse(input);
- };
- SessionAPIWrapper.getClaimValue = function (input) {
- return recipe.Session.getInstanceOrThrow().getClaimValue({
- claim: input.claim,
- userContext: genericComponentOverrideContext.getNormalisedUserContext(
- input === null || input === void 0 ? void 0 : input.userContext
- ),
- });
- };
- SessionAPIWrapper.useSessionContext = useSessionContext$1;
- SessionAPIWrapper.useClaimValue = useClaimValue$1;
- SessionAPIWrapper.SessionAuth = uiEntry.SessionAuthWrapper;
- SessionAPIWrapper.ComponentsOverrideProvider = componentOverrideContext.Provider;
- return SessionAPIWrapper;
-})();
-var useSessionContext = SessionAPIWrapper.useSessionContext;
-var useClaimValue = SessionAPIWrapper.useClaimValue;
-var SessionAuth = SessionAPIWrapper.SessionAuth;
-var init = SessionAPIWrapper.init;
-var getUserId = SessionAPIWrapper.getUserId;
-var getAccessToken = SessionAPIWrapper.getAccessToken;
-var getAccessTokenPayloadSecurely = SessionAPIWrapper.getAccessTokenPayloadSecurely;
-var attemptRefreshingSession = SessionAPIWrapper.attemptRefreshingSession;
-var doesSessionExist = SessionAPIWrapper.doesSessionExist;
-/**
- * @deprecated
- */
-var addAxiosInterceptors = SessionAPIWrapper.addAxiosInterceptors;
-var signOut = SessionAPIWrapper.signOut;
-var validateClaims = SessionAPIWrapper.validateClaims;
-var getInvalidClaimsFromResponse = SessionAPIWrapper.getInvalidClaimsFromResponse;
-var getClaimValue = SessionAPIWrapper.getClaimValue;
-var SessionComponentsOverrideProvider = SessionAPIWrapper.ComponentsOverrideProvider;
-
-exports.BooleanClaim = BooleanClaim;
-exports.PrimitiveArrayClaim = PrimitiveArrayClaim;
-exports.PrimitiveClaim = PrimitiveClaim;
-exports.SessionAPIWrapper = SessionAPIWrapper;
-exports.SessionAuth = SessionAuth;
-exports.SessionComponentsOverrideProvider = SessionComponentsOverrideProvider;
-exports.addAxiosInterceptors = addAxiosInterceptors;
-exports.attemptRefreshingSession = attemptRefreshingSession;
-exports.doesSessionExist = doesSessionExist;
-exports.getAccessToken = getAccessToken;
-exports.getAccessTokenPayloadSecurely = getAccessTokenPayloadSecurely;
-exports.getClaimValue = getClaimValue;
-exports.getInvalidClaimsFromResponse = getInvalidClaimsFromResponse;
-exports.getUserId = getUserId;
-exports.init = init;
-exports.signOut = signOut;
-exports.useClaimValue = useClaimValue;
-exports.useSessionContext = useSessionContext$1;
-exports.useSessionContext$1 = useSessionContext;
-exports.validateClaims = validateClaims;
+exports.Provider = Provider;
+exports.useContext = useContext;
diff --git a/lib/build/session.js b/lib/build/session.js
index c109ea077..1b65118a2 100644
--- a/lib/build/session.js
+++ b/lib/build/session.js
@@ -3,8 +3,8 @@
Object.defineProperty(exports, "__esModule", { value: true });
require("./genericComponentOverrideContext.js");
-var session = require("./session-shared3.js");
-require("./session-shared.js");
+var session = require("./session-shared.js");
+require("./session-shared3.js");
require("./session-shared2.js");
var uiEntry = require("./index2.js");
require("supertokens-web-js");
diff --git a/lib/build/sessionprebuiltui.js b/lib/build/sessionprebuiltui.js
index f5a76e021..9a46856cd 100644
--- a/lib/build/sessionprebuiltui.js
+++ b/lib/build/sessionprebuiltui.js
@@ -3,7 +3,7 @@
var genericComponentOverrideContext = require("./genericComponentOverrideContext.js");
var jsxRuntime = require("react/jsx-runtime");
var uiEntry = require("./index2.js");
-var componentOverrideContext = require("./session-shared.js");
+var componentOverrideContext = require("./session-shared3.js");
var windowHandler = require("supertokens-web-js/utils/windowHandler");
var translations = require("./translations.js");
var translationContext = require("./translationContext.js");
@@ -82,7 +82,7 @@ function LogoutButton(_a) {
}
var styles =
- '/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.\n *\n * This software is licensed under the Apache License, Version 2.0 (the\n * "License") as published by the Apache Software Foundation.\n *\n * You may not use this file except in compliance with the License. You may\n * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations\n * under the License.\n */\n\n[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 255, 155, 51;\n --palette-primaryBorder: 238, 141, 35;\n --palette-success: 65, 167, 0;\n --palette-successBackground: 217, 255, 191;\n --palette-error: 255, 23, 23;\n --palette-errorBackground: 255, 241, 235;\n --palette-textTitle: 34, 34, 34;\n --palette-textLabel: 34, 34, 34;\n --palette-textInput: 34, 34, 34;\n --palette-textPrimary: 101, 101, 101;\n --palette-textLink: 0, 118, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 128, 128, 128;\n --palette-superTokensBrandingBackground: 242, 245, 246;\n --palette-superTokensBrandingText: 173, 189, 196;\n\n --font-size-0: 12px;\n --font-size-1: 14px;\n --font-size-2: 16px;\n --font-size-3: 19px;\n --font-size-4: 24px;\n}\n\n/*\n * Default styles.\n */\n\n@-webkit-keyframes slideTop {\n 0% {\n -webkit-transform: translateY(-5px);\n transform: translateY(-5px);\n }\n 100% {\n -webkit-transform: translateY(0px);\n transform: translateY(0px);\n }\n}\n\n@keyframes slideTop {\n 0% {\n -webkit-transform: translateY(-5px);\n transform: translateY(-5px);\n }\n 100% {\n -webkit-transform: translateY(0px);\n transform: translateY(0px);\n }\n}\n\n@-webkit-keyframes swing-in-top-fwd {\n 0% {\n -webkit-transform: rotateX(-100deg);\n transform: rotateX(-100deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n -webkit-transform: rotateX(0deg);\n transform: rotateX(0deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 1;\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n -webkit-transform: rotateX(-100deg);\n transform: rotateX(-100deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n -webkit-transform: rotateX(0deg);\n transform: rotateX(0deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Rubik", sans-serif;\n margin: 12px auto;\n margin-top: 26px;\n margin-bottom: 26px;\n width: 420px;\n text-align: center;\n border-radius: 8px;\n box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.16);\n background-color: rgb(var(--palette-background));\n}\n\n@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 0 auto;\n background: rgb(var(--palette-superTokensBrandingBackground));\n color: rgb(var(--palette-superTokensBrandingText));\n text-decoration: none;\n width: -webkit-fit-content;\n width: -moz-fit-content;\n width: fit-content;\n border-radius: 6px 6px 0 0;\n padding: 4px 9px;\n font-weight: 300;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 15px;\n padding-left: 18px;\n padding-right: 18px;\n letter-spacing: 0.2px;\n font-size: var(--font-size-1);\n border-radius: 8px;\n color: rgb(var(--palette-error));\n -webkit-animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 40px;\n letter-spacing: 0.58px;\n font-weight: 800;\n margin-bottom: 2px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n margin-bottom: 21px;\n}\n\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n\n/* TODO: split the link style into separate things*/\n\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\n\n[data-supertokens~="link"] {\n padding-left: 3px;\n padding-right: 3px;\n color: rgb(var(--palette-textLink));\n font-size: var(--font-size-1);\n cursor: pointer;\n letter-spacing: 0.16px;\n line-height: 26px;\n}\n\n[data-supertokens~="primaryText"] {\n font-size: var(--font-size-1);\n font-weight: 500;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 300;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1em;\n margin-bottom: 1em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 13px;\n font-size: var(--font-size-3);\n letter-spacing: 1.1px;\n font-weight: 500;\n line-height: 28px;\n}\n\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\n}\n\n[data-supertokens~="generalSuccess"] {\n color: rgb(var(--palette-success));\n font-size: var(--font-size-1);\n background: rgb(var(--palette-successBackground));\n -webkit-animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n padding: 9px 15px 9px 15px;\n border-radius: 6px;\n display: inline-block;\n}\n\n[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n\n[data-supertokens~="linkButton"] {\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n\n[data-supertokens~="button"] {\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 700;\n border-width: 1px;\n border-style: solid;\n border-radius: 6px;\n border-color: rgb(var(--palette-primaryBorder));\n background-position: center;\n transition: all 0.4s;\n background-size: 12000%;\n cursor: pointer;\n}\n\n[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n -webkit-filter: brightness(0.85);\n filter: brightness(0.85);\n}\n\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n\n/* Override */\n\n[data-supertokens~="row"] {\n padding-top: 32px;\n padding-bottom: 32px;\n}\n\n[data-supertokens~="divider"] {\n padding: 0;\n margin: 24px 0;\n}\n\n[data-supertokens~="headerTitle"] {\n padding-top: 24px;\n font-style: normal;\n font-weight: 700;\n font-size: 20px;\n line-height: 30px;\n}\n\n/* Override end */\n\n[data-supertokens~="center"] {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1 1 auto;\n}\n\n[data-supertokens~="buttonsGroup"] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n[data-supertokens~="buttonBase"] {\n font-size: var(--font-size-1);\n line-height: 21px;\n font-weight: 500;\n background: transparent;\n outline: none;\n border: none;\n cursor: pointer;\n}\n\n[data-supertokens~="backButton"] {\n color: rgb(var(--palette-textLink));\n}\n\n[data-supertokens~="logoutButton"] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: rgb(var(--palette-textGray));\n}\n';
+ '/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.\n *\n * This software is licensed under the Apache License, Version 2.0 (the\n * "License") as published by the Apache Software Foundation.\n *\n * You may not use this file except in compliance with the License. You may\n * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * License for the specific language governing permissions and limitations\n * under the License.\n */\n\n[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 255, 155, 51;\n --palette-primaryBorder: 238, 141, 35;\n --palette-success: 65, 167, 0;\n --palette-successBackground: 217, 255, 191;\n --palette-error: 255, 23, 23;\n --palette-errorBackground: 255, 241, 235;\n --palette-textTitle: 34, 34, 34;\n --palette-textLabel: 34, 34, 34;\n --palette-textInput: 34, 34, 34;\n --palette-textPrimary: 101, 101, 101;\n --palette-textLink: 0, 118, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 128, 128, 128;\n --palette-superTokensBrandingBackground: 242, 245, 246;\n --palette-superTokensBrandingText: 173, 189, 196;\n\n --font-size-0: 12px;\n --font-size-1: 14px;\n --font-size-2: 16px;\n --font-size-3: 19px;\n --font-size-4: 24px;\n}\n\n/*\n * Default styles.\n */\n\n@-webkit-keyframes slideTop {\n 0% {\n -webkit-transform: translateY(-5px);\n transform: translateY(-5px);\n }\n 100% {\n -webkit-transform: translateY(0px);\n transform: translateY(0px);\n }\n}\n\n@keyframes slideTop {\n 0% {\n -webkit-transform: translateY(-5px);\n transform: translateY(-5px);\n }\n 100% {\n -webkit-transform: translateY(0px);\n transform: translateY(0px);\n }\n}\n\n@-webkit-keyframes swing-in-top-fwd {\n 0% {\n -webkit-transform: rotateX(-100deg);\n transform: rotateX(-100deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n -webkit-transform: rotateX(0deg);\n transform: rotateX(0deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 1;\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n -webkit-transform: rotateX(-100deg);\n transform: rotateX(-100deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n -webkit-transform: rotateX(0deg);\n transform: rotateX(0deg);\n -webkit-transform-origin: top;\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Rubik", sans-serif;\n margin: 12px auto;\n margin-top: 26px;\n margin-bottom: 26px;\n width: 420px;\n text-align: center;\n border-radius: 8px;\n box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.16);\n background-color: rgb(var(--palette-background));\n}\n\n@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 0 auto;\n background: rgb(var(--palette-superTokensBrandingBackground));\n color: rgb(var(--palette-superTokensBrandingText));\n text-decoration: none;\n width: -webkit-fit-content;\n width: -moz-fit-content;\n width: fit-content;\n border-radius: 6px 6px 0 0;\n padding: 4px 9px;\n font-weight: 300;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 15px;\n padding-left: 18px;\n padding-right: 18px;\n letter-spacing: 0.2px;\n font-size: var(--font-size-1);\n border-radius: 8px;\n color: rgb(var(--palette-error));\n -webkit-animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 40px;\n letter-spacing: 0.58px;\n font-weight: 800;\n margin-bottom: 2px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n margin-bottom: 21px;\n}\n\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n\n/* TODO: split the link style into separate things*/\n\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\n\n[data-supertokens~="link"] {\n padding-left: 3px;\n padding-right: 3px;\n color: rgb(var(--palette-textLink));\n font-size: var(--font-size-1);\n cursor: pointer;\n letter-spacing: 0.16px;\n line-height: 26px;\n}\n\n[data-supertokens~="primaryText"] {\n font-size: var(--font-size-1);\n font-weight: 500;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 300;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1em;\n margin-bottom: 1em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 13px;\n font-size: var(--font-size-3);\n letter-spacing: 1.1px;\n font-weight: 500;\n line-height: 28px;\n}\n\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\n}\n\n[data-supertokens~="generalSuccess"] {\n color: rgb(var(--palette-success));\n font-size: var(--font-size-1);\n background: rgb(var(--palette-successBackground));\n -webkit-animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n padding: 9px 15px 9px 15px;\n border-radius: 6px;\n display: inline-block;\n}\n\n[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n\n[data-supertokens~="linkButton"] {\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n\n[data-supertokens~="button"] {\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 700;\n border-width: 1px;\n border-style: solid;\n border-radius: 6px;\n border-color: rgb(var(--palette-primaryBorder));\n background-position: center;\n transition: all 0.4s;\n background-size: 12000%;\n cursor: pointer;\n}\n\n[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n -webkit-filter: brightness(0.85);\n filter: brightness(0.85);\n}\n\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n\n/* Override */\n\n[data-supertokens~="row"] {\n padding-top: 32px;\n padding-bottom: 32px;\n}\n\n[data-supertokens~="divider"] {\n padding: 0;\n margin: 24px 0;\n}\n\n[data-supertokens~="headerTitle"] {\n padding-top: 24px;\n font-style: normal;\n font-weight: 700;\n font-size: 20px;\n line-height: 30px;\n}\n\n/* Override end */\n\n[data-supertokens~="center"] {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1 1 auto;\n}\n\n[data-supertokens~="buttonsGroup"] {\n margin-top: 24px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n[data-supertokens~="buttonBase"] {\n font-size: var(--font-size-1);\n line-height: 21px;\n font-weight: 500;\n background: transparent;\n outline: none;\n border: none;\n cursor: pointer;\n}\n\n[data-supertokens~="backButton"] {\n color: rgb(var(--palette-textLink));\n}\n\n[data-supertokens~="logoutButton"] {\n display: flex;\n align-items: center;\n gap: 6px;\n color: rgb(var(--palette-textGray));\n}\n';
var ThemeBase = function (_a) {
var children = _a.children,
@@ -166,6 +166,14 @@ var AccessDeniedScreen$2 = function (props) {
)
),
jsxRuntime.jsx("div", { "data-supertokens": "divider" }),
+ props.error &&
+ jsxRuntime.jsxs(
+ "div",
+ genericComponentOverrideContext.__assign(
+ { "data-supertokens": "primaryText accessDeniedError" },
+ { children: [" ", props.error] }
+ )
+ ),
jsxRuntime.jsxs(
"div",
genericComponentOverrideContext.__assign(
@@ -216,7 +224,7 @@ var defaultTranslationsSession = {
};
var AccessDeniedScreen$1 = function (props) {
- var _a;
+ var _a, _b;
var recipeComponentOverrides = props.useComponentOverrides();
var history =
(_a = uiEntry.UI.getReactRouterDomWithCustomHistory()) === null || _a === void 0
@@ -230,12 +238,19 @@ var AccessDeniedScreen$1 = function (props) {
children: jsxRuntime.jsx(
uiEntry.FeatureWrapper,
genericComponentOverrideContext.__assign(
- { defaultStore: defaultTranslationsSession },
+ {
+ defaultStore: defaultTranslationsSession,
+ useShadowDom:
+ (_b = props.useShadowDom) !== null && _b !== void 0
+ ? _b
+ : props.recipe.config.useShadowDom,
+ },
{
children: jsxRuntime.jsx(AccessDeniedScreenTheme, {
config: props.recipe.config,
history: history,
recipe: props.recipe,
+ error: props.error,
}),
}
)
@@ -270,6 +285,8 @@ var SessionPreBuiltUI = /** @class */ (function (_super) {
children: jsxRuntime.jsx(AccessDeniedScreen$1, {
recipe: _this.recipeInstance,
useComponentOverrides: useComponentOverrides,
+ error: props.error,
+ useShadowDom: props.useShadowDom,
}),
}
)
diff --git a/lib/build/thirdpartyemailpasswordprebuiltui.js b/lib/build/thirdpartyemailpasswordprebuiltui.js
index edace9854..4f57d9cd0 100644
--- a/lib/build/thirdpartyemailpasswordprebuiltui.js
+++ b/lib/build/thirdpartyemailpasswordprebuiltui.js
@@ -28,8 +28,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("./session-shared2.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared3.js");
require("./session-shared.js");
+require("./session-shared3.js");
require("./emailpassword-shared3.js");
require("./emailverification-shared2.js");
require("./emailpassword-shared7.js");
diff --git a/lib/build/thirdpartypasswordlessprebuiltui.js b/lib/build/thirdpartypasswordlessprebuiltui.js
index 8641abcd3..8c61dc76c 100644
--- a/lib/build/thirdpartypasswordlessprebuiltui.js
+++ b/lib/build/thirdpartypasswordlessprebuiltui.js
@@ -28,8 +28,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("./session-shared2.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared3.js");
require("./session-shared.js");
+require("./session-shared3.js");
require("./passwordless-shared.js");
require("supertokens-web-js/utils/error");
require("./emailpassword-shared2.js");
diff --git a/lib/build/thirdpartyprebuiltui.js b/lib/build/thirdpartyprebuiltui.js
index f76dfe0fa..15e20a138 100644
--- a/lib/build/thirdpartyprebuiltui.js
+++ b/lib/build/thirdpartyprebuiltui.js
@@ -24,8 +24,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("./session-shared2.js");
require("supertokens-web-js/recipe/session");
-require("./session-shared3.js");
require("./session-shared.js");
+require("./session-shared3.js");
require("supertokens-web-js/recipe/thirdparty");
require("./authRecipe-shared.js");
require("supertokens-web-js/lib/build/normalisedURLPath");
diff --git a/lib/build/ui-entry.js b/lib/build/ui-entry.js
index 5a2e95d9f..af7d68c58 100644
--- a/lib/build/ui-entry.js
+++ b/lib/build/ui-entry.js
@@ -12,12 +12,12 @@ require("react-dom");
require("./multitenancy-shared.js");
require("./multifactorauth-shared.js");
require("supertokens-web-js/recipe/multifactorauth");
+require("supertokens-web-js/utils");
require("supertokens-web-js/utils/postSuperTokensInitCallbacks");
require("supertokens-web-js/utils/sessionClaimValidatorStore");
require("./recipeModule-shared.js");
require("./session-shared2.js");
require("supertokens-web-js/recipe/session");
-require("supertokens-web-js/utils");
require("supertokens-web-js");
require("supertokens-web-js/utils/cookieHandler");
require("supertokens-web-js/utils/windowHandler");
diff --git a/lib/ts/recipe/multifactorauth/components/features/factorChooser/index.tsx b/lib/ts/recipe/multifactorauth/components/features/factorChooser/index.tsx
index 0f9f51c3e..0d68173a3 100644
--- a/lib/ts/recipe/multifactorauth/components/features/factorChooser/index.tsx
+++ b/lib/ts/recipe/multifactorauth/components/features/factorChooser/index.tsx
@@ -67,8 +67,15 @@ export const FactorChooser: React.FC = (props) => {
mfaInfo.factors.isAllowedToSetup.includes(id) || mfaInfo.factors.isAlreadySetup.includes(id)
)
.filter(({ id }) => mfaClaimValue.value!.n.length === 0 || mfaClaimValue.value!.n.includes(id));
- if (availableFactors.length === 1) {
- return MultiFactorAuth.getInstanceOrThrow().redirectToFactor(availableFactors[0].id, props.history);
+
+ // If we got here when the next array is not empty, that means that the user redirected here intentionally
+ // In this case we do not want to automatically redirect away but show the chooser screen.
+ if (mfaClaimValue.value!.n.length !== 0 && availableFactors.length === 1) {
+ return MultiFactorAuth.getInstanceOrThrow().redirectToFactor(
+ availableFactors[0].id,
+ false,
+ props.history
+ );
} else {
setMFAInfo(mfaInfo.factors);
}
@@ -127,7 +134,7 @@ export const FactorChooser: React.FC = (props) => {
showBackButton: mfaClaimValue.value?.n.length === 0,
mfaInfo: mfaInfo,
availableFactors: availableFactors,
- logout: signOut,
+ onLogoutClicked: signOut,
navigateToFactor: navigateToFactor,
};
diff --git a/lib/ts/recipe/multifactorauth/components/themes/factorChooser/index.tsx b/lib/ts/recipe/multifactorauth/components/themes/factorChooser/index.tsx
index 682b89e39..5e8483b52 100644
--- a/lib/ts/recipe/multifactorauth/components/themes/factorChooser/index.tsx
+++ b/lib/ts/recipe/multifactorauth/components/themes/factorChooser/index.tsx
@@ -15,7 +15,9 @@
import { SuperTokensBranding } from "../../../../../components/SuperTokensBranding";
import { hasFontDefined } from "../../../../../styles/styles";
+import { useTranslation } from "../../../../../translation/translationContext";
import UserContextWrapper from "../../../../../usercontext/userContextWrapper";
+import { AccessDeniedScreen } from "../../../../session/prebuiltui";
import { ThemeBase } from "../themeBase";
import { FactorChooserFooter } from "./factorChooserFooter";
@@ -25,6 +27,15 @@ import { FactorList } from "./factorList";
import type { FactorChooserThemeProps } from "../../../types";
export function FactorChooserTheme(props: FactorChooserThemeProps): JSX.Element {
+ const t = useTranslation();
+ if (props.availableFactors.length === 0) {
+ return (
+
+ );
+ }
return (
-
+
);
diff --git a/lib/ts/recipe/multifactorauth/components/themes/translations.ts b/lib/ts/recipe/multifactorauth/components/themes/translations.ts
index 468d3d52e..f5300cb9f 100644
--- a/lib/ts/recipe/multifactorauth/components/themes/translations.ts
+++ b/lib/ts/recipe/multifactorauth/components/themes/translations.ts
@@ -5,5 +5,9 @@ export const defaultTranslationsMultiFactorAuth = {
...defaultTranslationsCommon.en,
MULTI_FACTOR_CHOOSER_HEADER_TITLE: "Please select a second factor",
MULTI_FACTOR_AUTH_LOGOUT: "Logout",
+
+ MFA_NO_AVAILABLE_OPTIONS: "You have no available secondary factors.",
+ MFA_NO_AVAILABLE_OPTIONS_LOGIN:
+ "You have no available secondary factors and cannot complete the sign-in process. Please contact support.",
},
};
diff --git a/lib/ts/recipe/multifactorauth/index.ts b/lib/ts/recipe/multifactorauth/index.ts
index 5161e7145..856a79f39 100644
--- a/lib/ts/recipe/multifactorauth/index.ts
+++ b/lib/ts/recipe/multifactorauth/index.ts
@@ -46,17 +46,29 @@ export default class Wrapper {
});
}
+ static redirectToFactor(factorId: string, redirectBack = true, history?: any) {
+ return MultiFactorAuthRecipe.getInstanceOrThrow().redirectToFactor(factorId, redirectBack, history);
+ }
+
+ static redirectToFactorChooser(redirectBack = true, history?: any) {
+ return MultiFactorAuthRecipe.getInstanceOrThrow().redirectToFactorChooser(redirectBack, history);
+ }
+
static ComponentsOverrideProvider = RecipeComponentsOverrideContextProvider;
}
const init = Wrapper.init;
const getMFAInfo = Wrapper.getMFAInfo;
+const redirectToFactor = Wrapper.redirectToFactor;
+const redirectToFactorChooser = Wrapper.redirectToFactorChooser;
const MultiFactorAuthComponentsOverrideProvider = Wrapper.ComponentsOverrideProvider;
const MultiFactorAuthClaim = MultiFactorAuthRecipe.MultiFactorAuthClaim;
export {
init,
getMFAInfo,
+ redirectToFactor,
+ redirectToFactorChooser,
MultiFactorAuthComponentsOverrideProvider,
GetRedirectionURLContext,
PreAPIHookContext as PreAPIHookContext,
diff --git a/lib/ts/recipe/multifactorauth/recipe.tsx b/lib/ts/recipe/multifactorauth/recipe.tsx
index 6d4bcd6ed..82655ee96 100644
--- a/lib/ts/recipe/multifactorauth/recipe.tsx
+++ b/lib/ts/recipe/multifactorauth/recipe.tsx
@@ -18,12 +18,14 @@
*/
import MultiFactorAuthWebJS from "supertokens-web-js/recipe/multifactorauth";
+import { appendQueryParamsToURL } from "supertokens-web-js/utils";
import NormalisedURLPath from "supertokens-web-js/utils/normalisedURLPath";
import { PostSuperTokensInitCallbacks } from "supertokens-web-js/utils/postSuperTokensInitCallbacks";
import { SessionClaimValidatorStore } from "supertokens-web-js/utils/sessionClaimValidatorStore";
import { SSR_ERROR } from "../../constants";
import SuperTokens from "../../superTokens";
+import { getCurrentNormalisedUrlPath, getRedirectToPathFromURL } from "../../utils";
import RecipeModule from "../recipeModule";
import { DEFAULT_FACTOR_CHOOSER_PATH } from "./constants";
@@ -57,8 +59,8 @@ export default class MultiFactorAuth extends RecipeModule<
);
public recipeID = MultiFactorAuth.RECIPE_ID;
- private readonly firstFactors: string[] = [];
- private readonly secondaryFactors: SecondaryFactorRedirectionInfo[] = [];
+ private readonly firstFactors: Set = new Set();
+ private secondaryFactors: SecondaryFactorRedirectionInfo[] = [];
constructor(
config: NormalisedConfigWithAppInfoAndRecipeID,
@@ -130,46 +132,67 @@ export default class MultiFactorAuth extends RecipeModule<
getDefaultRedirectionURL = async (context: GetRedirectionURLContext): Promise => {
if (context.action === "FACTOR_CHOOSER") {
const chooserPath = new NormalisedURLPath(DEFAULT_FACTOR_CHOOSER_PATH);
- return `${this.config.appInfo.websiteBasePath.appendPath(chooserPath).getAsStringDangerous()}`;
+ return this.config.appInfo.websiteBasePath.appendPath(chooserPath).getAsStringDangerous();
} else if (context.action === "GO_TO_FACTOR") {
const redirectInfo = this.getSecondaryFactors().find((f) => f.id === context.factorId);
if (redirectInfo !== undefined) {
- return redirectInfo.path;
+ return this.config.appInfo.websiteBasePath.appendPath(redirectInfo.path).getAsStringDangerous();
}
- // TODO: access denied screen if not defined?
- return "/";
+ throw new Error("Requested redirect to unknown factor id");
} else {
return "/";
}
};
- getDefaultFirstFactors(): string[] {
- return this.firstFactors;
- }
-
addMFAFactors(firstFactors: string[], secondaryFactors: SecondaryFactorRedirectionInfo[]) {
- this.firstFactors.push(...firstFactors);
- this.secondaryFactors.push(...secondaryFactors);
+ for (const fact of firstFactors) {
+ this.firstFactors.add(fact);
+ }
+ this.secondaryFactors = [
+ ...this.secondaryFactors.filter((factor) =>
+ secondaryFactors.every((newFactor) => factor.id !== newFactor.id)
+ ),
+ ...secondaryFactors,
+ ];
}
getFirstFactors() {
- return this.config.firstFactors ?? this.firstFactors;
+ return this.config.firstFactors ?? Array.from(this.firstFactors);
}
getSecondaryFactors() {
return this.config.getFactorInfo(this.secondaryFactors);
}
- async redirectToFactor(factorId: string, history?: any) {
- return SuperTokens.getInstanceOrThrow().redirectToUrl(
- await this.getRedirectUrl({ action: "GO_TO_FACTOR", factorId }),
- history
- );
+ async redirectToFactor(factorId: string, redirectBack = false, history?: any) {
+ let url = await this.getRedirectUrl({ action: "GO_TO_FACTOR", factorId });
+
+ if (redirectBack) {
+ const redirectUrl = getCurrentNormalisedUrlPath().getAsStringDangerous();
+ url = appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ } else {
+ const redirectUrl = getRedirectToPathFromURL();
+ if (redirectUrl) {
+ url = appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ }
+ }
+
+ return SuperTokens.getInstanceOrThrow().redirectToUrl(url, history);
}
- async redirectToFactorChooser(history?: any) {
- return SuperTokens.getInstanceOrThrow().redirectToUrl(
- await this.getRedirectUrl({ action: "FACTOR_CHOOSER" }),
- history
- );
+
+ async redirectToFactorChooser(redirectBack = false, history?: any) {
+ let url = await this.getRedirectUrl({ action: "FACTOR_CHOOSER" });
+
+ if (redirectBack) {
+ const redirectUrl = getCurrentNormalisedUrlPath().getAsStringDangerous();
+ url = appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ } else {
+ const redirectUrl = getRedirectToPathFromURL();
+ if (redirectUrl) {
+ url = appendQueryParamsToURL(url, { redirectToPath: redirectUrl });
+ }
+ }
+
+ return SuperTokens.getInstanceOrThrow().redirectToUrl(url, history);
}
}
diff --git a/lib/ts/recipe/multifactorauth/types.ts b/lib/ts/recipe/multifactorauth/types.ts
index 1449f6859..08b22e940 100644
--- a/lib/ts/recipe/multifactorauth/types.ts
+++ b/lib/ts/recipe/multifactorauth/types.ts
@@ -22,6 +22,7 @@ import type {
} from "../recipeModule/types";
import type { FC } from "react";
import type { OverrideableBuilder } from "supertokens-js-override";
+import type NormalisedURLPath from "supertokens-web-js/lib/build/normalisedURLPath";
import type { RecipeInterface } from "supertokens-web-js/recipe/multifactorauth";
import type { MFAFactorInfo } from "supertokens-web-js/recipe/multifactorauth/types";
@@ -91,7 +92,7 @@ export type FactorChooserThemeProps = {
showBackButton: boolean;
onBackButtonClicked: () => void;
navigateToFactor: (factorId: string) => void;
- logout: () => void;
+ onLogoutClicked: () => void;
config: NormalisedConfig;
userContext?: any;
};
@@ -101,5 +102,5 @@ export type SecondaryFactorRedirectionInfo = {
name: string;
description: string;
logo: FC;
- path: string;
+ path: NormalisedURLPath;
};
diff --git a/lib/ts/recipe/passwordless/recipe.tsx b/lib/ts/recipe/passwordless/recipe.tsx
index 613c27ec4..a820d2855 100644
--- a/lib/ts/recipe/passwordless/recipe.tsx
+++ b/lib/ts/recipe/passwordless/recipe.tsx
@@ -18,9 +18,9 @@
*/
import PasswordlessWebJS from "supertokens-web-js/recipe/passwordless";
+import NormalisedURLPath from "supertokens-web-js/utils/normalisedURLPath";
import { PostSuperTokensInitCallbacks } from "supertokens-web-js/utils/postSuperTokensInitCallbacks";
-// import { LinkIcon } from "../../components/assets/linkIcon";
import { OTPIcon } from "../../components/assets/otpIcon";
import { SSR_ERROR } from "../../constants";
import { isTest } from "../../utils";
@@ -81,31 +81,16 @@ export default class Passwordless extends AuthRecipe<
id: "otp-phone",
name: "SMS based OTP",
description: "Get an OTP code on your phone to complete the authentication request",
- path: "/auth/mfa/otp-phone", // TODO: websitebasepath
+ path: new NormalisedURLPath("/check-auth/otp-phone"),
logo: OTPIcon,
},
- // {
- // id: "link-phone",
- // name: "SMS based Magic link",
- // description: "Get a magic link on your phone to complete the authentication request",
- // path: "/auth/mfa/link-phone",
- // logo: LinkIcon,
- // },
{
id: "otp-email",
name: "Email based OTP",
description: "Get an OTP code on your email address to complete the authentication request",
- path: "/auth/mfa/otp-email", // TODO: websitebasepath
+ path: new NormalisedURLPath("/check-auth/otp-email"),
logo: OTPIcon,
},
- // {
- // id: "link-email",
- // name: "SMS based Magic link",
- // description:
- // "Get a magic link on your email address to complete the authentication request",
- // path: "/auth/mfa/link-email",
- // logo: LinkIcon,
- // },
]
);
}
diff --git a/lib/ts/recipe/recipeRouter/index.tsx b/lib/ts/recipe/recipeRouter/index.tsx
index c6d43c30c..9ece4880b 100644
--- a/lib/ts/recipe/recipeRouter/index.tsx
+++ b/lib/ts/recipe/recipeRouter/index.tsx
@@ -8,6 +8,7 @@ import type RecipeModule from "../recipeModule";
import type NormalisedURLPath from "supertokens-web-js/lib/build/normalisedURLPath";
// The related ADR: https://supertokens.com/docs/contribute/decisions/multitenancy/0006
+// TODO: This could be by the recipes registering what factors they provide (at least partially)
const priorityOrder: {
rid: string;
includes: ("thirdparty" | "emailpassword" | "passwordless")[];
@@ -52,9 +53,9 @@ function chooseComponentBasedOnFirstFactors(
let maxProvided = 0;
let component = undefined;
// We find the component that provides the most factors
- for (const { rid, factorsProvided } of priorityOrder.reverse()) {
+ for (const { rid, factorsProvided } of priorityOrder) {
const providedByCurrent = factorsProvided.filter((id) => firstFactors.includes(id)).length;
- if (providedByCurrent >= maxProvided) {
+ if (providedByCurrent > maxProvided) {
const matchingComp = routeComponents.find((comp) => comp.recipeID === rid);
if (matchingComp) {
maxProvided = providedByCurrent;
@@ -63,6 +64,10 @@ function chooseComponentBasedOnFirstFactors(
}
}
+ if (component === undefined) {
+ throw new Error("No enabled recipes overlap with the requested firstFactors: " + firstFactors);
+ }
+
return component;
}
diff --git a/lib/ts/recipe/session/components/features/accessDeniedScreen/index.tsx b/lib/ts/recipe/session/components/features/accessDeniedScreen/index.tsx
index 3da527c3c..d7a66ff73 100644
--- a/lib/ts/recipe/session/components/features/accessDeniedScreen/index.tsx
+++ b/lib/ts/recipe/session/components/features/accessDeniedScreen/index.tsx
@@ -14,6 +14,8 @@ const AccessDeniedScreen: React.FC<
FeatureBaseProps & {
recipe: Recipe;
useComponentOverrides: () => ComponentOverrideMap;
+ useShadowDom?: boolean;
+ error?: string;
}
> = (props) => {
const recipeComponentOverrides = props.useComponentOverrides();
@@ -21,8 +23,15 @@ const AccessDeniedScreen: React.FC<
return (
-
-
+
+
);
diff --git a/lib/ts/recipe/session/components/themes/accessDeniedScreenTheme/index.tsx b/lib/ts/recipe/session/components/themes/accessDeniedScreenTheme/index.tsx
index 13d904618..fa3ceb5e3 100644
--- a/lib/ts/recipe/session/components/themes/accessDeniedScreenTheme/index.tsx
+++ b/lib/ts/recipe/session/components/themes/accessDeniedScreenTheme/index.tsx
@@ -47,6 +47,7 @@ const AccessDeniedScreen: FC = (props) => {
{t("ACCESS_DENIED")}
+ {props.error && {props.error}
}
diff --git a/lib/ts/recipe/session/components/themes/styles.css b/lib/ts/recipe/session/components/themes/styles.css
index 053a63e9a..624b6a843 100644
--- a/lib/ts/recipe/session/components/themes/styles.css
+++ b/lib/ts/recipe/session/components/themes/styles.css
@@ -45,6 +45,7 @@
}
[data-supertokens~="buttonsGroup"] {
+ margin-top: 24px;
display: flex;
align-items: center;
justify-content: space-between;
diff --git a/lib/ts/recipe/session/prebuiltui.tsx b/lib/ts/recipe/session/prebuiltui.tsx
index 3adff1e5a..217cafa7f 100644
--- a/lib/ts/recipe/session/prebuiltui.tsx
+++ b/lib/ts/recipe/session/prebuiltui.tsx
@@ -33,7 +33,7 @@ export class SessionPreBuiltUI extends RecipeRouter {
}
static getFeatureComponent(
componentName: "accessDenied",
- props: FeatureBaseProps & { redirectOnSessionExists?: boolean; userContext?: any },
+ props: FeatureBaseProps & { error?: string; userContext?: any },
useComponentOverrides: () => GenericComponentOverrideMap
= useRecipeComponentOverrideContext
): JSX.Element {
return SessionPreBuiltUI.getInstanceOrInitAndGetInstance().getFeatureComponent(
@@ -52,7 +52,7 @@ export class SessionPreBuiltUI extends RecipeRouter {
};
getFeatureComponent = (
componentName: "accessDenied",
- props: FeatureBaseProps & { userContext?: any },
+ props: FeatureBaseProps & { useShadowDom?: boolean; error?: string; userContext?: any },
useComponentOverrides: () => GenericComponentOverrideMap = useRecipeComponentOverrideContext
): JSX.Element => {
if (componentName === "accessDenied") {
@@ -61,6 +61,8 @@ export class SessionPreBuiltUI extends RecipeRouter {
);
@@ -78,8 +80,9 @@ export class SessionPreBuiltUI extends RecipeRouter {
return;
}
- static AccessDeniedScreen = (prop: PropsWithChildren<{ userContext?: any }> = {}): ReactElement =>
- this.getFeatureComponent("accessDenied", prop);
+ static AccessDeniedScreen = (
+ prop: PropsWithChildren<{ useShadowDom?: boolean; error?: string; userContext?: any }> = {}
+ ): ReactElement => this.getFeatureComponent("accessDenied", prop);
static AccessDeniedScreenTheme = AccessDeniedScreenTheme;
}
diff --git a/lib/ts/recipe/session/types.ts b/lib/ts/recipe/session/types.ts
index 6aae78bc3..92c7bdfa6 100644
--- a/lib/ts/recipe/session/types.ts
+++ b/lib/ts/recipe/session/types.ts
@@ -26,12 +26,14 @@ import type { UserInput as WebJSInputType, RecipeEvent } from "supertokens-web-j
export type RecipeEventWithSessionContext = RecipeEvent & { sessionContext: SessionContextUpdate };
export type InputType = WebJSInputType & {
+ useShadowDom?: boolean;
style?: string;
accessDeniedScreen?: SessionFeatureBaseConfig;
onHandleEvent?: (event: RecipeEventWithSessionContext) => void;
};
export type NormalisedSessionConfig = NormalisedConfig & {
+ useShadowDom: boolean;
accessDeniedScreen: NormalisedBaseConfig;
override: {
functions: (
@@ -64,6 +66,7 @@ export type SessionContextType =
export type AccessDeniedThemeProps = {
recipe: Session;
history: any;
+ error?: string;
config: NormalisedSessionConfig;
};