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; };