diff --git a/CHANGELOG.md b/CHANGELOG.md index ed42be581..9b9b2029b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,91 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +## [0.49.0] - 2024-10-07 + +### Changes + +- Added the `OAuth2Provider` recipe +- Changed the input types and default implementation of `AuthPageHeader` to show the client information in OAuth2 flows + +### Breaking changes + +- Now only supporting FDI 4.0 (Node >= 24.0.0) +- All `getRedirectionURL` functions now also get a new `tenantIdFromQueryParams` prop + - This is used in OAuth2 + Multi-tenant flows. + - This should be safe to ignore if: + - You are not using those recipes + - You have a custom `getTenantId` implementation + - You are not customizing paths of the pages handled by SuperTokens. + - This is used to keep the `tenantId` query param during internal redirections between pages handled by the SDK. + - If you have custom paths, you should set the tenantId queryparam based on this. (See migrations below for more details) +- Added a new `shouldTryLinkingToSessionUser` flag to sign in/up related function inputs: + - No action is needed if you are not using MFA/session based account linking. + - If you are implementing MFA: + - Plase set this flag to `false` (or leave as undefined) during first factor sign-ins + - Please set this flag to `true` for secondary factors. + - Please forward this flag to the original implementation in any of your overrides. + - Changed functions: + - `EmailPassword`: + - `signIn`, `signUp`: both override and callable functions + - `ThirdParty`: + - `getAuthorisationURLWithQueryParamsAndSetState`: both override and callable function + - `redirectToThirdPartyLogin`: callable function takes this flag as an optional input (it defaults to false on the backend) + - `Passwordless`: + - Functions overrides: `consumeCode`, `resendCode`, `createCode`, `setLoginAttemptInfo`, `getLoginAttemptInfo` + - Calling `createCode` and `setLoginAttemptInfo` take this flag as an optional input (it defaults to false on the backend) +- Changed the default implementation of `getTenantId` to default to the `tenantId` query parameter (if present) then falling back to the public tenant instead of always defaulting to the public tenant +- We now disable session based account linking in the magic link based flow in passwordless by default + - This is to make it function more consistently instead of only working if the link was opened on the same device + - You can override by overriding the `consumeCode` function in the Passwordless Recipe + +### Migration + +#### tenantIdFromQueryParams in getRedirectionURL + +Before: + +```ts +EmailPassword.init({ + async getRedirectionURL(context) { + if (context.action === "RESET_PASSWORD") { + return `/reset-password`; + } + return ""; + }, +}); +``` + +After: + +```ts +EmailPassword.init({ + async getRedirectionURL(context) { + return `/reset-password?tenantId=${context.tenantIdFromQueryParams}`; + }, +}); +``` + +#### Session based account linking for magic link based flows + +You can re-enable linking by overriding the `consumeCode` function in the passwordless recipe and setting `shouldTryLinkingToSessionUser` to `true`. + +```ts +Passwordless.init({ + override: { + functions: (original) => { + return { + ...original, + consumeCode: async (input) => { + // Please note that this is means that the session is required and will cause an error if it is not present + return original.consumeCode({ ...input, shouldTryLinkingWithSessionUser: true }); + }, + }; + }, + }, +}); +``` + ## [0.47.1] - 2024-09-18 ### Fixes diff --git a/examples/for-tests/package.json b/examples/for-tests/package.json index 9f67560d0..04323793d 100644 --- a/examples/for-tests/package.json +++ b/examples/for-tests/package.json @@ -4,8 +4,10 @@ "private": true, "dependencies": { "axios": "^0.21.0", + "oidc-client-ts": "^3.0.1", "react": "^18.0.0", "react-dom": "^18.0.0", + "react-oidc-context": "^3.1.0", "react-router-dom": "6.11.2", "react-scripts": "^5.0.1" }, diff --git a/examples/for-tests/src/App.js b/examples/for-tests/src/App.js index 071ada40f..71c1d7ea3 100644 --- a/examples/for-tests/src/App.js +++ b/examples/for-tests/src/App.js @@ -14,6 +14,7 @@ import Multitenancy from "supertokens-auth-react/recipe/multitenancy"; import UserRoles from "supertokens-auth-react/recipe/userroles"; import MultiFactorAuth from "supertokens-auth-react/recipe/multifactorauth"; import TOTP from "supertokens-auth-react/recipe/totp"; +import OAuth2Provider from "supertokens-auth-react/recipe/oauth2provider"; import axios from "axios"; import { useSessionContext } from "supertokens-auth-react/recipe/session"; @@ -27,6 +28,7 @@ import { logWithPrefix } from "./logWithPrefix"; import { ErrorBoundary } from "./ErrorBoundary"; import { useNavigate } from "react-router-dom"; import { getTestContext, getEnabledRecipes, getQueryParams } from "./testContext"; +import { getApiDomain, getWebsiteDomain } from "./config"; const loadv5RRD = window.localStorage.getItem("react-router-dom-is-v5") === "true"; if (loadv5RRD) { @@ -43,18 +45,6 @@ const withRouter = function (Child) { Session.addAxiosInterceptors(axios); -export function getApiDomain() { - const apiPort = process.env.REACT_APP_API_PORT || 8082; - const apiUrl = process.env.REACT_APP_API_URL || `http://localhost:${apiPort}`; - return apiUrl; -} - -export function getWebsiteDomain() { - const websitePort = process.env.REACT_APP_WEBSITE_PORT || 3031; - const websiteUrl = process.env.REACT_APP_WEBSITE_URL || `http://localhost:${websitePort}`; - return getQueryParams("websiteDomain") ?? websiteUrl; -} - /* * Use localStorage for tests configurations. */ @@ -419,6 +409,7 @@ let recipeList = [ console.log(`ST_LOGS SESSION ON_HANDLE_EVENT ${ctx.action}`); }, }), + OAuth2Provider.init(), ]; let enabledRecipes = getEnabledRecipes(); @@ -452,6 +443,7 @@ if (testContext.enableMFA) { SuperTokens.init({ usesDynamicLoginMethods: testContext.usesDynamicLoginMethods, clientType: testContext.clientType, + enableDebugLogs: true, appInfo: { appName: "SuperTokens", websiteDomain: getWebsiteDomain(), @@ -813,7 +805,6 @@ function getSignInFormFields(formType) { id: "test", }, ]; - return; } } diff --git a/examples/for-tests/src/AppWithReactDomRouter.js b/examples/for-tests/src/AppWithReactDomRouter.js index a545bb447..9e1a664ec 100644 --- a/examples/for-tests/src/AppWithReactDomRouter.js +++ b/examples/for-tests/src/AppWithReactDomRouter.js @@ -7,11 +7,13 @@ import { EmailPasswordPreBuiltUI } from "supertokens-auth-react/recipe/emailpass import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui"; import { EmailVerificationPreBuiltUI } from "supertokens-auth-react/recipe/emailverification/prebuiltui"; import { ThirdPartyPreBuiltUI, SignInAndUpCallback } from "supertokens-auth-react/recipe/thirdparty/prebuiltui"; +import { OAuth2ProviderPreBuiltUI } from "supertokens-auth-react/recipe/oauth2provider/prebuiltui"; import { AccessDeniedScreen } from "supertokens-auth-react/recipe/session/prebuiltui"; import { MultiFactorAuthPreBuiltUI } from "supertokens-auth-react/recipe/multifactorauth/prebuiltui"; import { TOTPPreBuiltUI } from "supertokens-auth-react/recipe/totp/prebuiltui"; import { BaseComponent, Home, Contact, Dashboard, DashboardNoAuthRequired } from "./App"; import { getEnabledRecipes, getTestContext } from "./testContext"; +import OAuth2Page from "./OAuth2Page"; function AppWithReactDomRouter(props) { /** @@ -30,7 +32,7 @@ function AppWithReactDomRouter(props) { const emailVerificationMode = window.localStorage.getItem("mode") || "OFF"; const websiteBasePath = window.localStorage.getItem("websiteBasePath") || undefined; - let recipePreBuiltUIList = [TOTPPreBuiltUI]; + let recipePreBuiltUIList = [TOTPPreBuiltUI, OAuth2ProviderPreBuiltUI]; if (enabledRecipes.some((r) => r.startsWith("thirdparty"))) { recipePreBuiltUIList.push(ThirdPartyPreBuiltUI); } @@ -172,6 +174,9 @@ function AppWithReactDomRouter(props) { } /> )} + + } /> + } /> diff --git a/examples/for-tests/src/OAuth2Page.js b/examples/for-tests/src/OAuth2Page.js new file mode 100644 index 000000000..3db24f8b8 --- /dev/null +++ b/examples/for-tests/src/OAuth2Page.js @@ -0,0 +1,91 @@ +import { AuthProvider, useAuth } from "react-oidc-context"; +import { getApiDomain, getWebsiteDomain } from "./config"; + +// NOTE: For convenience, the same page/component handles both login initiation and callback. +// Separate pages for login and callback are not required. + +const scopes = window.localStorage.getItem("oauth2-scopes") ?? "profile openid offline_access email"; +const extraConfig = JSON.parse(window.localStorage.getItem("oauth2-extra-config") ?? "{}"); +const extraSignInParams = JSON.parse(window.localStorage.getItem("oauth2-extra-sign-in-params") ?? "{}"); +const extraSignOutParams = JSON.parse(window.localStorage.getItem("oauth2-extra-sign-out-params") ?? "{}"); + +const oidcConfig = { + client_id: window.localStorage.getItem("oauth2-client-id"), + authority: `${getApiDomain()}/auth`, + response_type: "code", + redirect_uri: `${getWebsiteDomain()}/oauth/callback`, + scope: scopes ? scopes : "profile openid offline_access email", + ...extraConfig, + onSigninCallback: async (user) => { + // Clears the response code and other params from the callback url + window.history.replaceState({}, document.title, window.location.pathname); + }, +}; + +function AuthPage() { + const { signinRedirect, signinSilent, signoutSilent, signoutRedirect, user, error } = useAuth(); + + return ( +
+

OAuth2 Login Test

+
+ {error &&

Error: {error.message}

} + {user && ( + <> +
{JSON.stringify(user.profile, null, 2)}
+ + + + )} + + + + + +
+
+ ); +} + +export default function OAuth2Page() { + return ( + + + + ); +} diff --git a/examples/for-tests/src/config.js b/examples/for-tests/src/config.js new file mode 100644 index 000000000..ae591c224 --- /dev/null +++ b/examples/for-tests/src/config.js @@ -0,0 +1,13 @@ +import { getQueryParams } from "./testContext"; + +export function getApiDomain() { + const apiPort = process.env.REACT_APP_API_PORT || 8082; + const apiUrl = process.env.REACT_APP_API_URL || `http://localhost:${apiPort}`; + return apiUrl; +} + +export function getWebsiteDomain() { + const websitePort = process.env.REACT_APP_WEBSITE_PORT || 3031; + const websiteUrl = process.env.REACT_APP_WEBSITE_URL || `http://localhost:${websitePort}`; + return getQueryParams("websiteDomain") ?? websiteUrl; +} diff --git a/frontendDriverInterfaceSupported.json b/frontendDriverInterfaceSupported.json index fb1c46a67..269e3d6ae 100644 --- a/frontendDriverInterfaceSupported.json +++ b/frontendDriverInterfaceSupported.json @@ -1,4 +1,4 @@ { "_comment": "contains a list of frontend-backend interface versions that this package supports", - "versions": ["2.0", "3.0"] + "versions": ["4.0"] } diff --git a/hooks/pre-commit.sh b/hooks/pre-commit.sh index 68e81428d..c78117c0a 100755 --- a/hooks/pre-commit.sh +++ b/hooks/pre-commit.sh @@ -34,7 +34,7 @@ else fi npm run check-circular-dependencies -circDep=$? +circDep=$? echo "$(tput setaf 3)* No circular dependencies?$(tput sgr 0)" diff --git a/lib/.eslintrc.js b/lib/.eslintrc.js index d7cb8d283..5f2f77fba 100644 --- a/lib/.eslintrc.js +++ b/lib/.eslintrc.js @@ -60,7 +60,10 @@ module.exports = { ], "@typescript-eslint/naming-convention": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unused-vars": [2, { vars: "all", args: "all", varsIgnorePattern: "^React$|^jsx$" }], + "@typescript-eslint/no-unused-vars": [ + 2, + { vars: "all", args: "all", varsIgnorePattern: "^React$|^jsx$", argsIgnorePattern: "^_" }, + ], "@typescript-eslint/prefer-namespace-keyword": "error", "@typescript-eslint/quotes": ["error", "double"], "@typescript-eslint/semi": ["error", "always"], diff --git a/lib/build/components/assets/logoutIcon.d.ts b/lib/build/components/assets/logoutIcon.d.ts new file mode 100644 index 000000000..4f3513ab8 --- /dev/null +++ b/lib/build/components/assets/logoutIcon.d.ts @@ -0,0 +1,2 @@ +/// +export default function LogoutIcon(): JSX.Element; diff --git a/lib/build/constants.d.ts b/lib/build/constants.d.ts index f4997a2e1..8ba89d3bd 100644 --- a/lib/build/constants.d.ts +++ b/lib/build/constants.d.ts @@ -1,4 +1,5 @@ export declare const RECIPE_ID_QUERY_PARAM = "rid"; +export declare const TENANT_ID_QUERY_PARAM = "tenantId"; export declare const DEFAULT_API_BASE_PATH = "/auth"; export declare const DEFAULT_WEBSITE_BASE_PATH = "/auth"; export declare const ST_ROOT_ID = "supertokens-root"; diff --git a/lib/build/emailpassword-shared3.js b/lib/build/emailpassword-shared3.js index 73b589369..9abb90a67 100644 --- a/lib/build/emailpassword-shared3.js +++ b/lib/build/emailpassword-shared3.js @@ -2,7 +2,6 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); var EmailPasswordWebJS = require("supertokens-web-js/recipe/emailpassword"); -var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath"); var index = require("./authRecipe-shared2.js"); var types = require("./multifactorauth-shared.js"); var constants = require("./emailpassword-shared4.js"); @@ -13,7 +12,6 @@ function _interopDefault(e) { } var EmailPasswordWebJS__default = /*#__PURE__*/ _interopDefault(EmailPasswordWebJS); -var NormalisedURLPath__default = /*#__PURE__*/ _interopDefault(NormalisedURLPath); var getFunctionOverrides = function (onHandleEvent) { return function (originalImp) { @@ -600,29 +598,21 @@ var EmailPassword = /** @class */ (function (_super) { _this.firstFactorIds = [types.FactorIds.EMAILPASSWORD]; _this.getDefaultRedirectionURL = function (context) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { - var resetPasswordPath; return genericComponentOverrideContext.__generator(this, function (_a) { if (context.action === "RESET_PASSWORD") { - resetPasswordPath = new NormalisedURLPath__default.default( - constants.DEFAULT_RESET_PASSWORD_PATH - ); return [ 2 /*return*/, - "" - .concat( - this.config.appInfo.websiteBasePath - .appendPath(resetPasswordPath) - .getAsStringDangerous(), - "?rid=" - ) - .concat(this.config.recipeId), + genericComponentOverrideContext.getDefaultRedirectionURLForPath( + this.config, + constants.DEFAULT_RESET_PASSWORD_PATH, + context + ), ]; } return [2 /*return*/, this.getAuthRecipeDefaultRedirectionURL(context)]; }); }); }; - _this.recipeID = config.recipeId; return _this; } EmailPassword.prototype.getFirstFactorsForAuthPage = function () { diff --git a/lib/build/emailpassword.js b/lib/build/emailpassword.js index 34ec5282c..d297074f3 100644 --- a/lib/build/emailpassword.js +++ b/lib/build/emailpassword.js @@ -20,6 +20,8 @@ require("./authRecipe-shared2.js"); require("./recipeModule-shared.js"); require("./multifactorauth-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./emailpassword-shared4.js"); require("./authRecipe-shared.js"); diff --git a/lib/build/emailpasswordprebuiltui.js b/lib/build/emailpasswordprebuiltui.js index f0e7253a8..7614a23e1 100644 --- a/lib/build/emailpasswordprebuiltui.js +++ b/lib/build/emailpasswordprebuiltui.js @@ -15,12 +15,12 @@ var STGeneralError = require("supertokens-web-js/utils/error"); var button = require("./emailpassword-shared.js"); var authCompWrapper = require("./authCompWrapper.js"); var emailverification = require("./emailverification.js"); -var recipe = require("./emailverification-shared.js"); +var recipe$1 = require("./emailverification-shared.js"); var session = require("./session.js"); var types = require("./multifactorauth-shared.js"); +var recipe = require("./emailpassword-shared3.js"); var STGeneralError$1 = require("supertokens-web-js/lib/build/error"); var constants = require("./emailpassword-shared4.js"); -var recipe$1 = require("./emailpassword-shared3.js"); require("supertokens-web-js"); require("supertokens-web-js/utils/cookieHandler"); require("supertokens-web-js/utils/postSuperTokensInitCallbacks"); @@ -34,6 +34,8 @@ require("./multifactorauth-shared2.js"); require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); require("./multifactorauth-shared3.js"); @@ -724,6 +726,7 @@ var SignInForm = uiEntry.withOverride("EmailPasswordSignInForm", function EmailP 4 /*yield*/, props.recipeImplementation.signIn({ formFields: formFields, + shouldTryLinkingWithSessionUser: false, userContext: userContext, }), ]; @@ -767,14 +770,14 @@ function SignInTheme(props) { ); } -function useChildProps$1(recipe$1, error, onError, clearError, userContext, navigate) { +function useChildProps$1(recipe$2, onAuthSuccess, error, onError, clearError, userContext, navigate) { var _this = this; var session$1 = uiEntry.useSessionContext(); var recipeImplementation = React.useMemo( function () { - return getModifiedRecipeImplementation$1(recipe$1.webJSRecipe); + return getModifiedRecipeImplementation$1(recipe$2.webJSRecipe); }, - [recipe$1] + [recipe$2] ); var rethrowInRender = genericComponentOverrideContext.useRethrowInRender(); var t = translationContext.useTranslation(); @@ -802,39 +805,38 @@ function useChildProps$1(recipe$1, error, onError, clearError, userContext, navi case 3: return [ 2 /*return*/, - types.Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: false, - isNewRecipeUser: false, - newSessionCreated: - session$1.loading || - !session$1.doesSessionExist || - (payloadAfterCall !== undefined && - session$1.accessTokenPayload.sessionHandle !== - payloadAfterCall.sessionHandle), - recipeId: recipe$1.recipeID, - }, - recipe$1.recipeID, - genericComponentOverrideContext.getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender), + onAuthSuccess({ + createdNewUser: false, + isNewRecipeUser: false, + newSessionCreated: + session$1.loading || + !session$1.doesSessionExist || + (payloadAfterCall !== undefined && + session$1.accessTokenPayload.sessionHandle !== + payloadAfterCall.sessionHandle), + recipeId: recipe.EmailPassword.RECIPE_ID, + }).catch(rethrowInRender), ]; } }); }); }, - [recipe$1, userContext, navigate] + [recipe$2, userContext, navigate] ); return React.useMemo( function () { var onForgotPasswordClick = function () { - return recipe$1.redirect({ action: "RESET_PASSWORD" }, navigate, undefined, userContext); + return recipe$2.redirect( + { + action: "RESET_PASSWORD", + tenantIdFromQueryParams: genericComponentOverrideContext.getTenantIdFromQueryParams(), + }, + navigate, + undefined, + userContext + ); }; - var signInAndUpFeature = recipe$1.config.signInAndUpFeature; + var signInAndUpFeature = recipe$2.config.signInAndUpFeature; var signInFeature = signInAndUpFeature.signInForm; var formFields = signInFeature.formFields.map(function (f) { return f.id !== "password" @@ -869,7 +871,7 @@ function useChildProps$1(recipe$1, error, onError, clearError, userContext, navi }); return { recipeImplementation: recipeImplementation, - config: recipe$1.config, + config: recipe$2.config, styleFromInit: signInFeature.style, formFields: formFields, error: error, @@ -906,12 +908,14 @@ function useChildProps$1(recipe$1, error, onError, clearError, userContext, navi _b.label = 2; case 2: _b.trys.push([2, 4, , 5]); - evInstance = recipe.EmailVerification.getInstanceOrThrow(); + evInstance = recipe$1.EmailVerification.getInstanceOrThrow(); return [ 4 /*yield*/, evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, navigate, undefined, @@ -936,12 +940,13 @@ function useChildProps$1(recipe$1, error, onError, clearError, userContext, navi userContext: userContext, }; }, - [recipe$1, error, userContext] + [recipe$2, error, userContext] ); } var SignInFeature = function (props) { var childProps = useChildProps$1( props.recipe, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -975,7 +980,52 @@ var SignInFeature = function (props) { ); }; var getModifiedRecipeImplementation$1 = function (origImpl) { - return genericComponentOverrideContext.__assign({}, origImpl); + return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, origImpl), { + signIn: function (input) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var response; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + origImpl.signIn( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, input), + { shouldTryLinkingWithSessionUser: false } + ) + ), + ]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); + }, + signUp: function (input) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var response; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + origImpl.signUp( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, input), + { shouldTryLinkingWithSessionUser: false } + ) + ), + ]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); + }, + }); }; var SignUpForm = uiEntry.withOverride("EmailPasswordSignUpForm", function EmailPasswordSignUpForm(props) { @@ -1016,6 +1066,7 @@ var SignUpForm = uiEntry.withOverride("EmailPasswordSignUpForm", function EmailP 4 /*yield*/, props.recipeImplementation.signUp({ formFields: formFields, + shouldTryLinkingWithSessionUser: false, userContext: userContext, }), ]; @@ -1054,14 +1105,14 @@ function SignUpTheme(props) { ); } -function useChildProps(recipe$1, error, onError, clearError, userContext, navigate) { +function useChildProps(recipe, onAuthSuccess, error, onError, clearError, userContext, navigate) { var _this = this; var session$1 = uiEntry.useSessionContext(); var recipeImplementation = React.useMemo( function () { - return recipe$1 && getModifiedRecipeImplementation(recipe$1.webJSRecipe); + return recipe && getModifiedRecipeImplementation(recipe.webJSRecipe); }, - [recipe$1] + [recipe] ); var rethrowInRender = genericComponentOverrideContext.useRethrowInRender(); var onSignUpSuccess = React.useCallback( @@ -1088,42 +1139,33 @@ function useChildProps(recipe$1, error, onError, clearError, userContext, naviga case 3: return [ 2 /*return*/, - types.Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: result.user.loginMethods.length === 1, - isNewRecipeUser: true, - newSessionCreated: - session$1.loading || - !session$1.doesSessionExist || - (payloadAfterCall !== undefined && - session$1.accessTokenPayload.sessionHandle !== - payloadAfterCall.sessionHandle), - recipeId: recipe$1.recipeID, - }, - recipe$1.recipeID, - genericComponentOverrideContext.getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender), + onAuthSuccess({ + createdNewUser: result.user.loginMethods.length === 1, + isNewRecipeUser: true, + newSessionCreated: + session$1.loading || + !session$1.doesSessionExist || + (payloadAfterCall !== undefined && + session$1.accessTokenPayload.sessionHandle !== + payloadAfterCall.sessionHandle), + recipeId: recipe.recipeID, + }).catch(rethrowInRender), ]; } }); }); }, - [recipe$1, userContext, navigate] + [recipe, userContext, navigate] ); return React.useMemo( function () { - var signInAndUpFeature = recipe$1.config.signInAndUpFeature; + var signInAndUpFeature = recipe.config.signInAndUpFeature; var signUpFeature = signInAndUpFeature.signUpForm; return { recipeImplementation: recipeImplementation, - config: recipe$1.config, + config: recipe.config, styleFromInit: signUpFeature.style, - formFields: getThemeSignUpFeatureFormFields(signUpFeature.formFields, recipe$1, userContext), + formFields: getThemeSignUpFeatureFormFields(signUpFeature.formFields, recipe, userContext), onFetchError: function (err) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { var invalidClaims, evInstance; @@ -1155,12 +1197,14 @@ function useChildProps(recipe$1, error, onError, clearError, userContext, naviga _b.label = 2; case 2: _b.trys.push([2, 4, , 5]); - evInstance = recipe.EmailVerification.getInstanceOrThrow(); + evInstance = recipe$1.EmailVerification.getInstanceOrThrow(); return [ 4 /*yield*/, evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, navigate, undefined, @@ -1187,7 +1231,7 @@ function useChildProps(recipe$1, error, onError, clearError, userContext, naviga clearError: clearError, }; }, - [recipe$1, error, userContext] + [recipe, error, userContext] ); } var SignUpFeature = function (props) { @@ -1197,6 +1241,7 @@ var SignUpFeature = function (props) { } var childProps = useChildProps( props.recipe, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -1230,7 +1275,52 @@ var SignUpFeature = function (props) { ); }; var getModifiedRecipeImplementation = function (origImpl) { - return genericComponentOverrideContext.__assign({}, origImpl); + return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, origImpl), { + signIn: function (input) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var response; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + origImpl.signIn( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, input), + { shouldTryLinkingWithSessionUser: false } + ) + ), + ]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); + }, + signUp: function (input) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var response; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + origImpl.signUp( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, input), + { shouldTryLinkingWithSessionUser: false } + ) + ), + ]; + case 1: + response = _a.sent(); + return [2 /*return*/, response]; + } + }); + }); + }, + }); }; function getThemeSignUpFeatureFormFields(formFields, recipe, userContext) { var _this = this; @@ -1322,7 +1412,7 @@ var EmailPasswordPreBuiltUI = /** @class */ (function (_super) { component: function (props) { return _this.getFeatureComponent("resetpassword", props, useComponentOverrides); }, - recipeID: recipe$1.EmailPassword.RECIPE_ID, + recipeID: recipe.EmailPassword.RECIPE_ID, }; } return features; @@ -1356,7 +1446,7 @@ var EmailPasswordPreBuiltUI = /** @class */ (function (_super) { // Static methods EmailPasswordPreBuiltUI.getInstanceOrInitAndGetInstance = function () { if (EmailPasswordPreBuiltUI.instance === undefined) { - var recipeInstance = recipe$1.EmailPassword.getInstanceOrThrow(); + var recipeInstance = recipe.EmailPassword.getInstanceOrThrow(); EmailPasswordPreBuiltUI.instance = new EmailPasswordPreBuiltUI(recipeInstance); } return EmailPasswordPreBuiltUI.instance; diff --git a/lib/build/emailverification-shared.js b/lib/build/emailverification-shared.js index e75d4a068..1c7d9189f 100644 --- a/lib/build/emailverification-shared.js +++ b/lib/build/emailverification-shared.js @@ -2,7 +2,6 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); var EmailVerificationWebJS = require("supertokens-web-js/recipe/emailverification"); -var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath"); var postSuperTokensInitCallbacks = require("supertokens-web-js/utils/postSuperTokensInitCallbacks"); var sessionClaimValidatorStore = require("supertokens-web-js/utils/sessionClaimValidatorStore"); var index = require("./recipeModule-shared.js"); @@ -12,7 +11,6 @@ function _interopDefault(e) { } var EmailVerificationWebJS__default = /*#__PURE__*/ _interopDefault(EmailVerificationWebJS); -var NormalisedURLPath__default = /*#__PURE__*/ _interopDefault(NormalisedURLPath); var _a = genericComponentOverrideContext.createGenericComponentsOverrideContext(), useContext = _a[0], @@ -55,7 +53,14 @@ var EmailVerificationClaimClass = /** @class */ (function (_super) { } var recipe = EmailVerification.getInstanceOrThrow(); if (recipe.config.mode === "REQUIRED") { - return recipe.getRedirectUrl({ action: "VERIFY_EMAIL" }, args.userContext); + return recipe.getRedirectUrl( + { + action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + }, + args.userContext + ); } return undefined; }, @@ -202,20 +207,15 @@ var EmailVerification = /** @class */ (function (_super) { _this.recipeID = EmailVerification.RECIPE_ID; _this.getDefaultRedirectionURL = function (context) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { - var verifyEmailPath; return genericComponentOverrideContext.__generator(this, function (_a) { if (context.action === "VERIFY_EMAIL") { - verifyEmailPath = new NormalisedURLPath__default.default(DEFAULT_VERIFY_EMAIL_PATH); return [ 2 /*return*/, - "" - .concat( - this.config.appInfo.websiteBasePath - .appendPath(verifyEmailPath) - .getAsStringDangerous(), - "?rid=" - ) - .concat(this.config.recipeId), + genericComponentOverrideContext.getDefaultRedirectionURLForPath( + this.config, + DEFAULT_VERIFY_EMAIL_PATH, + context + ), ]; } else { return [2 /*return*/, "/"]; diff --git a/lib/build/emailverification-shared2.js b/lib/build/emailverification-shared2.js index fe4b214a9..bfc3d9cef 100644 --- a/lib/build/emailverification-shared2.js +++ b/lib/build/emailverification-shared2.js @@ -6,7 +6,7 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext var uiEntry = require("./index2.js"); 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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n\n[data-supertokens~="inputContainer"] {\n margin-top: 6px;\n}\n\n[data-supertokens~="inputWrapper"] {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n align-items: center;\n background-color: rgb(var(--palette-inputBackground));\n height: 34px;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n}\n\n[data-supertokens~="inputWrapper"][focus-within] {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputWrapper"]:focus-within {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"][focus-within] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"]:focus-within {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="input"] {\n box-sizing: border-box;\n padding-left: 15px;\n filter: none;\n color: rgb(var(--palette-textInput));\n background-color: transparent;\n border-radius: 6px;\n font-size: var(--font-size-1);\n border: none;\n padding-right: 25px;\n letter-spacing: 1.2px;\n flex: 9 1 75%;\n width: 75%;\n height: 32px;\n}\n\n[data-supertokens~="input"]:focus {\n border: none;\n outline: none;\n}\n\n[data-supertokens~="input"]:-webkit-autofill,\n[data-supertokens~="input"]:-webkit-autofill:hover,\n[data-supertokens~="input"]:-webkit-autofill:focus,\n[data-supertokens~="input"]:-webkit-autofill:active {\n -webkit-text-fill-color: rgb(var(--palette-textInput));\n box-shadow: 0 0 0 30px rgb(var(--palette-inputBackground)) inset;\n}\n\n[data-supertokens~="inputAdornment"] {\n justify-content: center;\n margin-right: 5px;\n}\n\n[data-supertokens~="showPassword"] {\n cursor: pointer;\n}\n\n[data-supertokens~="enterEmailSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n word-break: break-word;\n}\n\n[data-supertokens~="submitNewPasswordSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n\n[data-supertokens~="inputErrorMessage"] {\n padding-top: 5px;\n padding-bottom: 5px;\n color: rgb(var(--palette-error));\n line-height: 24px;\n font-weight: 400;\n font-size: var(--font-size-1);\n text-align: left;\n animation: slideTop 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\n max-width: 330px;\n}\n\n@media (max-width: 440px) {\n [data-supertokens~="inputErrorMessage"] {\n max-width: 250px;\n }\n}\n\n[data-supertokens~="inputErrorSymbol"] {\n margin-right: 5px;\n top: 1px;\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="label"] {\n text-align: left;\n font-weight: 700;\n font-size: var(--font-size-0);\n line-height: 24px;\n color: rgb(var(--palette-textLabel));\n}\n\n[data-supertokens~="formRow"] {\n display: flex;\n flex-direction: column;\n padding-top: 0px;\n padding-bottom: 20px;\n}\n\n[data-supertokens~="formRow"][data-supertokens~="hasError"] {\n padding-bottom: 0;\n}\n\n[data-supertokens~="formRow"]:last-child {\n padding-bottom: 0;\n}\n\n[data-supertokens~="sendVerifyEmailIcon"] {\n margin-top: 11px;\n}\n\n[data-supertokens~="primaryText"][data-supertokens~="sendVerifyEmailText"] {\n text-align: center;\n letter-spacing: 0.8px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n font-weight: 700;\n}\n\n[data-supertokens~="sendVerifyEmailResend"] {\n margin-top: 13px;\n font-weight: 400;\n}\n\n[data-supertokens~="sendVerifyEmailResend"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="noFormRow"] {\n padding-bottom: 25px;\n}\n\n[data-supertokens~="emailVerificationButtonWrapper"] {\n padding-top: 25px;\n max-width: 96px;\n margin: 0 auto;\n}\n\n[data-supertokens~="resendEmailLink"] {\n display: inline-block;\n}\n\n[data-supertokens~="resetPasswordEmailForm"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="resetPasswordPasswordForm"] {\n padding-bottom: 20px;\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n\n[data-supertokens~="inputContainer"] {\n margin-top: 6px;\n}\n\n[data-supertokens~="inputWrapper"] {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n align-items: center;\n background-color: rgb(var(--palette-inputBackground));\n height: 34px;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n}\n\n[data-supertokens~="inputWrapper"][focus-within] {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputWrapper"]:focus-within {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"][focus-within] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"]:focus-within {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="input"] {\n box-sizing: border-box;\n padding-left: 15px;\n filter: none;\n color: rgb(var(--palette-textInput));\n background-color: transparent;\n border-radius: 6px;\n font-size: var(--font-size-1);\n border: none;\n padding-right: 25px;\n letter-spacing: 1.2px;\n flex: 9 1 75%;\n width: 75%;\n height: 32px;\n}\n\n[data-supertokens~="input"]:focus {\n border: none;\n outline: none;\n}\n\n[data-supertokens~="input"]:-webkit-autofill,\n[data-supertokens~="input"]:-webkit-autofill:hover,\n[data-supertokens~="input"]:-webkit-autofill:focus,\n[data-supertokens~="input"]:-webkit-autofill:active {\n -webkit-text-fill-color: rgb(var(--palette-textInput));\n box-shadow: 0 0 0 30px rgb(var(--palette-inputBackground)) inset;\n}\n\n[data-supertokens~="inputAdornment"] {\n justify-content: center;\n margin-right: 5px;\n}\n\n[data-supertokens~="showPassword"] {\n cursor: pointer;\n}\n\n[data-supertokens~="enterEmailSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n word-break: break-word;\n}\n\n[data-supertokens~="submitNewPasswordSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n\n[data-supertokens~="inputErrorMessage"] {\n padding-top: 5px;\n padding-bottom: 5px;\n color: rgb(var(--palette-error));\n line-height: 24px;\n font-weight: 400;\n font-size: var(--font-size-1);\n text-align: left;\n animation: slideTop 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\n max-width: 330px;\n}\n\n@media (max-width: 440px) {\n [data-supertokens~="inputErrorMessage"] {\n max-width: 250px;\n }\n}\n\n[data-supertokens~="inputErrorSymbol"] {\n margin-right: 5px;\n top: 1px;\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="label"] {\n text-align: left;\n font-weight: 700;\n font-size: var(--font-size-0);\n line-height: 24px;\n color: rgb(var(--palette-textLabel));\n}\n\n[data-supertokens~="formRow"] {\n display: flex;\n flex-direction: column;\n padding-top: 0px;\n padding-bottom: 20px;\n}\n\n[data-supertokens~="formRow"][data-supertokens~="hasError"] {\n padding-bottom: 0;\n}\n\n[data-supertokens~="formRow"]:last-child {\n padding-bottom: 0;\n}\n\n[data-supertokens~="sendVerifyEmailIcon"] {\n margin-top: 11px;\n}\n\n[data-supertokens~="primaryText"][data-supertokens~="sendVerifyEmailText"] {\n text-align: center;\n letter-spacing: 0.8px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n font-weight: 700;\n}\n\n[data-supertokens~="sendVerifyEmailResend"] {\n margin-top: 13px;\n font-weight: 400;\n}\n\n[data-supertokens~="sendVerifyEmailResend"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="noFormRow"] {\n padding-bottom: 25px;\n}\n\n[data-supertokens~="emailVerificationButtonWrapper"] {\n padding-top: 25px;\n max-width: 96px;\n margin: 0 auto;\n}\n\n[data-supertokens~="resendEmailLink"] {\n display: inline-block;\n}\n\n[data-supertokens~="resetPasswordEmailForm"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="resetPasswordPasswordForm"] {\n padding-bottom: 20px;\n}\n'; var ThemeBase = function (_a) { var children = _a.children, diff --git a/lib/build/emailverificationprebuiltui.js b/lib/build/emailverificationprebuiltui.js index c52942f44..abfc568bc 100644 --- a/lib/build/emailverificationprebuiltui.js +++ b/lib/build/emailverificationprebuiltui.js @@ -26,6 +26,8 @@ require("./multifactorauth-shared2.js"); require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); require("supertokens-web-js/recipe/session"); diff --git a/lib/build/genericComponentOverrideContext.js b/lib/build/genericComponentOverrideContext.js index 6ff313470..9f8c18ad7 100644 --- a/lib/build/genericComponentOverrideContext.js +++ b/lib/build/genericComponentOverrideContext.js @@ -245,6 +245,7 @@ typeof SuppressedError === "function" * Consts. */ var RECIPE_ID_QUERY_PARAM = "rid"; +var TENANT_ID_QUERY_PARAM = "tenantId"; var DEFAULT_API_BASE_PATH = "/auth"; var DEFAULT_WEBSITE_BASE_PATH = "/auth"; var ST_ROOT_ID = "supertokens-root"; @@ -265,7 +266,7 @@ var SSR_ERROR = * License for the specific language governing permissions and limitations * under the License. */ -var package_version = "0.47.1"; +var package_version = "0.49.0"; /* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved. * @@ -389,6 +390,32 @@ function getRedirectToPathFromURL() { } } } +function getTenantIdFromQueryParams() { + var _a; + return (_a = getQueryParams(TENANT_ID_QUERY_PARAM)) !== null && _a !== void 0 ? _a : undefined; +} +function getDefaultRedirectionURLForPath(config, defaultPath, context, extraQueryParams) { + var redirectPath = config.appInfo.websiteBasePath + .appendPath(new NormalisedURLPath__default.default(defaultPath)) + .getAsStringDangerous(); + var queryParams = new URLSearchParams(); + if (context.tenantIdFromQueryParams !== undefined) { + queryParams.set(TENANT_ID_QUERY_PARAM, context.tenantIdFromQueryParams); + } + if (extraQueryParams !== undefined) { + Object.entries(extraQueryParams).forEach(function (_a) { + var key = _a[0], + value = _a[1]; + if (value !== undefined) { + queryParams.set(key, value); + } + }); + } + if (queryParams.toString() !== "") { + return "".concat(redirectPath, "?").concat(queryParams.toString()); + } + return redirectPath; +} /* * isTest */ @@ -1220,6 +1247,7 @@ var SuperTokens = /** @class */ (function () { { action: "TO_AUTH", showSignIn: options.show === "signin", + tenantIdFromQueryParams: getTenantIdFromQueryParams(), }, options.userContext ), @@ -1359,22 +1387,33 @@ var SuperTokens = /** @class */ (function () { SuperTokens.prototype.getRedirectUrl = function (context, userContext) { var _a; return __awaiter(this, void 0, void 0, function () { - var userRes, redirectUrl; - return __generator(this, function (_b) { - switch (_b.label) { + var userRes, redirectUrl, basePath; + var _b; + return __generator(this, function (_c) { + switch (_c.label) { case 0: if (!this.userGetRedirectionURL) return [3 /*break*/, 2]; return [4 /*yield*/, this.userGetRedirectionURL(context, userContext)]; case 1: - userRes = _b.sent(); + userRes = _c.sent(); if (userRes !== undefined) { return [2 /*return*/, userRes]; } - _b.label = 2; + _c.label = 2; case 2: if (context.action === "TO_AUTH") { redirectUrl = this.appInfo.websiteBasePath.getAsStringDangerous(); - return [2 /*return*/, appendTrailingSlashToURL(redirectUrl)]; + basePath = appendTrailingSlashToURL(redirectUrl); + if (context.tenantIdFromQueryParams) { + return [ + 2 /*return*/, + appendQueryParamsToURL( + basePath, + ((_b = {}), (_b[TENANT_ID_QUERY_PARAM] = context.tenantIdFromQueryParams), _b) + ), + ]; + } + return [2 /*return*/, basePath]; } else if (context.action === "SUCCESS") { return [2 /*return*/, (_a = context.redirectToPath) !== null && _a !== void 0 ? _a : "/"]; } @@ -1450,10 +1489,12 @@ exports.createGenericComponentsOverrideContext = createGenericComponentsOverride exports.getCurrentLanguageFromCookie = getCurrentLanguageFromCookie; exports.getCurrentNormalisedUrlPath = getCurrentNormalisedUrlPath; exports.getCurrentNormalisedUrlPathWithQueryParamsAndFragments = getCurrentNormalisedUrlPathWithQueryParamsAndFragments; +exports.getDefaultRedirectionURLForPath = getDefaultRedirectionURLForPath; exports.getLocalStorage = getLocalStorage; exports.getNormalisedUserContext = getNormalisedUserContext; exports.getQueryParams = getQueryParams; exports.getRedirectToPathFromURL = getRedirectToPathFromURL; +exports.getTenantIdFromQueryParams = getTenantIdFromQueryParams; exports.getURLHash = getURLHash; exports.isTest = isTest; exports.logDebugMessage = logDebugMessage; diff --git a/lib/build/index.js b/lib/build/index.js index 3df5aed90..b2a26c6c8 100644 --- a/lib/build/index.js +++ b/lib/build/index.js @@ -23,6 +23,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); require("./multifactorauth-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); diff --git a/lib/build/index2.js b/lib/build/index2.js index bf0faa82a..bc16a1368 100644 --- a/lib/build/index2.js +++ b/lib/build/index2.js @@ -8,8 +8,9 @@ var translationContext = require("./translationContext.js"); var windowHandler = require("supertokens-web-js/utils/windowHandler"); var reactDom = require("react-dom"); var componentOverrideContext = require("./multitenancy-shared.js"); -var recipe = require("./multifactorauth-shared2.js"); +var recipe$1 = require("./multifactorauth-shared2.js"); var types = require("./multifactorauth-shared.js"); +var recipe = require("./oauth2provider-shared.js"); var utils = require("./authRecipe-shared.js"); var NormalisedURLPath$1 = require("supertokens-web-js/lib/build/normalisedURLPath"); @@ -120,7 +121,7 @@ var withOverride = function (overrideKey, DefaultComponent) { }; var styles$1 = - '[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n'; var ThemeBase$1 = function (_a) { var children = _a.children, @@ -354,6 +355,7 @@ var defaultTranslationsCommon = { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: "Sign Up / Sign In", AUTH_PAGE_HEADER_TITLE_SIGN_IN: "Sign In", AUTH_PAGE_HEADER_TITLE_SIGN_UP: "Sign Up", + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: " to continue to ", AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: "Not registered yet?", AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: "Sign Up", AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: "", @@ -459,7 +461,7 @@ function GeneralError(_a) { } var styles = - '[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n'; var ThemeBase = function (_a) { var children = _a.children, @@ -628,10 +630,17 @@ var AuthPageHeader = withOverride("AuthPageHeader", function AuthPageHeader(_a) hasSeparateSignUpView = _a.hasSeparateSignUpView, isSignUp = _a.isSignUp, showBackButton = _a.showBackButton, - resetFactorList = _a.resetFactorList; + resetFactorList = _a.resetFactorList, + oauth2ClientInfo = _a.oauth2ClientInfo; var t = translationContext.useTranslation(); return jsxRuntime.jsxs(React.Fragment, { children: [ + (oauth2ClientInfo === null || oauth2ClientInfo === void 0 ? void 0 : oauth2ClientInfo.logoUri) && + jsxRuntime.jsx("img", { + src: oauth2ClientInfo.logoUri, + alt: oauth2ClientInfo.clientName, + "data-supertokens": "authPageTitleOAuthClientLogo", + }), jsxRuntime.jsxs( "div", genericComponentOverrideContext.__assign( @@ -653,6 +662,38 @@ var AuthPageHeader = withOverride("AuthPageHeader", function AuthPageHeader(_a) } ) ), + oauth2ClientInfo && + oauth2ClientInfo.clientName !== undefined && + oauth2ClientInfo.clientName.length > 0 && + jsxRuntime.jsxs( + "div", + genericComponentOverrideContext.__assign( + { "data-supertokens": "authPageTitleOAuthClient" }, + { + children: [ + t("AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP"), + oauth2ClientInfo.clientUri !== undefined + ? jsxRuntime.jsx( + "a", + genericComponentOverrideContext.__assign( + { + "data-supertokens": "authPageTitleOAuthClientUrl link", + href: oauth2ClientInfo.clientUri, + }, + { children: oauth2ClientInfo.clientName } + ) + ) + : jsxRuntime.jsx( + "span", + genericComponentOverrideContext.__assign( + { "data-supertokens": "authPageTitleOAuthClientName" }, + { children: oauth2ClientInfo.clientName } + ) + ), + ], + } + ) + ), hasSeparateSignUpView && (!isSignUp ? jsxRuntime.jsxs( @@ -731,6 +772,7 @@ function AuthPageTheme(props) { hasSeparateSignUpView: props.hasSeparateSignUpView, resetFactorList: props.resetFactorList, showBackButton: props.showBackButton, + oauth2ClientInfo: props.oauth2ClientInfo, }), props.error !== undefined && jsxRuntime.jsx(GeneralError, { error: props.error }), jsxRuntime.jsx( @@ -836,33 +878,38 @@ var AuthPageInner = function (props) { : undefined; var showStringFromQSRef = React.useRef(showStringFromQS); var errorFromQSRef = React.useRef(errorFromQS); + var loginChallenge = search.get("loginChallenge"); + var forceFreshAuth = search.get("forceFreshAuth") === "true"; var sessionContext = useSessionContext(); var userContext = useUserContext(); var rethrowInRender = genericComponentOverrideContext.useRethrowInRender(); var _f = React.useState(undefined), loadedDynamicLoginMethods = _f[0], setLoadedDynamicLoginMethods = _f[1]; - var _g = React.useState(errorFromQS), - error = _g[0], - setError = _g[1]; - var _h = React.useState(false), - sessionLoadedAndNotRedirecting = _h[0], - setSessionLoadedAndNotRedirecting = _h[1]; + var _g = React.useState(undefined), + oauth2ClientInfo = _g[0], + setOAuth2ClientInfo = _g[1]; + var _h = React.useState(errorFromQS), + error = _h[0], + setError = _h[1]; + var _j = React.useState(false), + sessionLoadedAndNotRedirecting = _j[0], + setSessionLoadedAndNotRedirecting = _j[1]; var st = genericComponentOverrideContext.SuperTokens.getInstanceOrThrow(); - var _j = React.useState(props.factors), - factorList = _j[0], - setFactorList = _j[1]; - var _k = React.useState( + var _k = React.useState(props.factors), + factorList = _k[0], + setFactorList = _k[1]; + var _l = React.useState( (_e = (_d = props.isSignUp) !== null && _d !== void 0 ? _d : isSignUpFromQS) !== null && _e !== void 0 ? _e : st.defaultToSignUp ), - isSignUp = _k[0], - setIsSignUp = _k[1]; + isSignUp = _l[0], + setIsSignUp = _l[1]; // We use this to signal that we need to update the components we show on screen - var _l = React.useState(0), - rebuildReqCount = _l[0], - setRebuildReqCount = _l[1]; + var _m = React.useState(0), + rebuildReqCount = _m[0], + setRebuildReqCount = _m[1]; var lastBuild = React.useRef({ buildReq: undefined }); React.useEffect(function () { if (props.useSignUpStateFromQueryString && showStringFromQSRef.current !== showStringFromQS) { @@ -918,6 +965,46 @@ var AuthPageInner = function (props) { }, [loadedDynamicLoginMethods, setLoadedDynamicLoginMethods] ); + genericComponentOverrideContext.useOnMountAPICall( + function () { + return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () { + var oauth2Recipe; + return genericComponentOverrideContext.__generator(this, function (_a) { + if (oauth2ClientInfo) { + return [2 /*return*/]; + } + oauth2Recipe = recipe.OAuth2Provider.getInstance(); + if (oauth2Recipe !== undefined && loginChallenge !== null) { + return [ + 2 /*return*/, + oauth2Recipe.webJSRecipe.getLoginChallengeInfo({ + loginChallenge: loginChallenge, + userContext: userContext, + }), + ]; + } + return [2 /*return*/, undefined]; + }); + }); + }, + function (info) { + return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () { + return genericComponentOverrideContext.__generator(this, function (_a) { + if (info !== undefined) { + if (info.status === "OK") { + setOAuth2ClientInfo(info.info); + } else { + setError("SOMETHING_WENT_WRONG_ERROR"); + } + } + return [2 /*return*/]; + }); + }); + }, + function () { + return genericComponentOverrideContext.clearQueryParams(["loginChallenge"]); + } + ); React.useEffect( function () { if (sessionLoadedAndNotRedirecting) { @@ -930,19 +1017,64 @@ var AuthPageInner = function (props) { if (sessionContext.doesSessionExist) { if (props.onSessionAlreadyExists !== undefined) { props.onSessionAlreadyExists(); - } else if (props.redirectOnSessionExists !== false) { + } else if (props.redirectOnSessionExists !== false && !forceFreshAuth) { types.Session.getInstanceOrThrow().config.onHandleEvent({ action: "SESSION_ALREADY_EXISTS", }); - void types.Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - undefined, - types.Session.RECIPE_ID, // TODO - genericComponentOverrideContext.getRedirectToPathFromURL(), - userContext, - props.navigate - ) - .catch(rethrowInRender); + var oauth2Recipe_1 = recipe.OAuth2Provider.getInstance(); + if (loginChallenge !== null && oauth2Recipe_1 !== undefined) { + (function () { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var frontendRedirectTo; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + oauth2Recipe_1.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge: loginChallenge, + userContext: userContext, + }), + ]; + case 1: + frontendRedirectTo = _a.sent().frontendRedirectTo; + return [ + 2 /*return*/, + types.Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + { + // We get here if the user was redirected to the auth screen with an already existing session + // and a loginChallenge (we check the forceFreshAuth queryparam above) + action: "SUCCESS_OAUTH2", + frontendRedirectTo: frontendRedirectTo, + // We can use these defaults, since this is not the result of a sign in/up call + createdNewUser: false, + isNewRecipeUser: false, + newSessionCreated: false, + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + recipeId: types.Session.RECIPE_ID, + }, + types.Session.RECIPE_ID, + genericComponentOverrideContext.getRedirectToPathFromURL(), + userContext, + props.navigate + ), + ]; + } + }); + }); + })().catch(rethrowInRender); + } else { + void types.Session.getInstanceOrThrow() + .validateGlobalClaimsAndHandleSuccessRedirection( + undefined, + types.Session.RECIPE_ID, + genericComponentOverrideContext.getRedirectToPathFromURL(), + userContext, + props.navigate + ) + .catch(rethrowInRender); + } } else { setSessionLoadedAndNotRedirecting(true); } @@ -953,9 +1085,9 @@ var AuthPageInner = function (props) { }, [sessionContext.loading] ); - var _m = React.useState(), - authComponentListInfo = _m[0], - setAuthComponentListInfo = _m[1]; + var _o = React.useState(), + authComponentListInfo = _o[0], + setAuthComponentListInfo = _o[1]; var showUseAnotherLink = factorList !== undefined && (props.factors === undefined || @@ -1005,11 +1137,76 @@ var AuthPageInner = function (props) { rethrowInRender, ] ); + var onAuthSuccess = React.useCallback( + function (ctx) { + return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () { + var oauth2Recipe, frontendRedirectTo; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + oauth2Recipe = recipe.OAuth2Provider.getInstance(); + if (loginChallenge === null || oauth2Recipe === undefined) { + return [ + 2 /*return*/, + types.Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, ctx), + { + action: "SUCCESS", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + redirectToPath: + genericComponentOverrideContext.getRedirectToPathFromURL(), + } + ), + ctx.recipeId, + genericComponentOverrideContext.getRedirectToPathFromURL(), + userContext, + props.navigate + ), + ]; + } + return [ + 4 /*yield*/, + oauth2Recipe.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge: loginChallenge, + userContext: userContext, + }), + ]; + case 1: + frontendRedirectTo = _a.sent().frontendRedirectTo; + return [ + 2 /*return*/, + types.Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, ctx), + { + action: "SUCCESS_OAUTH2", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + frontendRedirectTo: frontendRedirectTo, + } + ), + ctx.recipeId, + genericComponentOverrideContext.getRedirectToPathFromURL(), + userContext, + props.navigate + ), + ]; + } + }); + }); + }, + [loginChallenge] + ); var childProps = - authComponentListInfo !== undefined + authComponentListInfo !== undefined && + (loginChallenge === null || oauth2ClientInfo !== undefined || recipe.OAuth2Provider.getInstance() === undefined) ? genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, authComponentListInfo), { + oauth2ClientInfo: oauth2ClientInfo, + onAuthSuccess: onAuthSuccess, error: error, onError: function (err) { setError(err); @@ -1166,7 +1363,7 @@ function buildAndSetChildProps( ? void 0 : loadedDynamicLoginMethods.firstFactors) !== null && _a !== void 0 ? _a - : (_b = recipe.MultiFactorAuth.getInstance()) === null || _b === void 0 + : (_b = recipe$1.MultiFactorAuth.getInstance()) === null || _b === void 0 ? void 0 : _b.config.firstFactors) !== null && _c !== void 0 ? _c @@ -1182,7 +1379,7 @@ function buildAndSetChildProps( (loadedDynamicLoginMethods === null || loadedDynamicLoginMethods === void 0 ? void 0 : loadedDynamicLoginMethods.firstFactors) === undefined && - ((_d = recipe.MultiFactorAuth.getInstance()) === null || _d === void 0 + ((_d = recipe$1.MultiFactorAuth.getInstance()) === null || _d === void 0 ? void 0 : _d.config.firstFactors) === undefined ) { @@ -1318,7 +1515,7 @@ function buildAndSetChildProps( ? void 0 : loadedDynamicLoginMethods.firstFactors) !== undefined ? "dynamic tenant configuration" - : ((_e = recipe.MultiFactorAuth.getInstance()) === null || _e === void 0 + : ((_e = recipe$1.MultiFactorAuth.getInstance()) === null || _e === void 0 ? void 0 : _e.config.firstFactors) !== undefined ? "the config passed to the MFA recipe" @@ -1613,7 +1810,7 @@ var RecipeRouter = /** @class */ (function () { if (defaultToStaticList) { return defaultComp; } - var mfaRecipe = recipe.MultiFactorAuth.getInstance(); + var mfaRecipe = recipe$1.MultiFactorAuth.getInstance(); if (genericComponentOverrideContext.SuperTokens.usesDynamicLoginMethods === false) { // If we are not using dynamic login methods, we can use the rid requested by the app if (componentMatchingRid) { @@ -2566,6 +2763,7 @@ exports.AuthPageHeader = AuthPageHeader; exports.AuthPageTheme = AuthPageTheme; exports.BackButton = BackButton; exports.ComponentOverrideContext = ComponentOverrideContext; +exports.DynamicLoginMethodsSpinner = DynamicLoginMethodsSpinner; exports.FeatureWrapper = FeatureWrapper; exports.GeneralError = GeneralError; exports.Provider = Provider; diff --git a/lib/build/multifactorauth-shared.js b/lib/build/multifactorauth-shared.js index dcbacf133..7b88f6acf 100644 --- a/lib/build/multifactorauth-shared.js +++ b/lib/build/multifactorauth-shared.js @@ -2,6 +2,7 @@ var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); var WebJSSessionRecipe = require("supertokens-web-js/recipe/session"); +var recipe = require("./oauth2provider-shared.js"); var index = require("./recipeModule-shared.js"); var utils = require("supertokens-web-js/utils"); var windowHandler = require("supertokens-web-js/utils/windowHandler"); @@ -350,13 +351,25 @@ var Session = /** @class */ (function (_super) { createdNewUser: false, isNewRecipeUser: false, newSessionCreated: false, + tenantIdFromQueryParams: genericComponentOverrideContext.getTenantIdFromQueryParams(), }; _a.label = 13; case 13: if (successRedirectContext === undefined) { throw new Error("This should never happen: successRedirectContext undefined "); } - if (redirectToPath !== undefined) { + if (successRedirectContext.action === "SUCCESS_OAUTH2") { + return [ + 2 /*return*/, + recipe.OAuth2Provider.getInstanceOrThrow().redirect( + successRedirectContext, + navigate, + {}, + userContext + ), + ]; + } + if (successRedirectContext.action === "SUCCESS" && redirectToPath !== undefined) { successRedirectContext.redirectToPath = redirectToPath; } return [ @@ -379,6 +392,7 @@ var Session = /** @class */ (function (_super) { _this.getDefaultRedirectionURL = function () { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { return genericComponentOverrideContext.__generator(this, function (_a) { + // We do not use the util here, since we are redirecting outside of the SDK routes return [2 /*return*/, "/"]; }); }); diff --git a/lib/build/multifactorauth-shared2.js b/lib/build/multifactorauth-shared2.js index 708a9f1e9..d5e65825c 100644 --- a/lib/build/multifactorauth-shared2.js +++ b/lib/build/multifactorauth-shared2.js @@ -3,7 +3,6 @@ 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"); var windowHandler = require("supertokens-web-js/utils/windowHandler"); @@ -15,7 +14,6 @@ function _interopDefault(e) { } var MultiFactorAuthWebJS__default = /*#__PURE__*/ _interopDefault(MultiFactorAuthWebJS); -var NormalisedURLPath__default = /*#__PURE__*/ _interopDefault(NormalisedURLPath); /* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved. * @@ -349,6 +347,23 @@ function normaliseMultiFactorAuthFeature(config) { ); } function getAvailableFactors(factors, nextArrayQueryParam, recipe, userContext) { + genericComponentOverrideContext.logDebugMessage( + "getAvailableFactors: allowed to setup: ".concat(factors.allowedToSetup) + ); + genericComponentOverrideContext.logDebugMessage( + "getAvailableFactors: already setup: ".concat(factors.alreadySetup) + ); + genericComponentOverrideContext.logDebugMessage("getAvailableFactors: next from factorInfo: ".concat(factors.next)); + genericComponentOverrideContext.logDebugMessage( + "getAvailableFactors: nextArrayQueryParam: ".concat(nextArrayQueryParam) + ); + genericComponentOverrideContext.logDebugMessage( + "getAvailableFactors: secondary factors: ".concat( + recipe.getSecondaryFactors(userContext).map(function (f) { + return f.id; + }) + ) + ); // There are 3 cases here: // 1. The app provided an array of factors to show (nextArrayQueryParam) -> we show whatever is in the array // 2. no app provided list and validator passed -> we show all factors available to set up or complete @@ -389,41 +404,42 @@ var MultiFactorAuth = /** @class */ (function (_super) { _this.secondaryFactors = []; _this.getDefaultRedirectionURL = function (context, userContext) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { - var chooserPath, url, queryParams, redirectInfo, url, queryParams; + var nParam, redirectInfo; return genericComponentOverrideContext.__generator(this, function (_b) { if (context.action === "FACTOR_CHOOSER") { - chooserPath = new NormalisedURLPath__default.default(DEFAULT_FACTOR_CHOOSER_PATH); - url = this.config.appInfo.websiteBasePath.appendPath(chooserPath).getAsStringDangerous(); - queryParams = new URLSearchParams(); - if (context.nextFactorOptions && context.nextFactorOptions.length > 0) { - queryParams.set("n", context.nextFactorOptions.join(",")); - } - if (context.stepUp) { - queryParams.set("stepUp", "true"); - } - if (queryParams.toString() !== "") { - url += "?" + queryParams.toString(); - } - return [2 /*return*/, url]; + nParam = + context.nextFactorOptions && context.nextFactorOptions.length > 0 + ? context.nextFactorOptions.join(",") + : undefined; + return [ + 2 /*return*/, + genericComponentOverrideContext.getDefaultRedirectionURLForPath( + this.config, + DEFAULT_FACTOR_CHOOSER_PATH, + context, + { + n: nParam, + stepUp: context.stepUp ? "true" : undefined, + } + ), + ]; } else if (context.action === "GO_TO_FACTOR") { redirectInfo = this.getSecondaryFactors(userContext).find(function (f) { return f.id === context.factorId; }); if (redirectInfo !== undefined) { - url = this.config.appInfo.websiteBasePath - .appendPath(new NormalisedURLPath__default.default(redirectInfo.path)) - .getAsStringDangerous(); - queryParams = new URLSearchParams(); - if (context.forceSetup) { - queryParams.set("setup", "true"); - } - if (context.stepUp) { - queryParams.set("stepUp", "true"); - } - if (queryParams.toString() !== "") { - url += "?" + queryParams.toString(); - } - return [2 /*return*/, url]; + return [ + 2 /*return*/, + genericComponentOverrideContext.getDefaultRedirectionURLForPath( + this.config, + redirectInfo.path, + context, + { + setup: context.forceSetup ? "true" : undefined, + stepUp: context.stepUp ? "true" : undefined, + } + ), + ]; } throw new Error("Requested redirect to unknown factor id: " + context.factorId); } else { @@ -526,7 +542,14 @@ var MultiFactorAuth = /** @class */ (function (_super) { return [ 4 /*yield*/, this.getRedirectUrl( - { action: "GO_TO_FACTOR", forceSetup: forceSetup, stepUp: stepUp, factorId: factorId }, + { + action: "GO_TO_FACTOR", + forceSetup: forceSetup, + stepUp: stepUp, + factorId: factorId, + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + }, utils.getNormalisedUserContext(userContext) ), ]; @@ -587,7 +610,13 @@ var MultiFactorAuth = /** @class */ (function (_super) { return [ 4 /*yield*/, this.getRedirectUrl( - { action: "FACTOR_CHOOSER", nextFactorOptions: nextFactorOptions, stepUp: stepUp }, + { + action: "FACTOR_CHOOSER", + nextFactorOptions: nextFactorOptions, + stepUp: stepUp, + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + }, utils.getNormalisedUserContext(userContext) ), ]; @@ -643,7 +672,19 @@ var MultiFactorAuth = /** @class */ (function (_super) { return genericComponentOverrideContext.__generator(_a, function (_b) { switch (_b.label) { case 0: - return [4 /*yield*/, this.getInstanceOrThrow().getRedirectUrl(context, userContext)]; + return [ + 4 /*yield*/, + this.getInstanceOrThrow().getRedirectUrl( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, context), + { + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + } + ), + userContext + ), + ]; case 1: return [2 /*return*/, _b.sent() || undefined]; } diff --git a/lib/build/multifactorauth.js b/lib/build/multifactorauth.js index ab535c278..c837953b2 100644 --- a/lib/build/multifactorauth.js +++ b/lib/build/multifactorauth.js @@ -20,6 +20,8 @@ require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); /* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved. * diff --git a/lib/build/multifactorauthprebuiltui.js b/lib/build/multifactorauthprebuiltui.js index 83d04b517..7685444ea 100644 --- a/lib/build/multifactorauthprebuiltui.js +++ b/lib/build/multifactorauthprebuiltui.js @@ -21,11 +21,13 @@ require("supertokens-web-js/utils"); require("supertokens-web-js/utils/normalisedURLDomain"); require("react-dom"); require("./multitenancy-shared.js"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); +require("./recipeModule-shared.js"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); require("supertokens-web-js/recipe/session"); require("./session-shared.js"); -require("./recipeModule-shared.js"); require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); @@ -63,7 +65,7 @@ var NormalisedURLPath__default = /*#__PURE__*/ _interopDefault(NormalisedURLPath var React__namespace = /*#__PURE__*/ _interopNamespace(React); var styles = - '[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n[data-supertokens~="mfa"][data-supertokens~="container"] {\n padding-top: 34px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="row"] {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="headerTitle"] {\n font-size: var(--font-size-3);\n font-weight: 600;\n line-height: 30px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="factorChooserList"] {\n margin-bottom: 12px;\n}\n[data-supertokens~="factorChooserOption"] {\n display: flex;\n flex-direction: row;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n padding: 20px 16px;\n cursor: pointer;\n margin-top: 12px;\n}\n[data-supertokens~="factorChooserOption"]:hover {\n border: 1px solid rgba(var(--palette-primary), 0.6);\n}\n[data-supertokens~="factorOptionText"] {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n align-items: start;\n text-align: left;\n}\n[data-supertokens~="factorLogo"] {\n flex-grow: 0;\n min-width: 30px;\n text-align: left;\n margin-top: 6px;\n}\n[data-supertokens~="totp"] [data-supertokens~="factorLogo"] {\n margin-top: 3px;\n margin-left: -1px;\n}\n[data-supertokens~="factorName"] {\n color: rgb(var(--palette-primary));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 4px;\n}\n[data-supertokens~="factorDescription"] {\n color: rgb(var(--palette-textPrimary));\n font-size: var(--font-size-0);\n margin: 4px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n margin-bottom: 26px;\n text-align: right;\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n[data-supertokens~="mfa"][data-supertokens~="container"] {\n padding-top: 34px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="row"] {\n padding-top: 6px;\n padding-bottom: 6px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="headerTitle"] {\n font-size: var(--font-size-3);\n font-weight: 600;\n line-height: 30px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="factorChooserList"] {\n margin-bottom: 12px;\n}\n[data-supertokens~="factorChooserOption"] {\n display: flex;\n flex-direction: row;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n padding: 20px 16px;\n cursor: pointer;\n margin-top: 12px;\n}\n[data-supertokens~="factorChooserOption"]:hover {\n border: 1px solid rgba(var(--palette-primary), 0.6);\n}\n[data-supertokens~="factorOptionText"] {\n flex-grow: 1;\n display: flex;\n flex-direction: column;\n align-items: start;\n text-align: left;\n}\n[data-supertokens~="factorLogo"] {\n flex-grow: 0;\n min-width: 30px;\n text-align: left;\n margin-top: 6px;\n}\n[data-supertokens~="totp"] [data-supertokens~="factorLogo"] {\n margin-top: 3px;\n margin-left: -1px;\n}\n[data-supertokens~="factorName"] {\n color: rgb(var(--palette-primary));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 4px;\n}\n[data-supertokens~="factorDescription"] {\n color: rgb(var(--palette-textPrimary));\n font-size: var(--font-size-0);\n margin: 4px;\n}\n[data-supertokens~="mfa"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n margin-bottom: 26px;\n text-align: right;\n}\n'; var ThemeBase = function (_a) { var children = _a.children, diff --git a/lib/build/oauth2provider-shared.js b/lib/build/oauth2provider-shared.js new file mode 100644 index 000000000..27f1e02ea --- /dev/null +++ b/lib/build/oauth2provider-shared.js @@ -0,0 +1,197 @@ +"use strict"; + +var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); +var OAuth2WebJS = require("supertokens-web-js/recipe/oauth2provider"); +var index = require("./recipeModule-shared.js"); + +function _interopDefault(e) { + return e && e.__esModule ? e : { default: e }; +} + +var OAuth2WebJS__default = /*#__PURE__*/ _interopDefault(OAuth2WebJS); + +var getFunctionOverrides = function (onHandleEvent) { + return function (originalImp) { + return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, originalImp), { + getLoginChallengeInfo: function (input) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var response; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [4 /*yield*/, originalImp.getLoginChallengeInfo(input)]; + case 1: + response = _a.sent(); + onHandleEvent({ + action: "LOADED_LOGIN_CHALLENGE", + loginChallenge: input.loginChallenge, + loginInfo: response.info, + userContext: input.userContext, + }); + return [2 /*return*/, response]; + } + }); + }); + }, + logOut: function (input) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var response; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [4 /*yield*/, originalImp.logOut(input)]; + case 1: + response = _a.sent(); + onHandleEvent({ + action: "OAUTH2_LOGOUT_SUCCESS", + frontendRedirectTo: response.frontendRedirectTo, + userContext: input.userContext, + }); + return [2 /*return*/, response]; + } + }); + }); + }, + }); + }; +}; + +function normaliseOAuth2Config(config) { + var _a; + return genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign( + {}, + genericComponentOverrideContext.normaliseRecipeModuleConfig(config) + ), + { + disableDefaultUI: + (_a = config === null || config === void 0 ? void 0 : config.disableDefaultUI) !== null && _a !== void 0 + ? _a + : false, + tryRefreshPage: genericComponentOverrideContext.__assign( + { disableDefaultUI: false }, + config === null || config === void 0 ? void 0 : config.tryRefreshPage + ), + oauth2LogoutScreen: genericComponentOverrideContext.__assign( + { disableDefaultUI: false, style: "" }, + config === null || config === void 0 ? void 0 : config.oauth2LogoutScreen + ), + override: genericComponentOverrideContext.__assign( + { + functions: function (originalImplementation) { + return originalImplementation; + }, + }, + config === null || config === void 0 ? void 0 : config.override + ), + } + ); +} + +/* Copyright (c) 2024, 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. + */ +/* + * Class. + */ +var OAuth2Provider = /** @class */ (function (_super) { + genericComponentOverrideContext.__extends(OAuth2Provider, _super); + function OAuth2Provider(config, webJSRecipe) { + if (webJSRecipe === void 0) { + webJSRecipe = OAuth2WebJS__default.default; + } + var _this = _super.call(this, config) || this; + _this.webJSRecipe = webJSRecipe; + _this.recipeID = OAuth2Provider.RECIPE_ID; + return _this; + } + OAuth2Provider.init = function (config) { + var normalisedConfig = normaliseOAuth2Config(config); + return { + recipeID: OAuth2Provider.RECIPE_ID, + authReact: function (appInfo) { + OAuth2Provider.instance = new OAuth2Provider( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, normalisedConfig), + { appInfo: appInfo, recipeId: OAuth2Provider.RECIPE_ID } + ) + ); + return OAuth2Provider.instance; + }, + webJS: OAuth2WebJS__default.default.init( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, normalisedConfig), + { + override: { + functions: function (originalImpl, builder) { + var functions = getFunctionOverrides(normalisedConfig.onHandleEvent); + builder.override(functions); + builder.override(normalisedConfig.override.functions); + return originalImpl; + }, + }, + } + ) + ), + }; + }; + OAuth2Provider.getInstanceOrThrow = function () { + if (OAuth2Provider.instance === undefined) { + var error = + "No instance of OAuth2Provider found. Make sure to call the OAuth2Provider.init method." + + "See https://supertokens.io/docs/oauth2/quick-setup/frontend"; + // eslint-disable-next-line supertokens-auth-react/no-direct-window-object + if (typeof window === "undefined") { + error = error + genericComponentOverrideContext.SSR_ERROR; + } + throw Error(error); + } + return OAuth2Provider.instance; + }; + OAuth2Provider.getInstance = function () { + return OAuth2Provider.instance; + }; + OAuth2Provider.prototype.getDefaultRedirectionURL = function (ctx) { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + return genericComponentOverrideContext.__generator(this, function (_a) { + // We do not use the util here, because we are likely redirecting across domains here. + if ( + ctx.action === "SUCCESS_OAUTH2" || + ctx.action === "CONTINUE_OAUTH2_AFTER_REFRESH" || + ctx.action === "POST_OAUTH2_LOGOUT_REDIRECT" + ) { + return [2 /*return*/, ctx.frontendRedirectTo]; + } else { + throw new Error( + "Should never come here: unknown action in OAuth2Provider.getDefaultRedirectionURL" + ); + } + }); + }); + }; + /* + * Tests methods. + */ + OAuth2Provider.reset = function () { + if (!genericComponentOverrideContext.isTest()) { + return; + } + OAuth2Provider.instance = undefined; + return; + }; + OAuth2Provider.RECIPE_ID = "oauth2provider"; + return OAuth2Provider; +})(index.RecipeModule); + +exports.OAuth2Provider = OAuth2Provider; diff --git a/lib/build/oauth2provider-shared2.js b/lib/build/oauth2provider-shared2.js new file mode 100644 index 000000000..bd3b554b5 --- /dev/null +++ b/lib/build/oauth2provider-shared2.js @@ -0,0 +1,10 @@ +"use strict"; + +var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); + +var _a = genericComponentOverrideContext.createGenericComponentsOverrideContext(), + useContext = _a[0], + Provider = _a[1]; + +exports.Provider = Provider; +exports.useContext = useContext; diff --git a/lib/build/oauth2provider.js b/lib/build/oauth2provider.js new file mode 100644 index 000000000..aee148ac4 --- /dev/null +++ b/lib/build/oauth2provider.js @@ -0,0 +1,99 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); + +var componentOverrideContext = require("./oauth2provider-shared2.js"); +var recipe = require("./oauth2provider-shared.js"); +require("./genericComponentOverrideContext.js"); +require("supertokens-web-js"); +require("supertokens-web-js/utils/cookieHandler"); +require("supertokens-web-js/utils/postSuperTokensInitCallbacks"); +require("supertokens-web-js/utils/windowHandler"); +require("supertokens-web-js/recipe/multitenancy"); +require("supertokens-web-js/utils"); +require("react"); +require("supertokens-web-js/utils/normalisedURLDomain"); +require("supertokens-web-js/utils/normalisedURLPath"); +require("react/jsx-runtime"); +require("supertokens-web-js/recipe/oauth2provider"); +require("./recipeModule-shared.js"); + +/* Copyright (c) 2024, 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 Wrapper = /** @class */ (function () { + function Wrapper() {} + Wrapper.init = function (config) { + return recipe.OAuth2Provider.init(config); + }; + /** + * Returns information about an OAuth login in progress + * + * @param loginChallenge The login challenge from the url + * + * @param userContext (OPTIONAL) Refer to {@link https://supertokens.com/docs/emailpassword/advanced-customizations/user-context the documentation} + * + * @param options (OPTIONAL) Use this to configure additional properties (for example pre api hooks) + * + * @returns `{status: "OK", info: LoginInfo}` + * + * @throws STGeneralError if the API exposed by the backend SDKs returns `status: "GENERAL_ERROR"` + */ + Wrapper.getLoginChallengeInfo = function (input) { + return recipe.OAuth2Provider.getInstanceOrThrow().webJSRecipe.getLoginChallengeInfo(input); + }; + /** + * Accepts the OAuth2 Login request and returns the redirect URL to continue the OAuth flow. + * + * @param loginChallenge The login challenge from the url + * + * @param userContext (OPTIONAL) Refer to {@link https://supertokens.com/docs/emailpassword/advanced-customizations/user-context the documentation} + * + * @param options (OPTIONAL) Use this to configure additional properties (for example pre api hooks) + * + * @returns `{status: "OK", frontendRedirectTo: string}` + * + * @throws STGeneralError if the API exposed by the backend SDKs returns `status: "GENERAL_ERROR"` + */ + Wrapper.getRedirectURLToContinueOAuthFlow = function (input) { + return recipe.OAuth2Provider.getInstanceOrThrow().webJSRecipe.getRedirectURLToContinueOAuthFlow(input); + }; + /** + * Accepts the OAuth2 Logout request, clears the SuperTokens session and returns post logout redirect URL. + * + * @param logoutChallenge The logout challenge from the url + * + * @param userContext (OPTIONAL) Refer to {@link https://supertokens.com/docs/emailpassword/advanced-customizations/user-context the documentation} + * + * @param options (OPTIONAL) Use this to configure additional properties (for example pre api hooks) + * + * @returns `{status: "OK", frontendRedirectTo: string}` + * + * @throws STGeneralError if the API exposed by the backend SDKs returns `status: "GENERAL_ERROR"` + */ + Wrapper.logOut = function (input) { + return recipe.OAuth2Provider.getInstanceOrThrow().webJSRecipe.logOut(input); + }; + Wrapper.ComponentsOverrideProvider = componentOverrideContext.Provider; + return Wrapper; +})(); +var init = Wrapper.init; +var getLoginChallengeInfo = Wrapper.getLoginChallengeInfo; +var logOut = Wrapper.logOut; + +exports.RecipeComponentsOverrideContextProvider = componentOverrideContext.Provider; +exports.default = Wrapper; +exports.getLoginChallengeInfo = getLoginChallengeInfo; +exports.init = init; +exports.logOut = logOut; diff --git a/lib/build/oauth2providerprebuiltui.js b/lib/build/oauth2providerprebuiltui.js new file mode 100644 index 000000000..dca66706f --- /dev/null +++ b/lib/build/oauth2providerprebuiltui.js @@ -0,0 +1,616 @@ +"use strict"; + +var genericComponentOverrideContext = require("./genericComponentOverrideContext.js"); +var jsxRuntime = require("react/jsx-runtime"); +var NormalisedURLPath = require("supertokens-web-js/utils/normalisedURLPath"); +var uiEntry = require("./index2.js"); +var session = require("./session.js"); +var componentOverrideContext = require("./oauth2provider-shared2.js"); +var React = require("react"); +var recipe = require("./oauth2provider-shared.js"); +var translationContext = require("./translationContext.js"); +var button = require("./emailpassword-shared.js"); +require("supertokens-web-js"); +require("supertokens-web-js/utils/cookieHandler"); +require("supertokens-web-js/utils/postSuperTokensInitCallbacks"); +require("supertokens-web-js/utils/windowHandler"); +require("supertokens-web-js/recipe/multitenancy"); +require("supertokens-web-js/utils"); +require("supertokens-web-js/utils/normalisedURLDomain"); +require("react-dom"); +require("./multitenancy-shared.js"); +require("./multifactorauth-shared2.js"); +require("supertokens-web-js/recipe/multifactorauth"); +require("supertokens-web-js/utils/sessionClaimValidatorStore"); +require("./recipeModule-shared.js"); +require("./multifactorauth-shared.js"); +require("supertokens-web-js/recipe/session"); +require("./authRecipe-shared.js"); +require("supertokens-web-js/lib/build/normalisedURLPath"); +require("./session-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); + +function _interopDefault(e) { + return e && e.__esModule ? e : { default: e }; +} + +function _interopNamespace(e) { + if (e && e.__esModule) return e; + var n = Object.create(null); + if (e) { + Object.keys(e).forEach(function (k) { + if (k !== "default") { + var d = Object.getOwnPropertyDescriptor(e, k); + Object.defineProperty( + n, + k, + d.get + ? d + : { + enumerable: true, + get: function () { + return e[k]; + }, + } + ); + } + }); + } + n.default = e; + return Object.freeze(n); +} + +var NormalisedURLPath__default = /*#__PURE__*/ _interopDefault(NormalisedURLPath); +var React__namespace = /*#__PURE__*/ _interopNamespace(React); + +var styles = + '/* Copyright (c) 2024, 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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n\n[data-supertokens~="logoutIcon"] {\n padding: 18px 20px 18px 24px;\n background-color: rgba(var(--palette-textGray), 0.1);\n border-radius: 12px;\n}\n\n[data-supertokens~="oauth2Logout"] [data-supertokens~="headerTitle"] {\n margin-top: 24px;\n margin-bottom: 24px;\n}\n\n[data-supertokens~="oauth2Logout"] [data-supertokens~="button"] {\n margin-bottom: 24px;\n}\n'; + +var ThemeBase = function (_a) { + var children = _a.children, + userStyles = _a.userStyles; + return jsxRuntime.jsxs(React.Fragment, { + children: [children, jsxRuntime.jsxs("style", { children: [styles, userStyles.join("\n")] })], + }); +}; + +/* Copyright (c) 2024, 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. + */ +function LogoutIcon() { + return jsxRuntime.jsx( + "svg", + genericComponentOverrideContext.__assign( + { + "data-supertokens": "logoutIcon", + xmlns: "http://www.w3.org/2000/svg", + width: "40", + height: "38", + fill: "none", + }, + { + children: jsxRuntime.jsx("path", { + fill: "rgb(var(--palette-textGray))", + "fill-rule": "evenodd", + d: "M2.972.022a.874.874 0 0 1-.23.062c-.234.042-.926.362-1.148.53a4.638 4.638 0 0 0-.656.63c-.178.228-.415.681-.495.948l-.116.378C.272 2.742.27 32.075.326 32.251l.111.37c.165.559.636 1.207 1.133 1.558a3.9 3.9 0 0 1 .195.145c.048.046.368.206.588.292l.196.08c.036.016.183.063.326.105.144.042.295.093.337.113.041.02.11.037.154.037s.098.015.12.034c.023.019.218.087.434.15.215.065.43.133.478.153.048.019.254.085.457.146.204.06.404.128.446.148.041.021.11.038.154.038s.098.015.12.034c.023.02.16.069.303.11.144.041.295.092.337.112.041.02.11.037.154.037s.098.015.12.034c.023.018.218.086.434.15.215.065.43.133.478.152.048.02.254.086.457.148.204.062.404.129.446.148a.45.45 0 0 0 .163.037c.048 0 .088.018.088.041 0 .023.034.043.076.043.042 0 .213.048.38.104.168.057.34.104.381.104.042 0 .076.02.076.042 0 .023.04.042.088.042.048 0 .122.017.163.038.042.02.193.07.337.11.274.076.366.106.544.176.06.024.285.096.5.16.216.064.41.132.433.15a.224.224 0 0 0 .12.035.4.4 0 0 1 .155.04c.042.02.193.07.337.108.144.038.3.084.348.103.178.07.613.125.954.122.365-.004.908-.078.965-.133a.16.16 0 0 1 .096-.031c.08 0 .707-.291.784-.364.032-.03.073-.054.09-.054.053 0 .632-.55.748-.71.195-.27.432-.71.432-.803 0-.04.02-.083.044-.097.024-.014.043-.077.043-.14 0-.063.023-.137.05-.163.034-.033.059-.404.077-1.148l.026-1.1 2.894-.023c2.31-.02 2.939-.037 3.119-.084.123-.033.24-.074.257-.091.018-.017.077-.031.132-.031.054 0 .11-.02.125-.042.015-.023.055-.042.089-.042.19 0 1.14-.54 1.493-.849.456-.398.898-.926 1.095-1.304a.916.916 0 0 1 .088-.147c.02-.018.06-.104.219-.48.02-.047.059-.16.088-.252.029-.091.069-.214.09-.271.125-.356.146-.97.146-4.265 0-3.563-.003-3.626-.205-3.987-.204-.364-.756-.78-1.036-.78-.045 0-.093-.019-.108-.042-.035-.054-.661-.054-.696 0-.015.023-.066.042-.113.042-.256 0-.85.449-1.002.757-.253.514-.256.568-.256 4.24v3.287l-.11.222c-.06.123-.186.306-.28.408-.171.188-.551.41-.7.41-.044 0-.092.02-.107.042-.018.027-.943.042-2.635.042h-2.608l-.011-12.165c-.01-9.665-.023-12.176-.066-12.218a.236.236 0 0 1-.055-.149.426.426 0 0 0-.039-.169 4.357 4.357 0 0 1-.118-.26c-.201-.477-.692-1.057-1.127-1.332a2.216 2.216 0 0 1-.196-.134c-.054-.058-.664-.307-.848-.346-.048-.01 1.66-.021 3.795-.024 2.546-.003 3.89.01 3.908.037.015.023.064.042.11.042.19 0 .646.313.82.561.274.39.267.31.267 3.032 0 2.402.02 2.851.14 3.139.245.59.71.966 1.318 1.068.33.055.642.012.979-.134.242-.105.696-.489.696-.588 0-.03.015-.054.033-.054.042 0 .166-.305.213-.522.058-.272.046-5.251-.015-5.666a4.778 4.778 0 0 0-.27-1.066 9.014 9.014 0 0 0-.397-.773 2.902 2.902 0 0 1-.161-.23 3.223 3.223 0 0 0-.298-.377 7.831 7.831 0 0 1-.23-.25c-.149-.175-.564-.502-.91-.717a5.197 5.197 0 0 0-.38-.224c-.011 0-.133-.05-.271-.11a4.346 4.346 0 0 0-.98-.319C22.442.018 3.025-.029 2.973.022Zm28.17 7.903c-.364.092-.514.172-.764.407-.225.21-.38.445-.487.737-.04.11-.054.77-.055 2.645v2.498h-3.457c-2.258 0-3.467.015-3.485.042-.014.023-.063.042-.107.042-.138 0-.449.18-.655.379-.194.187-.38.497-.474.794-.06.187-.062.653-.004.687.024.015.044.06.044.102 0 .17.198.495.443.724.141.132.285.24.32.24.035 0 .063.02.063.042 0 .023.036.042.08.042.044 0 .094.014.111.03.125.12.504.134 3.78.136l3.34.001.014 2.52c.015 2.39.032 2.79.122 2.79.021 0 .039.038.039.084 0 .046.02.084.043.084.024 0 .044.026.044.058 0 .073.476.527.552.527.032 0 .057.016.057.036 0 .02.108.069.24.109.35.106 1.009.076 1.305-.059.175-.08.895-.75 3.656-3.406 1.89-1.82 3.487-3.373 3.548-3.454.278-.37.388-.944.256-1.342-.15-.456-.165-.47-3.737-3.915-1.915-1.846-3.511-3.356-3.547-3.356-.037 0-.067-.014-.067-.031 0-.074-.636-.261-.87-.256-.06.001-.217.03-.349.063Z", + "clip-rule": "evenodd", + }), + } + ) + ); +} + +var OAuth2LogoutScreenInner = uiEntry.withOverride("OAuth2LogoutScreenInner", function OAuth2LogoutScreenInner(props) { + var t = translationContext.useTranslation(); + return jsxRuntime.jsxs(jsxRuntime.Fragment, { + children: [ + jsxRuntime.jsx(LogoutIcon, {}), + jsxRuntime.jsx( + "div", + genericComponentOverrideContext.__assign( + { "data-supertokens": "headerTitle" }, + { children: t("LOGGING_OUT") } + ) + ), + jsxRuntime.jsx( + "div", + genericComponentOverrideContext.__assign( + { "data-supertokens": "headerSubtitle" }, + { children: t("LOGOUT_CONFIRMATION") } + ) + ), + jsxRuntime.jsx("div", { "data-supertokens": "divider" }), + jsxRuntime.jsx(button.Button, { + disabled: props.isLoggingOut, + isLoading: props.isLoggingOut, + type: "button", + label: t("LOGOUT"), + onClick: props.onLogoutClicked, + }), + ], + }); +}); + +var OAuth2LogoutScreen$1 = function (props) { + if (props.showSpinner) { + return jsxRuntime.jsx(uiEntry.DynamicLoginMethodsSpinner, {}); + } + return jsxRuntime.jsxs( + "div", + genericComponentOverrideContext.__assign( + { "data-supertokens": "oauth2Logout container" }, + { + children: [ + jsxRuntime.jsx( + "div", + genericComponentOverrideContext.__assign( + { "data-supertokens": "row" }, + { + children: jsxRuntime.jsx(OAuth2LogoutScreenInner, { + isLoggingOut: props.isLoggingOut, + onLogoutClicked: props.onLogoutClicked, + }), + } + ) + ), + jsxRuntime.jsx(uiEntry.SuperTokensBranding, {}), + ], + } + ) + ); +}; +var OAuth2LogoutScreenTheme = function (props) { + var rootStyle = genericComponentOverrideContext.SuperTokens.getInstanceOrThrow().rootStyle; + return jsxRuntime.jsx( + ThemeBase, + genericComponentOverrideContext.__assign( + { userStyles: [rootStyle, props.config.recipeRootStyle, props.config.oauth2LogoutScreen.style] }, + { children: jsxRuntime.jsx(OAuth2LogoutScreen$1, genericComponentOverrideContext.__assign({}, props)) } + ) + ); +}; + +var defaultTranslationsOAuth2Provider = { + en: genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, uiEntry.defaultTranslationsCommon.en), + { LOGGING_OUT: "Logging Out", LOGOUT_CONFIRMATION: "Are you sure you want to log out?", LOGOUT: "LOG OUT" } + ), +}; + +var OAuth2LogoutScreen = function (props) { + var _a, _b, _c; + var rethrowInRender = genericComponentOverrideContext.useRethrowInRender(); + var sessionContext = React__namespace.useContext(uiEntry.SessionContext); + var _d = React__namespace.useState(false), + isLoggingOut = _d[0], + setIsLoggingOut = _d[1]; + var recipeComponentOverrides = props.useComponentOverrides(); + var userContext = uiEntry.useUserContext(); + if (props.userContext !== undefined) { + userContext = props.userContext; + } + var logoutChallenge = + (_a = genericComponentOverrideContext.getQueryParams("logoutChallenge")) !== null && _a !== void 0 + ? _a + : undefined; + var navigate = + (_b = props.navigate) !== null && _b !== void 0 + ? _b + : (_c = uiEntry.UI.getReactRouterDomWithCustomHistory()) === null || _c === void 0 + ? void 0 + : _c.useHistoryCustom(); + var onLogout = React__namespace.useCallback( + function () { + return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () { + var frontendRedirectTo, err_1; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + if (logoutChallenge === undefined) { + return [2 /*return*/]; + } + setIsLoggingOut(true); + _a.label = 1; + case 1: + _a.trys.push([1, 4, , 5]); + return [ + 4 /*yield*/, + recipe.OAuth2Provider.getInstanceOrThrow().webJSRecipe.logOut({ + logoutChallenge: logoutChallenge, + userContext: userContext, + }), + ]; + case 2: + frontendRedirectTo = _a.sent().frontendRedirectTo; + return [ + 4 /*yield*/, + props.recipe.redirect( + { + recipeId: "oauth2provider", + action: "POST_OAUTH2_LOGOUT_REDIRECT", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + frontendRedirectTo: frontendRedirectTo, + }, + navigate, + {}, + userContext + ), + ]; + case 3: + _a.sent(); + return [3 /*break*/, 5]; + case 4: + err_1 = _a.sent(); + rethrowInRender(err_1); + return [3 /*break*/, 5]; + case 5: + return [2 /*return*/]; + } + }); + }); + }, + [logoutChallenge, navigate, props.recipe, userContext, rethrowInRender] + ); + React__namespace.useEffect( + function () { + // We wait for session loading to finish + if (sessionContext.loading === false) { + // Redirect to the auth page if there is no logoutChallenge + if (logoutChallenge === undefined) { + void genericComponentOverrideContext.SuperTokens.getInstanceOrThrow() + .redirectToAuth({ + userContext: userContext, + redirectBack: false, + }) + .catch(rethrowInRender); + } else { + // Call logOut directly if there is no session + if (sessionContext.doesSessionExist === false) { + void onLogout(); + } + } + } + }, + [userContext, logoutChallenge, sessionContext, onLogout] + ); + var childProps = { + config: props.recipe.config, + showSpinner: sessionContext.loading || sessionContext.doesSessionExist === false, + onLogoutClicked: onLogout, + isLoggingOut: isLoggingOut, + }; + if (logoutChallenge === undefined) { + return null; + } + return jsxRuntime.jsx( + uiEntry.ComponentOverrideContext.Provider, + genericComponentOverrideContext.__assign( + { value: recipeComponentOverrides }, + { + children: jsxRuntime.jsx( + uiEntry.FeatureWrapper, + genericComponentOverrideContext.__assign( + { + useShadowDom: genericComponentOverrideContext.SuperTokens.getInstanceOrThrow().useShadowDom, + defaultStore: defaultTranslationsOAuth2Provider, + }, + { + children: jsxRuntime.jsxs(React.Fragment, { + children: [ + props.children === undefined && + jsxRuntime.jsx( + OAuth2LogoutScreenTheme, + genericComponentOverrideContext.__assign({}, childProps) + ), + props.children && + React__namespace.Children.map(props.children, function (child) { + if (React__namespace.isValidElement(child)) { + return React__namespace.cloneElement(child, childProps); + } + return child; + }), + ], + }), + } + ) + ), + } + ) + ); +}; + +var TryRefreshPage$1 = function (props) { + var _a; + var rethrowInRender = genericComponentOverrideContext.useRethrowInRender(); + var sessionContext = React.useContext(uiEntry.SessionContext); + var loginChallenge = + (_a = genericComponentOverrideContext.getQueryParams("loginChallenge")) !== null && _a !== void 0 + ? _a + : undefined; + var userContext = uiEntry.useUserContext(); + if (props.userContext !== undefined) { + userContext = props.userContext; + } + React__namespace.useEffect( + function () { + if (sessionContext.loading === false) { + if (loginChallenge) { + (function () { + return genericComponentOverrideContext.__awaiter(this, void 0, void 0, function () { + var frontendRedirectTo; + return genericComponentOverrideContext.__generator(this, function (_a) { + switch (_a.label) { + case 0: + return [ + 4 /*yield*/, + props.recipe.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge: loginChallenge, + userContext: userContext, + }), + ]; + case 1: + frontendRedirectTo = _a.sent().frontendRedirectTo; + return [ + 2 /*return*/, + props.recipe.redirect( + { + action: "CONTINUE_OAUTH2_AFTER_REFRESH", + frontendRedirectTo: frontendRedirectTo, + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), + recipeId: "oauth2provider", + }, + props.navigate, + {}, + userContext + ), + ]; + } + }); + }); + })().catch(rethrowInRender); + } else { + void genericComponentOverrideContext.SuperTokens.getInstanceOrThrow() + .redirectToAuth({ + userContext: userContext, + redirectBack: false, + }) + .catch(rethrowInRender); + } + } + }, + [loginChallenge, props.recipe, props.navigate, userContext, sessionContext] + ); + var childProps = { + config: props.recipe.config, + }; + return jsxRuntime.jsx( + uiEntry.FeatureWrapper, + genericComponentOverrideContext.__assign( + { + useShadowDom: genericComponentOverrideContext.SuperTokens.getInstanceOrThrow().useShadowDom, + defaultStore: defaultTranslationsOAuth2Provider, + }, + { + children: jsxRuntime.jsxs(React.Fragment, { + children: [ + props.children === undefined && jsxRuntime.jsx(uiEntry.DynamicLoginMethodsSpinner, {}), + props.children && + React__namespace.Children.map(props.children, function (child) { + if (React__namespace.isValidElement(child)) { + return React__namespace.cloneElement(child, childProps); + } + return child; + }), + ], + }), + } + ) + ); +}; + +/* Copyright (c) 2024, 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 DEFAULT_TRY_REFRESH_PATH = "/try-refresh"; +var DEFAULT_OAUTH2_LOGOUT_PATH = "/oauth/logout"; + +var OAuth2ProviderPreBuiltUI = /** @class */ (function (_super) { + genericComponentOverrideContext.__extends(OAuth2ProviderPreBuiltUI, _super); + function OAuth2ProviderPreBuiltUI(recipeInstance) { + var _this = _super.call(this) || this; + _this.recipeInstance = recipeInstance; + _this.languageTranslations = defaultTranslationsOAuth2Provider; + // Instance methods + _this.getFeatures = function (useComponentOverrides) { + if (useComponentOverrides === void 0) { + useComponentOverrides = componentOverrideContext.useContext; + } + if (_this.recipeInstance.config.disableDefaultUI) { + return {}; + } + var features = {}; + if (_this.recipeInstance.config.tryRefreshPage.disableDefaultUI !== true) { + var normalisedFullPath = _this.recipeInstance.config.appInfo.websiteBasePath.appendPath( + new NormalisedURLPath__default.default(DEFAULT_TRY_REFRESH_PATH) + ); + features[normalisedFullPath.getAsStringDangerous()] = { + matches: genericComponentOverrideContext.matchRecipeIdUsingQueryParams( + _this.recipeInstance.config.recipeId + ), + component: function (props) { + return _this.getFeatureComponent("try-refresh-page", props, useComponentOverrides); + }, + recipeID: recipe.OAuth2Provider.RECIPE_ID, + }; + } + if (_this.recipeInstance.config.oauth2LogoutScreen.disableDefaultUI !== true) { + var normalisedFullPath = _this.recipeInstance.config.appInfo.websiteBasePath.appendPath( + new NormalisedURLPath__default.default(DEFAULT_OAUTH2_LOGOUT_PATH) + ); + features[normalisedFullPath.getAsStringDangerous()] = { + matches: genericComponentOverrideContext.matchRecipeIdUsingQueryParams( + _this.recipeInstance.config.recipeId + ), + component: function (props) { + return _this.getFeatureComponent("oauth2-logout-screen", props, useComponentOverrides); + }, + recipeID: recipe.OAuth2Provider.RECIPE_ID, + }; + } + return features; + }; + _this.getFeatureComponent = function ( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + componentName, + props, + useComponentOverrides + ) { + if (useComponentOverrides === void 0) { + useComponentOverrides = componentOverrideContext.useContext; + } + if (componentName === "try-refresh-page") { + return jsxRuntime.jsx( + uiEntry.UserContextWrapper, + genericComponentOverrideContext.__assign( + { userContext: props.userContext }, + { + children: jsxRuntime.jsx( + session.SessionAuth, + genericComponentOverrideContext.__assign( + { + requireAuth: false, + overrideGlobalClaimValidators: function () { + return []; + }, + }, + { + children: jsxRuntime.jsx( + TryRefreshPage$1, + genericComponentOverrideContext.__assign( + { + recipe: _this.recipeInstance, + useComponentOverrides: useComponentOverrides, + }, + props + ) + ), + } + ) + ), + } + ) + ); + } else if (componentName === "oauth2-logout-screen") { + return jsxRuntime.jsx( + uiEntry.UserContextWrapper, + genericComponentOverrideContext.__assign( + { userContext: props.userContext }, + { + children: jsxRuntime.jsx( + session.SessionAuth, + genericComponentOverrideContext.__assign( + { + requireAuth: false, + overrideGlobalClaimValidators: function () { + return []; + }, + }, + { + children: jsxRuntime.jsx( + OAuth2LogoutScreen, + genericComponentOverrideContext.__assign( + { + recipe: _this.recipeInstance, + useComponentOverrides: useComponentOverrides, + }, + props + ) + ), + } + ) + ), + } + ) + ); + } + throw new Error("Should never come here."); + }; + return _this; + } + // Static methods + OAuth2ProviderPreBuiltUI.getInstanceOrInitAndGetInstance = function () { + if (OAuth2ProviderPreBuiltUI.instance === undefined) { + var recipeInstance = recipe.OAuth2Provider.getInstanceOrThrow(); + OAuth2ProviderPreBuiltUI.instance = new OAuth2ProviderPreBuiltUI(recipeInstance); + } + return OAuth2ProviderPreBuiltUI.instance; + }; + OAuth2ProviderPreBuiltUI.getFeatures = function (useComponentOverrides) { + if (useComponentOverrides === void 0) { + useComponentOverrides = componentOverrideContext.useContext; + } + return OAuth2ProviderPreBuiltUI.getInstanceOrInitAndGetInstance().getFeatures(useComponentOverrides); + }; + OAuth2ProviderPreBuiltUI.getFeatureComponent = function (componentName, props, useComponentOverrides) { + if (useComponentOverrides === void 0) { + useComponentOverrides = componentOverrideContext.useContext; + } + return OAuth2ProviderPreBuiltUI.getInstanceOrInitAndGetInstance().getFeatureComponent( + componentName, + props, + useComponentOverrides + ); + }; + OAuth2ProviderPreBuiltUI.prototype.getAuthComponents = function () { + return []; + }; + // For tests + OAuth2ProviderPreBuiltUI.reset = function () { + if (!genericComponentOverrideContext.isTest()) { + return; + } + OAuth2ProviderPreBuiltUI.instance = undefined; + return; + }; + OAuth2ProviderPreBuiltUI.TryRefreshPage = function (props) { + return OAuth2ProviderPreBuiltUI.getInstanceOrInitAndGetInstance().getFeatureComponent( + "try-refresh-page", + props + ); + }; + OAuth2ProviderPreBuiltUI.OAuth2LogoutScreen = function (props) { + return OAuth2ProviderPreBuiltUI.getInstanceOrInitAndGetInstance().getFeatureComponent( + "oauth2-logout-screen", + props + ); + }; + return OAuth2ProviderPreBuiltUI; +})(uiEntry.RecipeRouter); +var TryRefreshPage = OAuth2ProviderPreBuiltUI.TryRefreshPage; + +exports.OAuth2ProviderPreBuiltUI = OAuth2ProviderPreBuiltUI; +exports.TryRefreshPage = TryRefreshPage; diff --git a/lib/build/passwordless.js b/lib/build/passwordless.js index da90f1017..1b2c514be 100644 --- a/lib/build/passwordless.js +++ b/lib/build/passwordless.js @@ -19,6 +19,8 @@ require("./authRecipe-shared2.js"); require("./recipeModule-shared.js"); require("./multifactorauth-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./multifactorauth-shared2.js"); require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); diff --git a/lib/build/passwordlessprebuiltui.js b/lib/build/passwordlessprebuiltui.js index 74352f7a8..1d2c93364 100644 --- a/lib/build/passwordlessprebuiltui.js +++ b/lib/build/passwordlessprebuiltui.js @@ -31,11 +31,13 @@ require("supertokens-web-js/utils"); require("supertokens-web-js/utils/normalisedURLDomain"); require("react-dom"); require("./multitenancy-shared.js"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); +require("./recipeModule-shared.js"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); require("supertokens-web-js/recipe/emailpassword"); require("./authRecipe-shared2.js"); -require("./recipeModule-shared.js"); require("./emailpassword-shared4.js"); require("./multifactorauth-shared3.js"); require("supertokens-web-js/recipe/session"); @@ -81,7 +83,7 @@ var STGeneralError__default = /*#__PURE__*/ _interopDefault(STGeneralError); var STGeneralError__default$1 = /*#__PURE__*/ _interopDefault(STGeneralError$1); 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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\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~="inputContainer"] {\n margin-top: 6px;\n}\n\n[data-supertokens~="inputWrapper"] {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n align-items: center;\n background-color: rgb(var(--palette-inputBackground));\n height: 34px;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n}\n\n[data-supertokens~="inputWrapper"][focus-within] {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputWrapper"]:focus-within {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"][focus-within] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"]:focus-within {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="input"] {\n box-sizing: border-box;\n padding-left: 15px;\n filter: none;\n color: rgb(var(--palette-textInput));\n background-color: transparent;\n border-radius: 6px;\n font-size: var(--font-size-1);\n border: none;\n padding-right: 25px;\n letter-spacing: 1.2px;\n flex: 9 1 75%;\n width: 75%;\n height: 32px;\n}\n\n[data-supertokens~="input"]:focus {\n border: none;\n outline: none;\n}\n\n[data-supertokens~="input"]:-webkit-autofill,\n[data-supertokens~="input"]:-webkit-autofill:hover,\n[data-supertokens~="input"]:-webkit-autofill:focus,\n[data-supertokens~="input"]:-webkit-autofill:active {\n -webkit-text-fill-color: rgb(var(--palette-textInput));\n box-shadow: 0 0 0 30px rgb(var(--palette-inputBackground)) inset;\n}\n\n[data-supertokens~="inputAdornment"] {\n justify-content: center;\n margin-right: 5px;\n}\n\n[data-supertokens~="showPassword"] {\n cursor: pointer;\n}\n\n[data-supertokens~="enterEmailSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n word-break: break-word;\n}\n\n[data-supertokens~="submitNewPasswordSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n\n[data-supertokens~="inputErrorMessage"] {\n padding-top: 5px;\n padding-bottom: 5px;\n color: rgb(var(--palette-error));\n line-height: 24px;\n font-weight: 400;\n font-size: var(--font-size-1);\n text-align: left;\n animation: slideTop 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\n max-width: 330px;\n}\n\n@media (max-width: 440px) {\n [data-supertokens~="inputErrorMessage"] {\n max-width: 250px;\n }\n}\n\n[data-supertokens~="inputErrorSymbol"] {\n margin-right: 5px;\n top: 1px;\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="label"] {\n text-align: left;\n font-weight: 700;\n font-size: var(--font-size-0);\n line-height: 24px;\n color: rgb(var(--palette-textLabel));\n}\n\n[data-supertokens~="formRow"] {\n display: flex;\n flex-direction: column;\n padding-top: 0px;\n padding-bottom: 20px;\n}\n\n[data-supertokens~="formRow"][data-supertokens~="hasError"] {\n padding-bottom: 0;\n}\n\n[data-supertokens~="formRow"]:last-child {\n padding-bottom: 0;\n}\n\n[data-supertokens~="sendVerifyEmailIcon"] {\n margin-top: 11px;\n}\n\n[data-supertokens~="primaryText"][data-supertokens~="sendVerifyEmailText"] {\n text-align: center;\n letter-spacing: 0.8px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n font-weight: 700;\n}\n\n[data-supertokens~="sendVerifyEmailResend"] {\n margin-top: 13px;\n font-weight: 400;\n}\n\n[data-supertokens~="sendVerifyEmailResend"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="noFormRow"] {\n padding-bottom: 25px;\n}\n\n[data-supertokens~="emailVerificationButtonWrapper"] {\n padding-top: 25px;\n max-width: 96px;\n margin: 0 auto;\n}\n\n[data-supertokens~="resendEmailLink"] {\n display: inline-block;\n}\n\n[data-supertokens~="resetPasswordEmailForm"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="resetPasswordPasswordForm"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="generalSuccess"] {\n margin-bottom: 20px;\n animation: swingIn 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) alternate 2 both;\n}\n\n[data-supertokens~="headerSubtitle"] strong {\n max-width: 100%;\n display: inline-block;\n vertical-align: bottom;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-supertokens~="primaryText"][data-supertokens~="sendCodeText"] {\n margin-top: 15px;\n margin-bottom: 20px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="sendCodeText"] strong {\n max-width: 100%;\n display: inline-block;\n vertical-align: bottom;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-supertokens~="phoneInputLibRoot"] {\n display: flex;\n align-items: center;\n}\n\n[data-supertokens~="phoneInputWrapper"] {\n display: flex;\n align-items: center;\n}\n\ninput[type="tel"][data-supertokens~="input-phoneNumber"] {\n padding-left: 15px;\n}\n\n[data-supertokens~="phoneInputWrapper"] .iti {\n flex: 1 1;\n min-width: 0;\n width: 100%;\n background: transparent;\n border: none;\n color: inherit;\n outline: none;\n}\n\n[data-supertokens~="continueButtonWrapper"] {\n margin-top: 10px;\n margin-bottom: 30px;\n}\n\n.iti__country-list {\n border: 0;\n top: 40px;\n width: min(72.2vw, 320px);\n border-radius: 6;\n box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.16);\n}\n\n.iti__country {\n display: flex;\n align-items: center;\n height: 34px;\n cursor: pointer;\n\n padding: 0 8px;\n}\n\n.iti__country-name {\n color: var(--palette-textLabel);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin: "0 16px";\n}\n\n[data-supertokens~="continueWithPasswordlessButtonWrapper"] {\n margin: 9px 0;\n}\n\n[data-supertokens~="continueWithPasswordlessLink"] {\n margin-top: 9px;\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\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~="inputContainer"] {\n margin-top: 6px;\n}\n\n[data-supertokens~="inputWrapper"] {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n align-items: center;\n background-color: rgb(var(--palette-inputBackground));\n height: 34px;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n}\n\n[data-supertokens~="inputWrapper"][focus-within] {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputWrapper"]:focus-within {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"][focus-within] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="inputError"]:focus-within {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n\n[data-supertokens~="input"] {\n box-sizing: border-box;\n padding-left: 15px;\n filter: none;\n color: rgb(var(--palette-textInput));\n background-color: transparent;\n border-radius: 6px;\n font-size: var(--font-size-1);\n border: none;\n padding-right: 25px;\n letter-spacing: 1.2px;\n flex: 9 1 75%;\n width: 75%;\n height: 32px;\n}\n\n[data-supertokens~="input"]:focus {\n border: none;\n outline: none;\n}\n\n[data-supertokens~="input"]:-webkit-autofill,\n[data-supertokens~="input"]:-webkit-autofill:hover,\n[data-supertokens~="input"]:-webkit-autofill:focus,\n[data-supertokens~="input"]:-webkit-autofill:active {\n -webkit-text-fill-color: rgb(var(--palette-textInput));\n box-shadow: 0 0 0 30px rgb(var(--palette-inputBackground)) inset;\n}\n\n[data-supertokens~="inputAdornment"] {\n justify-content: center;\n margin-right: 5px;\n}\n\n[data-supertokens~="showPassword"] {\n cursor: pointer;\n}\n\n[data-supertokens~="enterEmailSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n word-break: break-word;\n}\n\n[data-supertokens~="submitNewPasswordSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n\n[data-supertokens~="inputErrorMessage"] {\n padding-top: 5px;\n padding-bottom: 5px;\n color: rgb(var(--palette-error));\n line-height: 24px;\n font-weight: 400;\n font-size: var(--font-size-1);\n text-align: left;\n animation: slideTop 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\n max-width: 330px;\n}\n\n@media (max-width: 440px) {\n [data-supertokens~="inputErrorMessage"] {\n max-width: 250px;\n }\n}\n\n[data-supertokens~="inputErrorSymbol"] {\n margin-right: 5px;\n top: 1px;\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="label"] {\n text-align: left;\n font-weight: 700;\n font-size: var(--font-size-0);\n line-height: 24px;\n color: rgb(var(--palette-textLabel));\n}\n\n[data-supertokens~="formRow"] {\n display: flex;\n flex-direction: column;\n padding-top: 0px;\n padding-bottom: 20px;\n}\n\n[data-supertokens~="formRow"][data-supertokens~="hasError"] {\n padding-bottom: 0;\n}\n\n[data-supertokens~="formRow"]:last-child {\n padding-bottom: 0;\n}\n\n[data-supertokens~="sendVerifyEmailIcon"] {\n margin-top: 11px;\n}\n\n[data-supertokens~="primaryText"][data-supertokens~="sendVerifyEmailText"] {\n text-align: center;\n letter-spacing: 0.8px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n font-weight: 700;\n}\n\n[data-supertokens~="sendVerifyEmailResend"] {\n margin-top: 13px;\n font-weight: 400;\n}\n\n[data-supertokens~="sendVerifyEmailResend"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="noFormRow"] {\n padding-bottom: 25px;\n}\n\n[data-supertokens~="emailVerificationButtonWrapper"] {\n padding-top: 25px;\n max-width: 96px;\n margin: 0 auto;\n}\n\n[data-supertokens~="resendEmailLink"] {\n display: inline-block;\n}\n\n[data-supertokens~="resetPasswordEmailForm"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="resetPasswordPasswordForm"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="generalSuccess"] {\n margin-bottom: 20px;\n animation: swingIn 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) alternate 2 both;\n}\n\n[data-supertokens~="headerSubtitle"] strong {\n max-width: 100%;\n display: inline-block;\n vertical-align: bottom;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-supertokens~="primaryText"][data-supertokens~="sendCodeText"] {\n margin-top: 15px;\n margin-bottom: 20px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="sendCodeText"] strong {\n max-width: 100%;\n display: inline-block;\n vertical-align: bottom;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n[data-supertokens~="phoneInputLibRoot"] {\n display: flex;\n align-items: center;\n}\n\n[data-supertokens~="phoneInputWrapper"] {\n display: flex;\n align-items: center;\n}\n\ninput[type="tel"][data-supertokens~="input-phoneNumber"] {\n padding-left: 15px;\n}\n\n[data-supertokens~="phoneInputWrapper"] .iti {\n flex: 1 1;\n min-width: 0;\n width: 100%;\n background: transparent;\n border: none;\n color: inherit;\n outline: none;\n}\n\n[data-supertokens~="continueButtonWrapper"] {\n margin-top: 10px;\n margin-bottom: 30px;\n}\n\n.iti__country-list {\n border: 0;\n top: 40px;\n width: min(72.2vw, 320px);\n border-radius: 6;\n box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.16);\n}\n\n.iti__country {\n display: flex;\n align-items: center;\n height: 34px;\n cursor: pointer;\n\n padding: 0 8px;\n}\n\n.iti__country-name {\n color: var(--palette-textLabel);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n margin: "0 16px";\n}\n\n[data-supertokens~="continueWithPasswordlessButtonWrapper"] {\n margin: 9px 0;\n}\n\n[data-supertokens~="continueWithPasswordlessLink"] {\n margin-top: 9px;\n}\n'; var ThemeBase = function (_a) { var children = _a.children, @@ -482,6 +484,8 @@ var LinkClickedScreen = function (props) { (payloadBeforeCall === undefined || payloadBeforeCall.sessionHandle !== payloadAfterCall.sessionHandle), recipeId: props.recipe.recipeID, + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, props.recipe.recipeID, loginAttemptInfo === null || loginAttemptInfo === void 0 @@ -1005,6 +1009,8 @@ function useChildProps$4( session$1.accessTokenPayload.sessionHandle !== payloadAfterCall.sessionHandle), recipeId: recipe$1.recipeID, + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, recipe$1.recipeID, genericComponentOverrideContext.getRedirectToPathFromURL(), @@ -1053,6 +1059,8 @@ function useChildProps$4( 4 /*yield*/, evInstance.redirect( { + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), action: "VERIFY_EMAIL", }, navigate, @@ -1131,12 +1139,13 @@ function getModifiedRecipeImplementation$4(originalImpl, setError, rebuildAuthPa resendCode: function (input) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { var res, loginAttemptInfo, timestamp; - return genericComponentOverrideContext.__generator(this, function (_a) { - switch (_a.label) { + var _a; + return genericComponentOverrideContext.__generator(this, function (_b) { + switch (_b.label) { case 0: return [4 /*yield*/, originalImpl.resendCode(input)]; case 1: - res = _a.sent(); + res = _b.sent(); if (!(res.status === "OK")) return [3 /*break*/, 5]; return [ 4 /*yield*/, @@ -1145,7 +1154,7 @@ function getModifiedRecipeImplementation$4(originalImpl, setError, rebuildAuthPa }), ]; case 2: - loginAttemptInfo = _a.sent(); + loginAttemptInfo = _b.sent(); if (!(loginAttemptInfo !== undefined)) return [3 /*break*/, 4]; timestamp = Date.now(); return [ @@ -1154,13 +1163,20 @@ function getModifiedRecipeImplementation$4(originalImpl, setError, rebuildAuthPa userContext: input.userContext, attemptInfo: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, loginAttemptInfo), - { lastResend: timestamp } + { + shouldTryLinkingWithSessionUser: + (_a = loginAttemptInfo.shouldTryLinkingWithSessionUser) !== null && + _a !== void 0 + ? _a + : false, + lastResend: timestamp, + } ), }), ]; case 3: - _a.sent(); - _a.label = 4; + _b.sent(); + _b.label = 4; case 4: return [3 /*break*/, 7]; case 5: @@ -1172,10 +1188,10 @@ function getModifiedRecipeImplementation$4(originalImpl, setError, rebuildAuthPa }), ]; case 6: - _a.sent(); + _b.sent(); setError("ERROR_SIGN_IN_UP_RESEND_RESTART_FLOW"); rebuildAuthPage(); - _a.label = 7; + _b.label = 7; case 7: return [2 /*return*/, res]; } @@ -1355,6 +1371,7 @@ var EmailForm = uiEntry.withOverride("PasswordlessEmailForm", function Passwordl 4 /*yield*/, props.recipeImplementation.createCode({ email: email, + // shouldTryLinkingWithSessionUser is set by the fn override userContext: userContext, }), ]; @@ -3515,6 +3532,7 @@ var PhoneForm = uiEntry.withOverride("PasswordlessPhoneForm", function Passwordl 4 /*yield*/, props.recipeImplementation.createCode({ phoneNumber: phoneNumber, + // shouldTryLinkingWithSessionUser is set by the fn override userContext: userContext, }), ]; @@ -4408,6 +4426,8 @@ function useChildProps$3(recipe$1, recipeImplementation, state, contactMethod, d evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, navigate, undefined, @@ -4664,7 +4684,7 @@ function useOnLoad(props, recipeImplementation, dispatch, userContext) { recipeImplementation.createCode( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, createCodeInfo), - { userContext: userContext } + { shouldTryLinkingWithSessionUser: true, userContext: userContext } ) ), ]; @@ -4701,6 +4721,8 @@ function useOnLoad(props, recipeImplementation, dispatch, userContext) { 4 /*yield*/, evInstance.redirect( { + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), action: "VERIFY_EMAIL", }, props.navigate, @@ -4804,6 +4826,7 @@ function getModifiedRecipeImplementation$3(originalImpl, config, dispatch) { genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input), { + shouldTryLinkingWithSessionUser: true, userContext: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input.userContext), { additionalAttemptInfo: additionalAttemptInfo } @@ -4834,12 +4857,13 @@ function getModifiedRecipeImplementation$3(originalImpl, config, dispatch) { resendCode: function (input) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { var res, loginAttemptInfo, timestamp; - return genericComponentOverrideContext.__generator(this, function (_a) { - switch (_a.label) { + var _a; + return genericComponentOverrideContext.__generator(this, function (_b) { + switch (_b.label) { case 0: return [4 /*yield*/, originalImpl.resendCode(input)]; case 1: - res = _a.sent(); + res = _b.sent(); if (!(res.status === "OK")) return [3 /*break*/, 5]; return [ 4 /*yield*/, @@ -4848,7 +4872,7 @@ function getModifiedRecipeImplementation$3(originalImpl, config, dispatch) { }), ]; case 2: - loginAttemptInfo = _a.sent(); + loginAttemptInfo = _b.sent(); if (!(loginAttemptInfo !== undefined)) return [3 /*break*/, 4]; timestamp = Date.now(); return [ @@ -4857,14 +4881,21 @@ function getModifiedRecipeImplementation$3(originalImpl, config, dispatch) { userContext: input.userContext, attemptInfo: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, loginAttemptInfo), - { lastResend: timestamp } + { + shouldTryLinkingWithSessionUser: + (_a = loginAttemptInfo.shouldTryLinkingWithSessionUser) !== null && + _a !== void 0 + ? _a + : true, + lastResend: timestamp, + } ), }), ]; case 3: - _a.sent(); + _b.sent(); dispatch({ type: "resendCode", timestamp: timestamp }); - _a.label = 4; + _b.label = 4; case 4: return [3 /*break*/, 7]; case 5: @@ -4876,9 +4907,9 @@ function getModifiedRecipeImplementation$3(originalImpl, config, dispatch) { }), ]; case 6: - _a.sent(); + _b.sent(); dispatch({ type: "restartFlow", error: "ERROR_SIGN_IN_UP_RESEND_RESTART_FLOW" }); - _a.label = 7; + _b.label = 7; case 7: return [2 /*return*/, res]; } @@ -4891,7 +4922,15 @@ function getModifiedRecipeImplementation$3(originalImpl, config, dispatch) { return genericComponentOverrideContext.__generator(this, function (_a) { switch (_a.label) { case 0: - return [4 /*yield*/, originalImpl.consumeCode(input)]; + return [ + 4 /*yield*/, + originalImpl.consumeCode( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, input), + { shouldTryLinkingWithSessionUser: true } + ) + ), + ]; case 1: res = _a.sent(); if (!(res.status === "RESTART_FLOW_ERROR")) return [3 /*break*/, 3]; @@ -5115,7 +5154,10 @@ var EmailOrPhoneForm = uiEntry.withOverride( props.recipeImplementation.createCode( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, contactInfo), - { userContext: userContext } + { + // shouldTryLinkingWithSessionUser is set by the fn override + userContext: userContext, + } ) ), ]; @@ -5209,7 +5251,17 @@ function getActiveScreen$1(factorIds) { } } -function useChildProps$2(recipe$1, factorIds, error, onError, clearError, rebuildAuthPage, userContext, navigate) { +function useChildProps$2( + recipe$1, + factorIds, + onAuthSuccess, + error, + onError, + clearError, + rebuildAuthPage, + userContext, + navigate +) { var _this = this; var session$1 = uiEntry.useSessionContext(); var recipeImplementation = React__namespace.useMemo( @@ -5249,28 +5301,18 @@ function useChildProps$2(recipe$1, factorIds, error, onError, clearError, rebuil case 3: return [ 2 /*return*/, - types.Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: - result.createdNewRecipeUser && - result.user.loginMethods.length === 1, - isNewRecipeUser: result.createdNewRecipeUser, - newSessionCreated: - session$1.loading || - !session$1.doesSessionExist || - (payloadAfterCall !== undefined && - session$1.accessTokenPayload.sessionHandle !== - payloadAfterCall.sessionHandle), - recipeId: recipe$1.recipeID, - }, - recipe$1.recipeID, - genericComponentOverrideContext.getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender), + onAuthSuccess({ + createdNewUser: + result.createdNewRecipeUser && result.user.loginMethods.length === 1, + isNewRecipeUser: result.createdNewRecipeUser, + newSessionCreated: + session$1.loading || + !session$1.doesSessionExist || + (payloadAfterCall !== undefined && + session$1.accessTokenPayload.sessionHandle !== + payloadAfterCall.sessionHandle), + recipeId: "passwordless", + }).catch(rethrowInRender), ]; } }); @@ -5316,6 +5358,8 @@ function useChildProps$2(recipe$1, factorIds, error, onError, clearError, rebuil evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, navigate, undefined, @@ -5355,6 +5399,7 @@ var SignInUpFeatureInner = function (props) { var childProps = useChildProps$2( props.recipe, props.factorIds, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -5423,6 +5468,7 @@ function getModifiedRecipeImplementation$2(originalImpl, config, rebuildAuthPage genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input), { + shouldTryLinkingWithSessionUser: false, userContext: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input.userContext), { additionalAttemptInfo: additionalAttemptInfo } @@ -5559,6 +5605,8 @@ var EPComboEmailForm = uiEntry.withOverride( onClick: function () { return recipe$1.EmailPassword.getInstanceOrThrow().redirect({ action: "RESET_PASSWORD", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }); }, "data-supertokens": "link linkButton formLabelLinkBtn forgotPasswordLink", @@ -5740,6 +5788,8 @@ var EPComboEmailOrPhoneForm = uiEntry.withOverride( onClick: function () { return recipe$1.EmailPassword.getInstanceOrThrow().redirect({ action: "RESET_PASSWORD", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }); }, "data-supertokens": "link linkButton formLabelLinkBtn forgotPasswordLink", @@ -5877,7 +5927,17 @@ function getActiveScreen(factorIds) { } } -function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuildAuthPage, userContext, navigate) { +function useChildProps$1( + recipe$2, + factorIds, + onAuthSuccess, + error, + onError, + clearError, + rebuildAuthPage, + userContext, + navigate +) { var _this = this; var session$1 = uiEntry.useSessionContext(); var recipeImplementation = React__namespace.useMemo( @@ -5929,6 +5989,7 @@ function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuil 4 /*yield*/, recipeImplementation.createCode({ phoneNumber: contactInfo, + shouldTryLinkingWithSessionUser: false, userContext: userContext, }), ]; @@ -5973,7 +6034,11 @@ function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuil if (!pwlessExists.doesExist) return [3 /*break*/, 6]; return [ 4 /*yield*/, - recipeImplementation.createCode({ email: email, userContext: userContext }), + recipeImplementation.createCode({ + email: email, + shouldTryLinkingWithSessionUser: false, + userContext: userContext, + }), ]; case 5: createRes = _b.sent(); @@ -6024,6 +6089,7 @@ function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuil 4 /*yield*/, recipe$1.EmailPassword.getInstanceOrThrow().webJSRecipe.signIn({ formFields: formFields, + shouldTryLinkingWithSessionUser: false, userContext: userContext, }), ]; @@ -6060,7 +6126,7 @@ function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuil recipeImplementation.createCode( genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, createInfo), - { userContext: userContext } + { shouldTryLinkingWithSessionUser: false, userContext: userContext } ) ), ]; @@ -6104,32 +6170,20 @@ function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuil case 4: return [ 2 /*return*/, - types.Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: - result.createdNewRecipeUser && - result.user.loginMethods.length === 1, - isNewRecipeUser: result.createdNewRecipeUser, - newSessionCreated: - session$1.loading || - !session$1.doesSessionExist || - (payloadAfterCall !== undefined && - session$1.accessTokenPayload.sessionHandle !== - payloadAfterCall.sessionHandle), - recipeId: result.isEmailPassword - ? recipe$1.EmailPassword.RECIPE_ID - : recipe$2.recipeID, - }, - result.isEmailPassword - ? recipe$1.EmailPassword.RECIPE_ID - : recipe$2.recipeID, - genericComponentOverrideContext.getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender), + onAuthSuccess({ + createdNewUser: + result.createdNewRecipeUser && result.user.loginMethods.length === 1, + isNewRecipeUser: result.createdNewRecipeUser, + newSessionCreated: + session$1.loading || + !session$1.doesSessionExist || + (payloadAfterCall !== undefined && + session$1.accessTokenPayload.sessionHandle !== + payloadAfterCall.sessionHandle), + recipeId: result.isEmailPassword + ? recipe$1.EmailPassword.RECIPE_ID + : recipe$2.recipeID, + }).catch(rethrowInRender), ]; } }); @@ -6175,6 +6229,8 @@ function useChildProps$1(recipe$2, factorIds, error, onError, clearError, rebuil evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, navigate, undefined, @@ -6222,6 +6278,7 @@ var SignInUpEPComboFeatureInner = function (props) { var childProps = useChildProps$1( props.recipe, props.factorIds, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -6295,6 +6352,7 @@ function getModifiedRecipeImplementation$1(originalImpl, config, rebuildAuthPage genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input), { + shouldTryLinkingWithSessionUser: false, userContext: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input.userContext), { additionalAttemptInfo: additionalAttemptInfo } @@ -6316,7 +6374,17 @@ function getModifiedRecipeImplementation$1(originalImpl, config, rebuildAuthPage }); } -function useChildProps(recipe$1, loginAttemptInfo, error, onError, clearError, rebuildAuthPage, userContext, navigate) { +function useChildProps( + recipe$1, + loginAttemptInfo, + onAuthSuccess, + error, + onError, + clearError, + rebuildAuthPage, + userContext, + navigate +) { var _this = this; var session$1 = uiEntry.useSessionContext(); var recipeImplementation = React__namespace.useMemo( @@ -6353,28 +6421,18 @@ function useChildProps(recipe$1, loginAttemptInfo, error, onError, clearError, r case 3: return [ 2 /*return*/, - types.Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: - result.createdNewRecipeUser && - result.user.loginMethods.length === 1, - isNewRecipeUser: result.createdNewRecipeUser, - newSessionCreated: - session$1.loading || - !session$1.doesSessionExist || - (payloadAfterCall !== undefined && - session$1.accessTokenPayload.sessionHandle !== - payloadAfterCall.sessionHandle), - recipeId: recipe$1.recipeID, - }, - recipe$1.recipeID, - genericComponentOverrideContext.getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender), + onAuthSuccess({ + createdNewUser: + result.createdNewRecipeUser && result.user.loginMethods.length === 1, + isNewRecipeUser: result.createdNewRecipeUser, + newSessionCreated: + session$1.loading || + !session$1.doesSessionExist || + (payloadAfterCall !== undefined && + session$1.accessTokenPayload.sessionHandle !== + payloadAfterCall.sessionHandle), + recipeId: "passwordless", + }).catch(rethrowInRender), ]; } }); @@ -6417,6 +6475,8 @@ function useChildProps(recipe$1, loginAttemptInfo, error, onError, clearError, r evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, navigate, undefined, @@ -6451,6 +6511,7 @@ var UserInputCodeFeatureInner = function (props) { var childProps = useChildProps( props.recipe, props.loginAttemptInfo, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -6494,12 +6555,13 @@ function getModifiedRecipeImplementation(originalImpl, setError, rebuildAuthPage resendCode: function (input) { return genericComponentOverrideContext.__awaiter(_this, void 0, void 0, function () { var res, loginAttemptInfo, timestamp; - return genericComponentOverrideContext.__generator(this, function (_a) { - switch (_a.label) { + var _a; + return genericComponentOverrideContext.__generator(this, function (_b) { + switch (_b.label) { case 0: return [4 /*yield*/, originalImpl.resendCode(input)]; case 1: - res = _a.sent(); + res = _b.sent(); if (!(res.status === "OK")) return [3 /*break*/, 5]; return [ 4 /*yield*/, @@ -6508,7 +6570,7 @@ function getModifiedRecipeImplementation(originalImpl, setError, rebuildAuthPage }), ]; case 2: - loginAttemptInfo = _a.sent(); + loginAttemptInfo = _b.sent(); if (!(loginAttemptInfo !== undefined)) return [3 /*break*/, 4]; timestamp = Date.now(); return [ @@ -6517,13 +6579,20 @@ function getModifiedRecipeImplementation(originalImpl, setError, rebuildAuthPage userContext: input.userContext, attemptInfo: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, loginAttemptInfo), - { lastResend: timestamp } + { + shouldTryLinkingWithSessionUser: + (_a = loginAttemptInfo.shouldTryLinkingWithSessionUser) !== null && + _a !== void 0 + ? _a + : false, + lastResend: timestamp, + } ), }), ]; case 3: - _a.sent(); - _a.label = 4; + _b.sent(); + _b.label = 4; case 4: return [3 /*break*/, 7]; case 5: @@ -6535,10 +6604,10 @@ function getModifiedRecipeImplementation(originalImpl, setError, rebuildAuthPage }), ]; case 6: - _a.sent(); + _b.sent(); setError("ERROR_SIGN_IN_UP_RESEND_RESTART_FLOW"); rebuildAuthPage(); - _a.label = 7; + _b.label = 7; case 7: return [2 /*return*/, res]; } diff --git a/lib/build/recipe/authRecipe/components/theme/authPage/authPageHeader.d.ts b/lib/build/recipe/authRecipe/components/theme/authPage/authPageHeader.d.ts index 60ed74fed..127a6536f 100644 --- a/lib/build/recipe/authRecipe/components/theme/authPage/authPageHeader.d.ts +++ b/lib/build/recipe/authRecipe/components/theme/authPage/authPageHeader.d.ts @@ -6,4 +6,11 @@ export declare const AuthPageHeader: import("react").ComponentType<{ onSignInUpSwitcherClick: (() => void) | undefined; resetFactorList: () => void; showBackButton: boolean; + oauth2ClientInfo?: + | { + logoUri?: string | undefined; + clientUri?: string | undefined; + clientName: string; + } + | undefined; }>; diff --git a/lib/build/recipe/authRecipe/types.d.ts b/lib/build/recipe/authRecipe/types.d.ts index 4dbbf3131..2111f5f31 100644 --- a/lib/build/recipe/authRecipe/types.d.ts +++ b/lib/build/recipe/authRecipe/types.d.ts @@ -3,7 +3,13 @@ import type { AuthPageComponentList } from "./components/theme/authPage/authPage import type { AuthPageFooter } from "./components/theme/authPage/authPageFooter"; import type { AuthPageHeader } from "./components/theme/authPage/authPageHeader"; import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; -import type { AuthComponentProps, Navigate, PartialAuthComponentProps, UserContext } from "../../types"; +import type { + AuthComponentProps, + Navigate, + PartialAuthComponentProps, + SuccessRedirectContext, + UserContext, +} from "../../types"; import type { Config as RecipeModuleConfig, NormalisedConfig as NormalisedRecipeModuleConfig, @@ -26,7 +32,19 @@ declare type ComponentWithPreloadInfo = { >; preloadInfo: T; }; +export declare type AuthSuccessContext = Omit< + SuccessRedirectContext, + "redirectToPath" | "action" | "loginChallenge" | "recipeId" +> & { + recipeId: string; +}; export declare type AuthPageThemeProps = { + oauth2ClientInfo?: { + clientLogo?: string; + clientUri?: string; + clientName: string; + }; + onAuthSuccess: (successContext: AuthSuccessContext) => Promise; showBackButton: boolean; setFactorList: (factorIds: string[]) => void; resetFactorList: () => void; diff --git a/lib/build/recipe/emailpassword/components/features/signin/index.d.ts b/lib/build/recipe/emailpassword/components/features/signin/index.d.ts index cc8a4adfa..89d1808a1 100644 --- a/lib/build/recipe/emailpassword/components/features/signin/index.d.ts +++ b/lib/build/recipe/emailpassword/components/features/signin/index.d.ts @@ -1,10 +1,12 @@ import * as React from "react"; import type { Navigate, UserContext, PartialAuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { SignInThemeProps } from "../../../types"; import type { ComponentOverrideMap } from "../../../types"; export declare function useChildProps( recipe: Recipe, + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, diff --git a/lib/build/recipe/emailpassword/components/features/signup/index.d.ts b/lib/build/recipe/emailpassword/components/features/signup/index.d.ts index a0b3bc16d..08715c7a5 100644 --- a/lib/build/recipe/emailpassword/components/features/signup/index.d.ts +++ b/lib/build/recipe/emailpassword/components/features/signup/index.d.ts @@ -1,10 +1,12 @@ import * as React from "react"; import type { Navigate, UserContext, PartialAuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { SignUpThemeProps } from "../../../types"; import type { ComponentOverrideMap } from "../../../types"; export declare function useChildProps( recipe: Recipe, + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, diff --git a/lib/build/recipe/emailpassword/components/themes/translations.d.ts b/lib/build/recipe/emailpassword/components/themes/translations.d.ts index 144c2c176..ec431cb0f 100644 --- a/lib/build/recipe/emailpassword/components/themes/translations.d.ts +++ b/lib/build/recipe/emailpassword/components/themes/translations.d.ts @@ -74,6 +74,7 @@ export declare const defaultTranslationsEmailPassword: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/emailpassword/index.d.ts b/lib/build/recipe/emailpassword/index.d.ts index f5dbca606..9bff21ab9 100644 --- a/lib/build/recipe/emailpassword/index.d.ts +++ b/lib/build/recipe/emailpassword/index.d.ts @@ -66,6 +66,7 @@ export default class Wrapper { id: string; value: string; }[]; + shouldTryLinkingWithSessionUser?: boolean; options?: RecipeFunctionOptions; userContext?: UserContext; }): Promise< @@ -93,6 +94,7 @@ export default class Wrapper { id: string; value: string; }[]; + shouldTryLinkingWithSessionUser?: boolean; options?: RecipeFunctionOptions; userContext?: UserContext; }): Promise< diff --git a/lib/build/recipe/emailpassword/prebuiltui.d.ts b/lib/build/recipe/emailpassword/prebuiltui.d.ts index 1865fe165..dde794f58 100644 --- a/lib/build/recipe/emailpassword/prebuiltui.d.ts +++ b/lib/build/recipe/emailpassword/prebuiltui.d.ts @@ -84,6 +84,7 @@ export declare class EmailPasswordPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/emailpassword/recipe.d.ts b/lib/build/recipe/emailpassword/recipe.d.ts index a4c04ec3e..73be9e8f5 100644 --- a/lib/build/recipe/emailpassword/recipe.d.ts +++ b/lib/build/recipe/emailpassword/recipe.d.ts @@ -16,8 +16,8 @@ export default class EmailPassword extends AuthRecipe< > { readonly webJSRecipe: WebJSRecipeInterface; static instance?: EmailPassword; - static RECIPE_ID: string; - recipeID: string; + static RECIPE_ID: "emailpassword"; + recipeID: "emailpassword"; firstFactorIds: "emailpassword"[]; getFirstFactorsForAuthPage(): string[]; constructor( diff --git a/lib/build/recipe/emailpassword/types.d.ts b/lib/build/recipe/emailpassword/types.d.ts index 4198ad5dc..a6879a04d 100644 --- a/lib/build/recipe/emailpassword/types.d.ts +++ b/lib/build/recipe/emailpassword/types.d.ts @@ -12,6 +12,7 @@ import type { FormFieldBaseConfig, NormalisedBaseConfig, NormalisedFormField, + NormalisedGetRedirectionURLContext, ThemeBaseProps, UserContext, } from "../../types"; @@ -141,9 +142,9 @@ export declare type PreAPIHookContext = { url: string; userContext: UserContext; }; -export declare type GetRedirectionURLContext = { +export declare type GetRedirectionURLContext = NormalisedGetRedirectionURLContext<{ action: "RESET_PASSWORD"; -}; +}>; export declare type OnHandleEventContext = | AuthRecipeModuleOnHandleEventContext | { diff --git a/lib/build/recipe/emailverification/components/themes/translations.d.ts b/lib/build/recipe/emailverification/components/themes/translations.d.ts index a41cb0c89..357f1f004 100644 --- a/lib/build/recipe/emailverification/components/themes/translations.d.ts +++ b/lib/build/recipe/emailverification/components/themes/translations.d.ts @@ -19,6 +19,7 @@ export declare const defaultTranslationsEmailVerification: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/emailverification/prebuiltui.d.ts b/lib/build/recipe/emailverification/prebuiltui.d.ts index 5b548ded9..4ada857a7 100644 --- a/lib/build/recipe/emailverification/prebuiltui.d.ts +++ b/lib/build/recipe/emailverification/prebuiltui.d.ts @@ -29,6 +29,7 @@ export declare class EmailVerificationPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/emailverification/types.d.ts b/lib/build/recipe/emailverification/types.d.ts index be135de75..673f4500c 100644 --- a/lib/build/recipe/emailverification/types.d.ts +++ b/lib/build/recipe/emailverification/types.d.ts @@ -1,7 +1,7 @@ import type { SendVerifyEmail } from "./components/themes/emailVerification/sendVerifyEmail"; import type { VerifyEmailLinkClicked } from "./components/themes/emailVerification/verifyEmailLinkClicked"; import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; -import type { FeatureBaseConfig, ThemeBaseProps, UserContext } from "../../types"; +import type { FeatureBaseConfig, NormalisedGetRedirectionURLContext, ThemeBaseProps, UserContext } from "../../types"; import type { Config as RecipeModuleConfig, NormalisedConfig as NormalisedRecipeModuleConfig, @@ -39,9 +39,9 @@ export declare type NormalisedConfig = { ) => RecipeInterface; }; } & NormalisedRecipeModuleConfig; -export declare type GetRedirectionURLContext = { +export declare type GetRedirectionURLContext = NormalisedGetRedirectionURLContext<{ action: "VERIFY_EMAIL"; -}; +}>; export declare type PreAndPostAPIHookAction = "VERIFY_EMAIL" | "SEND_VERIFY_EMAIL" | "IS_EMAIL_VERIFIED"; export declare type PreAPIHookContext = { action: PreAndPostAPIHookAction; diff --git a/lib/build/recipe/multifactorauth/components/themes/translations.d.ts b/lib/build/recipe/multifactorauth/components/themes/translations.d.ts index d1a9adae9..b26ba3b86 100644 --- a/lib/build/recipe/multifactorauth/components/themes/translations.d.ts +++ b/lib/build/recipe/multifactorauth/components/themes/translations.d.ts @@ -13,6 +13,7 @@ export declare const defaultTranslationsMultiFactorAuth: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/multifactorauth/prebuiltui.d.ts b/lib/build/recipe/multifactorauth/prebuiltui.d.ts index fc22c808a..796cdfa3d 100644 --- a/lib/build/recipe/multifactorauth/prebuiltui.d.ts +++ b/lib/build/recipe/multifactorauth/prebuiltui.d.ts @@ -23,6 +23,7 @@ export declare class MultiFactorAuthPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/multifactorauth/types.d.ts b/lib/build/recipe/multifactorauth/types.d.ts index bf8837003..025aea3a2 100644 --- a/lib/build/recipe/multifactorauth/types.d.ts +++ b/lib/build/recipe/multifactorauth/types.d.ts @@ -3,7 +3,7 @@ import type { FactorChooserHeader } from "./components/themes/factorChooser/fact import type { FactorList } from "./components/themes/factorChooser/factorList"; import type { FactorOption } from "./components/themes/factorChooser/factorOption"; import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; -import type { FeatureBaseConfig, UserContext } from "../../types"; +import type { FeatureBaseConfig, NormalisedGetRedirectionURLContext, UserContext } from "../../types"; import type { Config as RecipeModuleConfig, NormalisedConfig as NormalisedRecipeModuleConfig, @@ -51,7 +51,7 @@ export declare type NormalisedConfig = { ) => RecipeInterface; }; } & NormalisedRecipeModuleConfig; -export declare type GetRedirectionURLContext = +export declare type GetRedirectionURLContext = NormalisedGetRedirectionURLContext< | { action: "FACTOR_CHOOSER"; nextFactorOptions?: string[]; @@ -62,7 +62,8 @@ export declare type GetRedirectionURLContext = factorId: string; forceSetup?: boolean; stepUp?: boolean; - }; + } +>; export declare type PreAndPostAPIHookAction = "GET_MFA_INFO"; export declare type PreAPIHookContext = { action: PreAndPostAPIHookAction; diff --git a/lib/build/recipe/oauth2provider/componentOverrideContext.d.ts b/lib/build/recipe/oauth2provider/componentOverrideContext.d.ts new file mode 100644 index 000000000..288fc18e7 --- /dev/null +++ b/lib/build/recipe/oauth2provider/componentOverrideContext.d.ts @@ -0,0 +1,9 @@ +/// +import type { ComponentOverrideMap } from "./types"; +declare const useContext: () => ComponentOverrideMap, + Provider: import("react").FC< + import("react").PropsWithChildren<{ + components: ComponentOverrideMap; + }> + >; +export { useContext as useRecipeComponentOverrideContext, Provider as RecipeComponentsOverrideContextProvider }; diff --git a/lib/build/recipe/oauth2provider/components/features/oauth2LogoutScreen/index.d.ts b/lib/build/recipe/oauth2provider/components/features/oauth2LogoutScreen/index.d.ts new file mode 100644 index 000000000..6b278cc3f --- /dev/null +++ b/lib/build/recipe/oauth2provider/components/features/oauth2LogoutScreen/index.d.ts @@ -0,0 +1,11 @@ +import * as React from "react"; +import type { FeatureBaseProps, UserContext } from "../../../../../types"; +import type Recipe from "../../../recipe"; +import type { ComponentOverrideMap } from "../../../types"; +declare type Prop = FeatureBaseProps<{ + recipe: Recipe; + userContext?: UserContext; + useComponentOverrides: () => ComponentOverrideMap; +}>; +export declare const OAuth2LogoutScreen: React.FC; +export default OAuth2LogoutScreen; diff --git a/lib/build/recipe/oauth2provider/components/features/tryRefreshPage/index.d.ts b/lib/build/recipe/oauth2provider/components/features/tryRefreshPage/index.d.ts new file mode 100644 index 000000000..dfde96e31 --- /dev/null +++ b/lib/build/recipe/oauth2provider/components/features/tryRefreshPage/index.d.ts @@ -0,0 +1,11 @@ +import * as React from "react"; +import type { FeatureBaseProps, UserContext } from "../../../../../types"; +import type Recipe from "../../../recipe"; +import type { ComponentOverrideMap } from "../../../types"; +declare type Prop = FeatureBaseProps<{ + recipe: Recipe; + userContext?: UserContext; + useComponentOverrides: () => ComponentOverrideMap; +}>; +export declare const TryRefreshPage: React.FC; +export default TryRefreshPage; diff --git a/lib/build/recipe/oauth2provider/components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner.d.ts b/lib/build/recipe/oauth2provider/components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner.d.ts new file mode 100644 index 000000000..222609ded --- /dev/null +++ b/lib/build/recipe/oauth2provider/components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner.d.ts @@ -0,0 +1,5 @@ +/// +export declare const OAuth2LogoutScreenInner: import("react").ComponentType<{ + isLoggingOut: boolean; + onLogoutClicked: () => void; +}>; diff --git a/lib/build/recipe/oauth2provider/components/themes/oauth2LogoutScreen/index.d.ts b/lib/build/recipe/oauth2provider/components/themes/oauth2LogoutScreen/index.d.ts new file mode 100644 index 000000000..0fa32a566 --- /dev/null +++ b/lib/build/recipe/oauth2provider/components/themes/oauth2LogoutScreen/index.d.ts @@ -0,0 +1,3 @@ +import React from "react"; +import type { OAuth2LogoutScreenThemeProps } from "../../../types"; +export declare const OAuth2LogoutScreenTheme: React.FC; diff --git a/lib/build/recipe/oauth2provider/components/themes/themeBase.d.ts b/lib/build/recipe/oauth2provider/components/themes/themeBase.d.ts new file mode 100644 index 000000000..516a61754 --- /dev/null +++ b/lib/build/recipe/oauth2provider/components/themes/themeBase.d.ts @@ -0,0 +1,7 @@ +import React from "react"; +import type { PropsWithChildren } from "react"; +export declare const ThemeBase: React.FC< + PropsWithChildren<{ + userStyles: Array; + }> +>; diff --git a/lib/build/recipe/oauth2provider/components/themes/translations.d.ts b/lib/build/recipe/oauth2provider/components/themes/translations.d.ts new file mode 100644 index 000000000..f5122e036 --- /dev/null +++ b/lib/build/recipe/oauth2provider/components/themes/translations.d.ts @@ -0,0 +1,27 @@ +export declare const defaultTranslationsOAuth2Provider: { + en: { + LOGGING_OUT: string; + LOGOUT_CONFIRMATION: string; + LOGOUT: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; + AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_UP_START: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_UP_SIGN_IN_LINK: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_UP_END: string; + AUTH_PAGE_FOOTER_START: string; + AUTH_PAGE_FOOTER_TOS: string; + AUTH_PAGE_FOOTER_AND: string; + AUTH_PAGE_FOOTER_PP: string; + AUTH_PAGE_FOOTER_END: string; + DIVIDER_OR: string; + BRANDING_POWERED_BY_START: string; + BRANDING_POWERED_BY_END: string; + SOMETHING_WENT_WRONG_ERROR: string; + SOMETHING_WENT_WRONG_ERROR_RELOAD: string; + }; +}; diff --git a/lib/build/recipe/oauth2provider/constants.d.ts b/lib/build/recipe/oauth2provider/constants.d.ts new file mode 100644 index 000000000..4ce4a8095 --- /dev/null +++ b/lib/build/recipe/oauth2provider/constants.d.ts @@ -0,0 +1,2 @@ +export declare const DEFAULT_TRY_REFRESH_PATH = "/try-refresh"; +export declare const DEFAULT_OAUTH2_LOGOUT_PATH = "/oauth/logout"; diff --git a/lib/build/recipe/oauth2provider/functionOverrides.d.ts b/lib/build/recipe/oauth2provider/functionOverrides.d.ts new file mode 100644 index 000000000..f6163a931 --- /dev/null +++ b/lib/build/recipe/oauth2provider/functionOverrides.d.ts @@ -0,0 +1,6 @@ +import type { OnHandleEventContext } from "./types"; +import type { RecipeOnHandleEventFunction } from "../recipeModule/types"; +import type { RecipeInterface } from "supertokens-web-js/recipe/oauth2provider"; +export declare const getFunctionOverrides: ( + onHandleEvent: RecipeOnHandleEventFunction +) => (originalImp: RecipeInterface) => RecipeInterface; diff --git a/lib/build/recipe/oauth2provider/index.d.ts b/lib/build/recipe/oauth2provider/index.d.ts new file mode 100644 index 000000000..1a574d79b --- /dev/null +++ b/lib/build/recipe/oauth2provider/index.d.ts @@ -0,0 +1,89 @@ +/// +import { RecipeComponentsOverrideContextProvider } from "./componentOverrideContext"; +import { UserInput, GetRedirectionURLContext, PreAPIHookContext, OnHandleEventContext } from "./types"; +import type { RecipeFunctionOptions, LoginInfo } from "supertokens-web-js/recipe/oauth2provider"; +import type { RecipeInterface } from "supertokens-web-js/recipe/oauth2provider"; +export default class Wrapper { + static init(config?: UserInput): import("../../types").RecipeInitResult; + /** + * Returns information about an OAuth login in progress + * + * @param loginChallenge The login challenge from the url + * + * @param userContext (OPTIONAL) Refer to {@link https://supertokens.com/docs/emailpassword/advanced-customizations/user-context the documentation} + * + * @param options (OPTIONAL) Use this to configure additional properties (for example pre api hooks) + * + * @returns `{status: "OK", info: LoginInfo}` + * + * @throws STGeneralError if the API exposed by the backend SDKs returns `status: "GENERAL_ERROR"` + */ + static getLoginChallengeInfo(input: { + loginChallenge: string; + options?: RecipeFunctionOptions; + userContext?: any; + }): Promise<{ + status: "OK"; + info: LoginInfo; + fetchResponse: Response; + }>; + /** + * Accepts the OAuth2 Login request and returns the redirect URL to continue the OAuth flow. + * + * @param loginChallenge The login challenge from the url + * + * @param userContext (OPTIONAL) Refer to {@link https://supertokens.com/docs/emailpassword/advanced-customizations/user-context the documentation} + * + * @param options (OPTIONAL) Use this to configure additional properties (for example pre api hooks) + * + * @returns `{status: "OK", frontendRedirectTo: string}` + * + * @throws STGeneralError if the API exposed by the backend SDKs returns `status: "GENERAL_ERROR"` + */ + static getRedirectURLToContinueOAuthFlow(input: { + loginChallenge: string; + options?: RecipeFunctionOptions; + userContext?: any; + }): Promise<{ + status: "OK"; + frontendRedirectTo: string; + fetchResponse: Response; + }>; + /** + * Accepts the OAuth2 Logout request, clears the SuperTokens session and returns post logout redirect URL. + * + * @param logoutChallenge The logout challenge from the url + * + * @param userContext (OPTIONAL) Refer to {@link https://supertokens.com/docs/emailpassword/advanced-customizations/user-context the documentation} + * + * @param options (OPTIONAL) Use this to configure additional properties (for example pre api hooks) + * + * @returns `{status: "OK", frontendRedirectTo: string}` + * + * @throws STGeneralError if the API exposed by the backend SDKs returns `status: "GENERAL_ERROR"` + */ + static logOut(input: { logoutChallenge: string; options?: RecipeFunctionOptions; userContext?: any }): Promise<{ + status: "OK"; + frontendRedirectTo: string; + fetchResponse: Response; + }>; + static ComponentsOverrideProvider: import("react").FC< + import("react").PropsWithChildren<{ + components: import("./types").ComponentOverrideMap; + }> + >; +} +declare const init: typeof Wrapper.init; +declare const getLoginChallengeInfo: typeof Wrapper.getLoginChallengeInfo; +declare const logOut: typeof Wrapper.logOut; +export { + init, + getLoginChallengeInfo, + logOut, + GetRedirectionURLContext, + PreAPIHookContext, + OnHandleEventContext, + UserInput, + RecipeInterface, + RecipeComponentsOverrideContextProvider, +}; diff --git a/lib/build/recipe/oauth2provider/prebuiltui.d.ts b/lib/build/recipe/oauth2provider/prebuiltui.d.ts new file mode 100644 index 000000000..8b17b7fb5 --- /dev/null +++ b/lib/build/recipe/oauth2provider/prebuiltui.d.ts @@ -0,0 +1,71 @@ +/// +import { RecipeRouter } from "../recipeRouter"; +import OAuth2ProviderRecipe from "./recipe"; +import type { GenericComponentOverrideMap } from "../../components/componentOverride/componentOverrideContext"; +import type { FeatureBaseProps, RecipeFeatureComponentMap, UserContext } from "../../types"; +import type { AuthComponent } from "../../types"; +export declare class OAuth2ProviderPreBuiltUI extends RecipeRouter { + readonly recipeInstance: OAuth2ProviderRecipe; + static instance?: OAuth2ProviderPreBuiltUI; + languageTranslations: { + en: { + LOGGING_OUT: string; + LOGOUT_CONFIRMATION: string; + LOGOUT: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; + AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_UP_START: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_UP_SIGN_IN_LINK: string; + AUTH_PAGE_HEADER_SUBTITLE_SIGN_UP_END: string; + AUTH_PAGE_FOOTER_START: string; + AUTH_PAGE_FOOTER_TOS: string; + AUTH_PAGE_FOOTER_AND: string; + AUTH_PAGE_FOOTER_PP: string; + AUTH_PAGE_FOOTER_END: string; + DIVIDER_OR: string; + BRANDING_POWERED_BY_START: string; + BRANDING_POWERED_BY_END: string; + SOMETHING_WENT_WRONG_ERROR: string; + SOMETHING_WENT_WRONG_ERROR_RELOAD: string; + }; + }; + constructor(recipeInstance: OAuth2ProviderRecipe); + static getInstanceOrInitAndGetInstance(): OAuth2ProviderPreBuiltUI; + static getFeatures(useComponentOverrides?: () => GenericComponentOverrideMap): RecipeFeatureComponentMap; + static getFeatureComponent( + componentName: "try-refresh-page" | "oauth2-logout-screen", + props: any, + useComponentOverrides?: () => GenericComponentOverrideMap + ): JSX.Element; + getFeatures: (useComponentOverrides?: () => GenericComponentOverrideMap) => RecipeFeatureComponentMap; + getFeatureComponent: ( + componentName: "try-refresh-page" | "oauth2-logout-screen", + props: FeatureBaseProps<{ + userContext?: UserContext; + }>, + useComponentOverrides?: () => GenericComponentOverrideMap + ) => JSX.Element; + getAuthComponents(): AuthComponent[]; + static reset(): void; + static TryRefreshPage: ( + props: FeatureBaseProps<{ + userContext?: UserContext; + }> + ) => JSX.Element; + static OAuth2LogoutScreen: ( + props: FeatureBaseProps<{ + userContext?: UserContext; + }> + ) => JSX.Element; +} +declare const TryRefreshPage: ( + props: FeatureBaseProps<{ + userContext?: UserContext; + }> +) => JSX.Element; +export { TryRefreshPage }; diff --git a/lib/build/recipe/oauth2provider/recipe.d.ts b/lib/build/recipe/oauth2provider/recipe.d.ts new file mode 100644 index 000000000..88f243b82 --- /dev/null +++ b/lib/build/recipe/oauth2provider/recipe.d.ts @@ -0,0 +1,30 @@ +import OAuth2WebJS from "supertokens-web-js/recipe/oauth2provider"; +import RecipeModule from "../recipeModule"; +import type { + GetRedirectionURLContext, + NormalisedConfig, + OnHandleEventContext, + PreAndPostAPIHookAction, + UserInput, +} from "./types"; +import type { RecipeInitResult, NormalisedConfigWithAppInfoAndRecipeID, WebJSRecipeInterface } from "../../types"; +export default class OAuth2Provider extends RecipeModule< + GetRedirectionURLContext, + PreAndPostAPIHookAction, + OnHandleEventContext, + NormalisedConfig +> { + readonly webJSRecipe: WebJSRecipeInterface; + static instance?: OAuth2Provider; + static readonly RECIPE_ID = "oauth2provider"; + readonly recipeID = "oauth2provider"; + constructor( + config: NormalisedConfigWithAppInfoAndRecipeID, + webJSRecipe?: WebJSRecipeInterface + ); + static init(config?: UserInput): RecipeInitResult; + static getInstanceOrThrow(): OAuth2Provider; + static getInstance(): OAuth2Provider | undefined; + getDefaultRedirectionURL(ctx: GetRedirectionURLContext): Promise; + static reset(): void; +} diff --git a/lib/build/recipe/oauth2provider/types.d.ts b/lib/build/recipe/oauth2provider/types.d.ts new file mode 100644 index 000000000..5296a489a --- /dev/null +++ b/lib/build/recipe/oauth2provider/types.d.ts @@ -0,0 +1,90 @@ +import type { OAuth2LogoutScreenInner } from "./components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner"; +import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; +import type { + NormalisedBaseConfig, + NormalisedGetRedirectionURLContext, + SuccessRedirectContextOAuth2, + UserContext, +} from "../../types"; +import type { + UserInput as RecipeModuleUserInput, + NormalisedConfig as NormalisedRecipeModuleConfig, +} from "../recipeModule/types"; +import type OverrideableBuilder from "supertokens-js-override"; +import type { LoginInfo, RecipeInterface } from "supertokens-web-js/recipe/oauth2provider/types"; +export declare type PreAndPostAPIHookAction = + | "GET_LOGIN_CHALLENGE_INFO" + | "GET_REDIRECT_URL_TO_CONTINUE_OAUTH_FLOW" + | "LOG_OUT"; +export declare type PreAPIHookContext = { + action: PreAndPostAPIHookAction; + requestInit: RequestInit; + url: string; + userContext: UserContext; +}; +export declare type UserInput = { + disableDefaultUI?: boolean; + oauth2LogoutScreen?: Partial; + tryRefreshPage?: Partial; + override?: { + functions?: ( + originalImplementation: RecipeInterface, + builder: OverrideableBuilder + ) => RecipeInterface; + }; +} & RecipeModuleUserInput; +export declare type NormalisedConfig = NormalisedRecipeModuleConfig< + GetRedirectionURLContext, + PreAndPostAPIHookAction, + OnHandleEventContext +> & { + disableDefaultUI: boolean; + oauth2LogoutScreen: OAuth2LogoutScreenConfig; + tryRefreshPage: OAuth2TryRefreshPageConfig; + override: { + functions: ( + originalImplementation: RecipeInterface, + builder: OverrideableBuilder + ) => RecipeInterface; + }; +}; +export declare type OAuth2LogoutScreenConfig = NormalisedBaseConfig & { + disableDefaultUI: boolean; +}; +export declare type OAuth2TryRefreshPageConfig = { + disableDefaultUI: boolean; +}; +export declare type ContinueOAuth2AfterRefreshRedirectContext = { + recipeId: "oauth2provider"; + action: "CONTINUE_OAUTH2_AFTER_REFRESH"; + frontendRedirectTo: string; +}; +export declare type PostOAuth2LogoutRedirectContext = { + recipeId: "oauth2provider"; + action: "POST_OAUTH2_LOGOUT_REDIRECT"; + frontendRedirectTo: string; +}; +export declare type GetRedirectionURLContext = NormalisedGetRedirectionURLContext< + SuccessRedirectContextOAuth2 | ContinueOAuth2AfterRefreshRedirectContext | PostOAuth2LogoutRedirectContext +>; +export declare type OnHandleEventContext = + | { + action: "LOADED_LOGIN_CHALLENGE"; + loginChallenge: string; + loginInfo: LoginInfo; + userContext: UserContext; + } + | { + action: "OAUTH2_LOGOUT_SUCCESS"; + frontendRedirectTo: string; + userContext: UserContext; + }; +export declare type ComponentOverrideMap = { + OAuth2LogoutScreenInner_Override?: ComponentOverride; +}; +export declare type OAuth2LogoutScreenThemeProps = { + config: NormalisedConfig; + isLoggingOut: boolean; + onLogoutClicked: () => void; + showSpinner: boolean; +}; diff --git a/lib/build/recipe/oauth2provider/utils.d.ts b/lib/build/recipe/oauth2provider/utils.d.ts new file mode 100644 index 000000000..1fbfafdf5 --- /dev/null +++ b/lib/build/recipe/oauth2provider/utils.d.ts @@ -0,0 +1,2 @@ +import type { UserInput, NormalisedConfig } from "./types"; +export declare function normaliseOAuth2Config(config?: UserInput): NormalisedConfig; diff --git a/lib/build/recipe/passwordless/components/features/signInAndUp/index.d.ts b/lib/build/recipe/passwordless/components/features/signInAndUp/index.d.ts index ac9b8560b..c04406f69 100644 --- a/lib/build/recipe/passwordless/components/features/signInAndUp/index.d.ts +++ b/lib/build/recipe/passwordless/components/features/signInAndUp/index.d.ts @@ -1,11 +1,13 @@ import * as React from "react"; import type { Navigate, UserContext, PartialAuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { ComponentOverrideMap } from "../../../types"; import type { SignInUpChildProps } from "../../../types"; export declare function useChildProps( recipe: Recipe, factorIds: string[], + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, diff --git a/lib/build/recipe/passwordless/components/features/signInAndUpEPCombo/index.d.ts b/lib/build/recipe/passwordless/components/features/signInAndUpEPCombo/index.d.ts index 4b6c409d5..ca36dd12e 100644 --- a/lib/build/recipe/passwordless/components/features/signInAndUpEPCombo/index.d.ts +++ b/lib/build/recipe/passwordless/components/features/signInAndUpEPCombo/index.d.ts @@ -1,11 +1,13 @@ import * as React from "react"; import type { Navigate, UserContext, PartialAuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { ComponentOverrideMap } from "../../../types"; import type { SignInUpEPComboChildProps } from "../../../types"; export declare function useChildProps( recipe: Recipe, factorIds: string[], + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, diff --git a/lib/build/recipe/passwordless/components/features/userInputCode/index.d.ts b/lib/build/recipe/passwordless/components/features/userInputCode/index.d.ts index 969a82dd9..438527b9c 100644 --- a/lib/build/recipe/passwordless/components/features/userInputCode/index.d.ts +++ b/lib/build/recipe/passwordless/components/features/userInputCode/index.d.ts @@ -1,10 +1,12 @@ import * as React from "react"; import type { Navigate, UserContext, AuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { ComponentOverrideMap, LoginAttemptInfo, SignInUpUserInputCodeFormProps } from "../../../types"; export declare function useChildProps( recipe: Recipe, loginAttemptInfo: LoginAttemptInfo, + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, diff --git a/lib/build/recipe/passwordless/components/themes/translations.d.ts b/lib/build/recipe/passwordless/components/themes/translations.d.ts index d60b40a2e..d1ddad9ec 100644 --- a/lib/build/recipe/passwordless/components/themes/translations.d.ts +++ b/lib/build/recipe/passwordless/components/themes/translations.d.ts @@ -58,6 +58,7 @@ export declare const defaultTranslationsPasswordless: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/passwordless/index.d.ts b/lib/build/recipe/passwordless/index.d.ts index 0bf17133d..ca5a32715 100644 --- a/lib/build/recipe/passwordless/index.d.ts +++ b/lib/build/recipe/passwordless/index.d.ts @@ -20,11 +20,13 @@ export default class Wrapper { input: | { email: string; + shouldTryLinkingWithSessionUser?: boolean; userContext?: UserContext; options?: RecipeFunctionOptions; } | { phoneNumber: string; + shouldTryLinkingWithSessionUser?: boolean; userContext?: UserContext; options?: RecipeFunctionOptions; } diff --git a/lib/build/recipe/passwordless/prebuiltui.d.ts b/lib/build/recipe/passwordless/prebuiltui.d.ts index 18238e194..10c96a0a5 100644 --- a/lib/build/recipe/passwordless/prebuiltui.d.ts +++ b/lib/build/recipe/passwordless/prebuiltui.d.ts @@ -69,6 +69,7 @@ export declare class PasswordlessPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/recipeModule/index.d.ts b/lib/build/recipe/recipeModule/index.d.ts index ff126debf..c83e68e16 100644 --- a/lib/build/recipe/recipeModule/index.d.ts +++ b/lib/build/recipe/recipeModule/index.d.ts @@ -1,6 +1,6 @@ import { BaseRecipeModule } from "./baseRecipeModule"; import type { NormalisedConfig } from "./types"; -import type { Navigate, UserContext } from "../../types"; +import type { Navigate, NormalisedGetRedirectionURLContext, UserContext } from "../../types"; export default abstract class RecipeModule< GetRedirectionURLContextType, Action, @@ -8,11 +8,17 @@ export default abstract class RecipeModule< N extends NormalisedConfig > extends BaseRecipeModule { redirect: ( - context: GetRedirectionURLContextType, + context: NormalisedGetRedirectionURLContext, navigate?: Navigate, queryParams?: Record, userContext?: UserContext ) => Promise; - getRedirectUrl: (context: GetRedirectionURLContextType, userContext: UserContext) => Promise; - getDefaultRedirectionURL(_: GetRedirectionURLContextType, _userContext: UserContext): Promise; + getRedirectUrl: ( + context: NormalisedGetRedirectionURLContext, + userContext: UserContext + ) => Promise; + getDefaultRedirectionURL( + _: NormalisedGetRedirectionURLContext, + _userContext: UserContext + ): Promise; } diff --git a/lib/build/recipe/recipeModule/types.d.ts b/lib/build/recipe/recipeModule/types.d.ts index 968d0008d..3df75b39f 100644 --- a/lib/build/recipe/recipeModule/types.d.ts +++ b/lib/build/recipe/recipeModule/types.d.ts @@ -1,4 +1,4 @@ -import type { UserContext } from "../../types"; +import type { NormalisedGetRedirectionURLContext, UserContext } from "../../types"; export declare type RecipePreAPIHookContext = { requestInit: RequestInit; url: string; @@ -20,7 +20,7 @@ export declare type RecipePostAPIHookFunction = (context: RecipePostAPIH export declare type RecipeOnHandleEventFunction = (context: EventType) => void; export declare type UserInput = { getRedirectionURL?: ( - context: GetRedirectionURLContextType, + context: NormalisedGetRedirectionURLContext, userContext: UserContext ) => Promise; preAPIHook?: RecipePreAPIHookFunction; @@ -35,7 +35,7 @@ export declare type Config; export declare type NormalisedConfig = { getRedirectionURL: ( - context: GetRedirectionURLContextType, + context: NormalisedGetRedirectionURLContext, userContext: UserContext ) => Promise; onHandleEvent: RecipeOnHandleEventFunction; diff --git a/lib/build/recipe/session/components/themes/translations.d.ts b/lib/build/recipe/session/components/themes/translations.d.ts index 40c73700a..ba13878f9 100644 --- a/lib/build/recipe/session/components/themes/translations.d.ts +++ b/lib/build/recipe/session/components/themes/translations.d.ts @@ -6,6 +6,7 @@ export declare const defaultTranslationsSession: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/session/prebuiltui.d.ts b/lib/build/recipe/session/prebuiltui.d.ts index fb829532d..85559c54b 100644 --- a/lib/build/recipe/session/prebuiltui.d.ts +++ b/lib/build/recipe/session/prebuiltui.d.ts @@ -16,6 +16,7 @@ export declare class SessionPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/session/recipe.d.ts b/lib/build/recipe/session/recipe.d.ts index 536d3cae5..674e168a9 100644 --- a/lib/build/recipe/session/recipe.d.ts +++ b/lib/build/recipe/session/recipe.d.ts @@ -7,7 +7,8 @@ import type { Navigate, NormalisedConfigWithAppInfoAndRecipeID, RecipeInitResult, - SuccessRedirectContext, + SuccessRedirectContextInApp, + SuccessRedirectContextOAuth2, UserContext, } from "../../types"; import type { ClaimValidationError, SessionClaimValidator } from "supertokens-web-js/recipe/session"; @@ -52,14 +53,15 @@ export default class Session extends RecipeModule void) => () => void; validateGlobalClaimsAndHandleSuccessRedirection: ( successRedirectContext: - | (Omit & { + | ((Omit | Omit) & { recipeId: string; + tenantIdFromQueryParams: string | undefined; }) | undefined, fallbackRecipeId: string, - redirectToPath?: string, - userContext?: UserContext, - navigate?: Navigate + redirectToPath: string | undefined, + userContext: UserContext | undefined, + navigate: Navigate | undefined ) => Promise; /** * This should only get called if validateGlobalClaimsAndHandleSuccessRedirection couldn't get a redirectInfo diff --git a/lib/build/recipe/thirdparty/components/features/signInAndUp/index.d.ts b/lib/build/recipe/thirdparty/components/features/signInAndUp/index.d.ts index 55967b373..554676d75 100644 --- a/lib/build/recipe/thirdparty/components/features/signInAndUp/index.d.ts +++ b/lib/build/recipe/thirdparty/components/features/signInAndUp/index.d.ts @@ -1,9 +1,11 @@ import * as React from "react"; import type { Navigate, PartialAuthComponentProps, UserContext } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { ComponentOverrideMap, SignInAndUpThemeProps } from "../../../types"; export declare function useChildProps( recipe: Recipe, + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, diff --git a/lib/build/recipe/thirdparty/components/themes/translations.d.ts b/lib/build/recipe/thirdparty/components/themes/translations.d.ts index f42500509..426312d4d 100644 --- a/lib/build/recipe/thirdparty/components/themes/translations.d.ts +++ b/lib/build/recipe/thirdparty/components/themes/translations.d.ts @@ -13,6 +13,7 @@ export declare const defaultTranslationsThirdParty: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/thirdparty/index.d.ts b/lib/build/recipe/thirdparty/index.d.ts index 6b8fb2194..6b2d6695f 100644 --- a/lib/build/recipe/thirdparty/index.d.ts +++ b/lib/build/recipe/thirdparty/index.d.ts @@ -31,7 +31,11 @@ export default class Wrapper { import("./types").NormalisedConfig >; static signOut(input?: { userContext?: UserContext }): Promise; - static redirectToThirdPartyLogin(input: { thirdPartyId: string; userContext?: UserContext }): Promise<{ + static redirectToThirdPartyLogin(input: { + thirdPartyId: string; + shouldTryLinkingWithSessionUser?: boolean; + userContext?: UserContext; + }): Promise<{ status: "OK" | "ERROR"; }>; static getStateAndOtherInfoFromStorage(input?: { @@ -41,6 +45,7 @@ export default class Wrapper { thirdPartyId: string; frontendRedirectURI: string; redirectURIOnProviderDashboard?: string; + shouldTryLinkingWithSessionUser?: boolean; userContext?: UserContext; options?: RecipeFunctionOptions; }): Promise; diff --git a/lib/build/recipe/thirdparty/prebuiltui.d.ts b/lib/build/recipe/thirdparty/prebuiltui.d.ts index 0ae83b7e5..4c3899d89 100644 --- a/lib/build/recipe/thirdparty/prebuiltui.d.ts +++ b/lib/build/recipe/thirdparty/prebuiltui.d.ts @@ -23,6 +23,7 @@ export declare class ThirdPartyPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/thirdparty/types.d.ts b/lib/build/recipe/thirdparty/types.d.ts index 91531ef39..68867e1c1 100644 --- a/lib/build/recipe/thirdparty/types.d.ts +++ b/lib/build/recipe/thirdparty/types.d.ts @@ -81,4 +81,5 @@ export declare type StateObject = WebJsStateObject & { export declare type CustomStateProperties = { rid: string; redirectToPath: string; + oauth2LoginChallenge?: string; }; diff --git a/lib/build/recipe/thirdparty/utils.d.ts b/lib/build/recipe/thirdparty/utils.d.ts index b6324cf67..3611a90b9 100644 --- a/lib/build/recipe/thirdparty/utils.d.ts +++ b/lib/build/recipe/thirdparty/utils.d.ts @@ -17,6 +17,7 @@ export declare function redirectToThirdPartyLogin(input: { thirdPartyId: string; config: NormalisedConfig; userContext: UserContext; + shouldTryLinkingWithSessionUser: boolean | undefined; recipeImplementation: WebJSRecipeInterface; }): Promise<{ status: "OK" | "ERROR"; diff --git a/lib/build/recipe/totp/components/themes/translations.d.ts b/lib/build/recipe/totp/components/themes/translations.d.ts index 949499447..34fbb59e6 100644 --- a/lib/build/recipe/totp/components/themes/translations.d.ts +++ b/lib/build/recipe/totp/components/themes/translations.d.ts @@ -25,6 +25,7 @@ export declare const defaultTranslationsTOTP: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/recipe/totp/prebuiltui.d.ts b/lib/build/recipe/totp/prebuiltui.d.ts index 7799b5f0a..690aa7282 100644 --- a/lib/build/recipe/totp/prebuiltui.d.ts +++ b/lib/build/recipe/totp/prebuiltui.d.ts @@ -35,6 +35,7 @@ export declare class TOTPPreBuiltUI extends RecipeRouter { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/session.js b/lib/build/session.js index ed2d033bb..9fb87e239 100644 --- a/lib/build/session.js +++ b/lib/build/session.js @@ -17,6 +17,8 @@ require("react"); require("supertokens-web-js/utils/normalisedURLDomain"); require("supertokens-web-js/utils/normalisedURLPath"); require("react/jsx-runtime"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./recipeModule-shared.js"); require("./translationContext.js"); require("react-dom"); diff --git a/lib/build/sessionprebuiltui.js b/lib/build/sessionprebuiltui.js index 027537737..8592885bb 100644 --- a/lib/build/sessionprebuiltui.js +++ b/lib/build/sessionprebuiltui.js @@ -22,6 +22,8 @@ require("./multifactorauth-shared2.js"); require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); require("supertokens-web-js/recipe/session"); @@ -83,7 +85,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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n\n/* Override */\n\n[data-supertokens~="accessDenied"] [data-supertokens~="row"] {\n padding-bottom: 24px;\n}\n\n[data-supertokens~="accessDenied"] [data-supertokens~="divider"] {\n padding: 0;\n margin: 34px 0 18px 0;\n}\n\n[data-supertokens~="accessDenied"] [data-supertokens~="headerTitle"] {\n margin: 10px 0 0 0;\n font-style: normal;\n font-weight: 600;\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: 34px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n[data-supertokens~="buttonBase"] {\n font-family: "Arial", sans-serif;\n font-size: var(--font-size-1);\n line-height: 21px;\n font-weight: 400;\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\n[data-supertokens~="primaryText"][data-supertokens~="accessDeniedError"] {\n font-weight: 400;\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n\n/*\n * Default styles.\n */\n\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n\n[data-supertokens~="container"] {\n font-family: "Arial", 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: 10px auto 0;\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: 400;\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: 10px;\n margin-top: 24px;\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 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: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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-2);\n font-weight: 400;\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: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\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 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 font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\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 font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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 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[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n\n/* Override */\n\n[data-supertokens~="accessDenied"] [data-supertokens~="row"] {\n padding-bottom: 24px;\n}\n\n[data-supertokens~="accessDenied"] [data-supertokens~="divider"] {\n padding: 0;\n margin: 34px 0 18px 0;\n}\n\n[data-supertokens~="accessDenied"] [data-supertokens~="headerTitle"] {\n margin: 10px 0 0 0;\n font-style: normal;\n font-weight: 600;\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: 34px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n}\n\n[data-supertokens~="buttonBase"] {\n font-family: "Arial", sans-serif;\n font-size: var(--font-size-1);\n line-height: 21px;\n font-weight: 400;\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\n[data-supertokens~="primaryText"][data-supertokens~="accessDeniedError"] {\n font-weight: 400;\n}\n'; var ThemeBase = function (_a) { var children = _a.children, diff --git a/lib/build/superTokens.d.ts b/lib/build/superTokens.d.ts index 6fa48b469..3d5293d6d 100644 --- a/lib/build/superTokens.d.ts +++ b/lib/build/superTokens.d.ts @@ -3,7 +3,14 @@ import type RecipeModule from "./recipe/recipeModule"; import type { BaseRecipeModule } from "./recipe/recipeModule/baseRecipeModule"; import type { NormalisedConfig as NormalisedRecipeModuleConfig } from "./recipe/recipeModule/types"; import type { TranslationFunc, TranslationStore } from "./translation/translationHelpers"; -import type { Navigate, GetRedirectionURLContext, NormalisedAppInfo, SuperTokensConfig, UserContext } from "./types"; +import type { + Navigate, + GetRedirectionURLContext, + NormalisedAppInfo, + SuperTokensConfig, + UserContext, + NormalisedGetRedirectionURLContext, +} from "./types"; export default class SuperTokens { private static instance?; static usesDynamicLoginMethods: boolean; @@ -31,7 +38,10 @@ export default class SuperTokens { ): RecipeModule; changeLanguage: (lang: string) => Promise; loadTranslation(store: TranslationStore): void; - getRedirectUrl(context: GetRedirectionURLContext, userContext: UserContext): Promise; + getRedirectUrl( + context: NormalisedGetRedirectionURLContext, + userContext: UserContext + ): Promise; redirectToAuth: (options: { show?: "signin" | "signup" | undefined; navigate?: Navigate | undefined; @@ -41,7 +51,7 @@ export default class SuperTokens { }) => Promise; redirectToUrl: (redirectUrl: string, navigate?: Navigate) => Promise; redirect: ( - context: GetRedirectionURLContext, + context: NormalisedGetRedirectionURLContext, navigate?: Navigate, queryParams?: Record, userContext?: UserContext diff --git a/lib/build/thirdparty-shared.js b/lib/build/thirdparty-shared.js index 7f41ec363..c46ce4926 100644 --- a/lib/build/thirdparty-shared.js +++ b/lib/build/thirdparty-shared.js @@ -1690,10 +1690,19 @@ var getFunctionOverrides = function (recipeId, onHandleEvent) { }); }, setStateAndOtherInfoToStorage: function (input) { + var _a; + var loginChallenge = + (_a = genericComponentOverrideContext.getQueryParams("loginChallenge")) !== null && _a !== void 0 + ? _a + : undefined; return originalImp.setStateAndOtherInfoToStorage({ state: genericComponentOverrideContext.__assign( genericComponentOverrideContext.__assign({}, input.state), - { rid: recipeId, redirectToPath: genericComponentOverrideContext.getRedirectToPathFromURL() } + { + rid: recipeId, + oauth2LoginChallenge: loginChallenge, + redirectToPath: genericComponentOverrideContext.getRedirectToPathFromURL(), + } ), userContext: input.userContext, }); @@ -1856,6 +1865,7 @@ function redirectToThirdPartyLogin(input) { thirdPartyId: input.thirdPartyId, frontendRedirectURI: provider.getRedirectURL(), redirectURIOnProviderDashboard: provider.getRedirectURIOnProviderDashboard(), + shouldTryLinkingWithSessionUser: input.shouldTryLinkingWithSessionUser, userContext: input.userContext, }), ]; diff --git a/lib/build/thirdparty.js b/lib/build/thirdparty.js index 287ebc3ca..028c8b170 100644 --- a/lib/build/thirdparty.js +++ b/lib/build/thirdparty.js @@ -19,6 +19,8 @@ require("./authRecipe-shared2.js"); require("./recipeModule-shared.js"); require("./multifactorauth-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./authRecipe-shared.js"); require("./translationContext.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); @@ -70,6 +72,7 @@ var Wrapper = /** @class */ (function () { thirdPartyId: input.thirdPartyId, config: recipeInstance.config, userContext: genericComponentOverrideContext.getNormalisedUserContext(input.userContext), + shouldTryLinkingWithSessionUser: input.shouldTryLinkingWithSessionUser, recipeImplementation: recipeInstance.webJSRecipe, }), ]; diff --git a/lib/build/thirdpartyprebuiltui.js b/lib/build/thirdpartyprebuiltui.js index 994a44195..c6f19d687 100644 --- a/lib/build/thirdpartyprebuiltui.js +++ b/lib/build/thirdpartyprebuiltui.js @@ -12,7 +12,8 @@ var authCompWrapper = require("./authCompWrapper.js"); var types = require("./multifactorauth-shared.js"); var STGeneralError = require("supertokens-web-js/utils/error"); var emailverification = require("./emailverification.js"); -var recipe$1 = require("./emailverification-shared.js"); +var recipe$2 = require("./emailverification-shared.js"); +var recipe$1 = require("./oauth2provider-shared.js"); require("supertokens-web-js"); require("supertokens-web-js/utils/cookieHandler"); require("supertokens-web-js/utils/postSuperTokensInitCallbacks"); @@ -35,6 +36,7 @@ require("./session-shared.js"); require("supertokens-web-js/recipe/thirdparty"); require("./authRecipe-shared2.js"); require("supertokens-web-js/recipe/emailverification"); +require("supertokens-web-js/recipe/oauth2provider"); function _interopDefault(e) { return e && e.__esModule ? e : { default: e }; @@ -71,7 +73,7 @@ var React__namespace = /*#__PURE__*/ _interopNamespace(React); var STGeneralError__default = /*#__PURE__*/ _interopDefault(STGeneralError); var styles = - '[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n[data-supertokens~="providerContainer"] {\n padding-top: 9px;\n padding-bottom: 9px;\n\n --logo-size: 34px;\n --logo-horizontal-spacing: 8px;\n}\n[data-supertokens~="button"][data-supertokens~="providerButton"] {\n min-height: 32px;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n padding: 2px calc(var(--logo-size) + 2 * var(--logo-horizontal-spacing));\n background-color: white;\n border-color: rgb(221, 221, 221);\n color: black;\n position: relative;\n}\n[data-supertokens~="button"][data-supertokens~="providerButton"]:hover {\n filter: none;\n background-color: #fafafa;\n}\n[data-supertokens~="providerButtonLeft"] {\n width: calc(var(--logo-size));\n position: absolute;\n left: calc(var(--logo-horizontal-spacing));\n}\n[data-supertokens~="providerButtonLogo"] {\n height: 30px;\n display: flex;\n align-items: center;\n}\n[data-supertokens~="providerButtonLogoCenter"] {\n display: flex;\n margin: auto;\n}\n[data-supertokens~="providerButtonText"] {\n font-weight: 400;\n text-align: center;\n justify-content: center;\n overflow: hidden;\n white-space: nowrap;\n display: inline-block;\n flex-grow: 1;\n max-width: 100%;\n font-size: var(--font-size-1);\n text-overflow: ellipsis;\n}\n.scroll-text-animation:hover span,\n.scroll-text-animation:focus span {\n display: inline-block;\n animation: scroll-left 2s linear forwards;\n position: relative;\n width: -webkit-fit-content;\n width: -moz-fit-content;\n width: fit-content;\n text-overflow: clip;\n}\n@keyframes scroll-left {\n 0% {\n transform: translateX(0);\n left: 0%;\n }\n 50% {\n transform: translateX(calc(-100% - 10px));\n left: 100%;\n }\n 100% {\n transform: translateX(calc(-100% - 10px));\n left: 100%;\n }\n}\n@media (max-width: 640px) {\n [data-supertokens~="providerButtonText"] {\n font-size: var(--font-size-0);\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\n}\n[data-supertokens~="providerContainer"] {\n padding-top: 9px;\n padding-bottom: 9px;\n\n --logo-size: 34px;\n --logo-horizontal-spacing: 8px;\n}\n[data-supertokens~="button"][data-supertokens~="providerButton"] {\n min-height: 32px;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n padding: 2px calc(var(--logo-size) + 2 * var(--logo-horizontal-spacing));\n background-color: white;\n border-color: rgb(221, 221, 221);\n color: black;\n position: relative;\n}\n[data-supertokens~="button"][data-supertokens~="providerButton"]:hover {\n filter: none;\n background-color: #fafafa;\n}\n[data-supertokens~="providerButtonLeft"] {\n width: calc(var(--logo-size));\n position: absolute;\n left: calc(var(--logo-horizontal-spacing));\n}\n[data-supertokens~="providerButtonLogo"] {\n height: 30px;\n display: flex;\n align-items: center;\n}\n[data-supertokens~="providerButtonLogoCenter"] {\n display: flex;\n margin: auto;\n}\n[data-supertokens~="providerButtonText"] {\n font-weight: 400;\n text-align: center;\n justify-content: center;\n overflow: hidden;\n white-space: nowrap;\n display: inline-block;\n flex-grow: 1;\n max-width: 100%;\n font-size: var(--font-size-1);\n text-overflow: ellipsis;\n}\n.scroll-text-animation:hover span,\n.scroll-text-animation:focus span {\n display: inline-block;\n animation: scroll-left 2s linear forwards;\n position: relative;\n width: -webkit-fit-content;\n width: -moz-fit-content;\n width: fit-content;\n text-overflow: clip;\n}\n@keyframes scroll-left {\n 0% {\n transform: translateX(0);\n left: 0%;\n }\n 50% {\n transform: translateX(calc(-100% - 10px));\n left: 100%;\n }\n 100% {\n transform: translateX(calc(-100% - 10px));\n left: 100%;\n }\n}\n@media (max-width: 640px) {\n [data-supertokens~="providerButtonText"] {\n font-size: var(--font-size-0);\n }\n}\n'; var ThemeBase = function (_a) { var children = _a.children, @@ -101,6 +103,7 @@ var ThirdPartySignInAndUpProvidersForm = function (props) { recipeImplementation: props.recipeImplementation, thirdPartyId: providerId, config: props.config, + shouldTryLinkingWithSessionUser: false, userContext: userContext, }), ]; @@ -189,7 +192,17 @@ var SignInAndUpThemeWrapper = function (props) { ); }; -function useChildProps(recipe$1, error, onError, clearError, rebuildAuthPage, setFactorList, navigate, userContext) { +function useChildProps( + recipe$1, + onAuthSuccess, + error, + onError, + clearError, + rebuildAuthPage, + setFactorList, + navigate, + userContext +) { var recipeImplementation = React.useMemo( function () { return recipe$1 && getModifiedRecipeImplementation(recipe$1.webJSRecipe); @@ -210,6 +223,7 @@ function useChildProps(recipe$1, error, onError, clearError, rebuildAuthPage, se } } return { + onAuthSuccess: onAuthSuccess, error: error, onError: onError, clearError: clearError, @@ -232,6 +246,7 @@ function useChildProps(recipe$1, error, onError, clearError, rebuildAuthPage, se var SignInAndUpFeature = function (props) { var childProps = useChildProps( props.recipe, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -407,7 +422,14 @@ var SignInAndUpCallback$1 = function (props) { var response = _a.response, payloadBeforeCall = _a.payloadBeforeCall; return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () { - var payloadAfterCall, stateResponse, redirectToPath; + var payloadAfterCall, + stateResponse, + redirectToPath, + loginChallenge, + ctx, + oauth2Recipe, + frontendRedirectTo, + e_1; return genericComponentOverrideContext.__generator(this, function (_c) { switch (_c.label) { case 0: @@ -438,7 +460,7 @@ var SignInAndUpCallback$1 = function (props) { }), ]; } - if (!(response.status === "OK")) return [3 /*break*/, 5]; + if (!(response.status === "OK")) return [3 /*break*/, 10]; payloadAfterCall = void 0; _c.label = 1; case 1: @@ -461,22 +483,63 @@ var SignInAndUpCallback$1 = function (props) { userContext: userContext, }); redirectToPath = stateResponse === undefined ? undefined : stateResponse.redirectToPath; + loginChallenge = + stateResponse === null || stateResponse === void 0 + ? void 0 + : stateResponse.oauth2LoginChallenge; + ctx = { + createdNewUser: + response.createdNewRecipeUser && response.user.loginMethods.length === 1, + isNewRecipeUser: response.createdNewRecipeUser, + newSessionCreated: + payloadAfterCall !== undefined && + (payloadBeforeCall === undefined || + payloadBeforeCall.sessionHandle !== payloadAfterCall.sessionHandle), + recipeId: props.recipe.recipeID, + tenantIdFromQueryParams: genericComponentOverrideContext.getTenantIdFromQueryParams(), + }; + oauth2Recipe = recipe$1.OAuth2Provider.getInstance(); + if (!(loginChallenge !== undefined && oauth2Recipe !== undefined)) return [3 /*break*/, 9]; + _c.label = 5; + case 5: + _c.trys.push([5, 7, , 8]); + return [ + 4 /*yield*/, + oauth2Recipe.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge: loginChallenge, + userContext: userContext, + }), + ]; + case 6: + frontendRedirectTo = _c.sent().frontendRedirectTo; + return [ + 2 /*return*/, + types.Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, ctx), + { action: "SUCCESS_OAUTH2", frontendRedirectTo: frontendRedirectTo } + ), + props.recipe.recipeID, + redirectToPath, + userContext, + props.navigate + ), + ]; + case 7: + e_1 = _c.sent(); + rethrowInRender(e_1); + return [3 /*break*/, 8]; + case 8: + return [3 /*break*/, 10]; + case 9: return [ 2 /*return*/, types.Session.getInstanceOrThrow() .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: - response.createdNewRecipeUser && - response.user.loginMethods.length === 1, - isNewRecipeUser: response.createdNewRecipeUser, - newSessionCreated: - payloadAfterCall !== undefined && - (payloadBeforeCall === undefined || - payloadBeforeCall.sessionHandle !== payloadAfterCall.sessionHandle), - recipeId: props.recipe.recipeID, - }, + genericComponentOverrideContext.__assign( + genericComponentOverrideContext.__assign({}, ctx), + { action: "SUCCESS" } + ), props.recipe.recipeID, redirectToPath, userContext, @@ -484,7 +547,7 @@ var SignInAndUpCallback$1 = function (props) { ) .catch(rethrowInRender), ]; - case 5: + case 10: return [2 /*return*/]; } }); @@ -521,12 +584,14 @@ var SignInAndUpCallback$1 = function (props) { _b.label = 2; case 2: _b.trys.push([2, 4, , 5]); - evInstance = recipe$1.EmailVerification.getInstanceOrThrow(); + evInstance = recipe$2.EmailVerification.getInstanceOrThrow(); return [ 4 /*yield*/, evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: + genericComponentOverrideContext.getTenantIdFromQueryParams(), }, props.navigate, undefined, diff --git a/lib/build/totp.js b/lib/build/totp.js index 12f9d30d9..05a5da4c6 100644 --- a/lib/build/totp.js +++ b/lib/build/totp.js @@ -21,6 +21,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); require("./multifactorauth-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); /* Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved. * diff --git a/lib/build/totpprebuiltui.js b/lib/build/totpprebuiltui.js index e14197492..52dda6640 100644 --- a/lib/build/totpprebuiltui.js +++ b/lib/build/totpprebuiltui.js @@ -23,12 +23,14 @@ require("supertokens-web-js/utils"); require("supertokens-web-js/utils/normalisedURLDomain"); require("react-dom"); require("./multitenancy-shared.js"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); +require("./recipeModule-shared.js"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); require("supertokens-web-js/recipe/session"); require("./session-shared.js"); require("supertokens-web-js/recipe/totp"); -require("./recipeModule-shared.js"); require("supertokens-web-js/recipe/multifactorauth"); require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./emailpassword-shared4.js"); @@ -69,7 +71,7 @@ var React__namespace = /*#__PURE__*/ _interopNamespace(React); var STGeneralError__default = /*#__PURE__*/ _interopDefault(STGeneralError); var styles = - '[data-supertokens~="container"] {\n --palette-background: 255, 255, 255;\n --palette-inputBackground: 250, 250, 250;\n --palette-inputBorder: 224, 224, 224;\n --palette-primary: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\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[data-supertokens~="inputContainer"] {\n margin-top: 6px;\n}\n[data-supertokens~="inputWrapper"] {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n align-items: center;\n background-color: rgb(var(--palette-inputBackground));\n height: 34px;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n}\n[data-supertokens~="inputWrapper"][focus-within] {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n[data-supertokens~="inputWrapper"]:focus-within {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n[data-supertokens~="inputError"] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n[data-supertokens~="inputError"][focus-within] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n[data-supertokens~="inputError"]:focus-within {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n[data-supertokens~="input"] {\n box-sizing: border-box;\n padding-left: 15px;\n filter: none;\n color: rgb(var(--palette-textInput));\n background-color: transparent;\n border-radius: 6px;\n font-size: var(--font-size-1);\n border: none;\n padding-right: 25px;\n letter-spacing: 1.2px;\n flex: 9 1 75%;\n width: 75%;\n height: 32px;\n}\n[data-supertokens~="input"]:focus {\n border: none;\n outline: none;\n}\n[data-supertokens~="input"]:-webkit-autofill,\n[data-supertokens~="input"]:-webkit-autofill:hover,\n[data-supertokens~="input"]:-webkit-autofill:focus,\n[data-supertokens~="input"]:-webkit-autofill:active {\n -webkit-text-fill-color: rgb(var(--palette-textInput));\n box-shadow: 0 0 0 30px rgb(var(--palette-inputBackground)) inset;\n}\n[data-supertokens~="inputAdornment"] {\n justify-content: center;\n margin-right: 5px;\n}\n[data-supertokens~="showPassword"] {\n cursor: pointer;\n}\n[data-supertokens~="enterEmailSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n word-break: break-word;\n}\n[data-supertokens~="submitNewPasswordSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n[data-supertokens~="inputErrorMessage"] {\n padding-top: 5px;\n padding-bottom: 5px;\n color: rgb(var(--palette-error));\n line-height: 24px;\n font-weight: 400;\n font-size: var(--font-size-1);\n text-align: left;\n animation: slideTop 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\n max-width: 330px;\n}\n@media (max-width: 440px) {\n [data-supertokens~="inputErrorMessage"] {\n max-width: 250px;\n }\n}\n[data-supertokens~="inputErrorSymbol"] {\n margin-right: 5px;\n top: 1px;\n position: relative;\n left: 2px;\n}\n[data-supertokens~="label"] {\n text-align: left;\n font-weight: 700;\n font-size: var(--font-size-0);\n line-height: 24px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="formRow"] {\n display: flex;\n flex-direction: column;\n padding-top: 0px;\n padding-bottom: 20px;\n}\n[data-supertokens~="formRow"][data-supertokens~="hasError"] {\n padding-bottom: 0;\n}\n[data-supertokens~="formRow"]:last-child {\n padding-bottom: 0;\n}\n[data-supertokens~="sendVerifyEmailIcon"] {\n margin-top: 11px;\n}\n[data-supertokens~="primaryText"][data-supertokens~="sendVerifyEmailText"] {\n text-align: center;\n letter-spacing: 0.8px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n font-weight: 700;\n}\n[data-supertokens~="sendVerifyEmailResend"] {\n margin-top: 13px;\n font-weight: 400;\n}\n[data-supertokens~="sendVerifyEmailResend"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="noFormRow"] {\n padding-bottom: 25px;\n}\n[data-supertokens~="emailVerificationButtonWrapper"] {\n padding-top: 25px;\n max-width: 96px;\n margin: 0 auto;\n}\n[data-supertokens~="resendEmailLink"] {\n display: inline-block;\n}\n[data-supertokens~="resetPasswordEmailForm"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="resetPasswordPasswordForm"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="totp"] [data-supertokens~="container"] {\n padding-top: 24px;\n}\n[data-supertokens~="totp"] [data-supertokens~="divider"] {\n margin-top: 20px;\n margin-bottom: 20px;\n}\n[data-supertokens~="totp"] [data-supertokens~="row"] {\n padding-top: 16px;\n padding-bottom: 8px;\n width: auto;\n margin: 0 50px;\n}\n[data-supertokens~="totpDeviceQR"] {\n border-radius: 12px;\n border: 1px solid rgb(var(--palette-inputBorder));\n padding: 16px;\n max-width: 172px;\n max-height: 172px;\n}\n[data-supertokens~="showTOTPSecret"] {\n display: block;\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-0);\n margin: 16px 0 12px;\n}\n[data-supertokens~="totpSecret"] {\n display: block;\n border-radius: 6px;\n padding: 7px 15px;\n color: rgb(var(--palette-textLink));\n font-size: var(--font-size-1);\n font-weight: 600;\n letter-spacing: 3.36px;\n background: rgba(var(--palette-textLink), 0.08);\n word-wrap: break-word;\n overflow-y: hidden;\n}\nbutton[data-supertokens~="showTOTPSecretBtn"] {\n font-size: 12px;\n}\n[data-supertokens~="showTOTPSecretBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="retryCodeBtn"]:disabled {\n border: 0;\n border-radius: 6px;\n color: rgb(var(--palette-error));\n background: rgb(var(--palette-errorBackground));\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: 28, 34, 42;\n --palette-primaryBorder: 45, 54, 68;\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: 0, 0, 0;\n --palette-textLabel: 0, 0, 0;\n --palette-textInput: 0, 0, 0;\n --palette-textPrimary: 128, 128, 128;\n --palette-textLink: 0, 122, 255;\n --palette-buttonText: 255, 255, 255;\n --palette-textGray: 54, 54, 54;\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 --font-size-5: 28px;\n}\n/*\n * Default styles.\n */\n@keyframes slideTop {\n 0% {\n transform: translateY(-5px);\n }\n 100% {\n transform: translateY(0px);\n }\n}\n@keyframes swing-in-top-fwd {\n 0% {\n transform: rotateX(-100deg);\n transform-origin: top;\n opacity: 0;\n }\n 100% {\n transform: rotateX(0deg);\n transform-origin: top;\n opacity: 1;\n }\n}\n[data-supertokens~="container"] {\n font-family: "Arial", 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@media (max-width: 440px) {\n [data-supertokens~="container"] {\n width: 95vw;\n }\n}\n[data-supertokens~="row"] {\n margin: 0 auto;\n width: 76%;\n padding-top: 30px;\n padding-bottom: 10px;\n}\n[data-supertokens~="superTokensBranding"] {\n display: block;\n margin: 10px auto 0;\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: 400;\n font-size: var(--font-size-0);\n letter-spacing: 0.4px;\n}\n[data-supertokens~="generalError"] {\n background: rgb(var(--palette-errorBackground));\n padding-top: 10px;\n padding-bottom: 10px;\n margin-bottom: 10px;\n margin-top: 24px;\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 animation: swing-in-top-fwd 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;\n word-wrap: break-word;\n}\n[data-supertokens~="headerTitle"] {\n font-size: var(--font-size-4);\n line-height: 27.6px;\n letter-spacing: 0.58px;\n font-weight: 700;\n margin-bottom: 20px;\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="headerSubtitle"] {\n font-weight: 400;\n color: rgb(var(--palette-textGray));\n margin-bottom: 21px;\n}\n[data-supertokens~="headerSubtitle"][data-supertokens~="secondaryText"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] {\n max-width: 300px;\n margin-top: 10px;\n}\n[data-supertokens~="privacyPolicyAndTermsAndConditions"] a {\n line-height: 21px;\n}\n/* TODO: split the link style into separate things*/\n/* We add this before primary and secondary text, because if they are applied to the same element the other ones take priority */\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[data-supertokens~="primaryText"] {\n font-size: var(--font-size-2);\n font-weight: 400;\n letter-spacing: 0.4px;\n line-height: 21px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="secondaryText"] {\n font-size: var(--font-size-1);\n font-weight: 400;\n letter-spacing: 0.4px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryText"] strong {\n font-weight: 600;\n}\n[data-supertokens~="divider"] {\n margin-top: 1.5em;\n margin-bottom: 1.5em;\n border-bottom: 0.3px solid #dddddd;\n align-items: center;\n padding-bottom: 5px;\n flex: 3 3;\n}\n[data-supertokens~="headerTinyTitle"] {\n margin-top: 24px;\n font-size: var(--font-size-5);\n letter-spacing: 1.1px;\n font-weight: 700;\n line-height: 28px;\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithArrow"]:hover {\n position: relative;\n left: 2px;\n word-spacing: 4px;\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 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[data-supertokens~="spinner"] {\n width: 80px;\n height: auto;\n padding-top: 20px;\n padding-bottom: 40px;\n margin: 0 auto;\n}\n[data-supertokens~="error"] {\n color: rgb(var(--palette-error));\n}\n[data-supertokens~="linkButton"] {\n font-family: "Arial", sans-serif;\n background-color: transparent;\n border: 0;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] {\n color: rgb(var(--palette-textGray));\n font-weight: 400;\n margin-top: 10px;\n margin-bottom: 40px;\n cursor: pointer;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n margin-right: 0.3em;\n}\n[data-supertokens~="secondaryLinkWithLeftArrow"]:hover svg {\n position: relative;\n left: -4px;\n}\n[data-supertokens~="button"] {\n font-family: "Arial", sans-serif;\n background-color: rgb(var(--palette-primary));\n color: rgb(var(--palette-buttonText));\n width: 100%;\n height: 34px;\n font-weight: 600;\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[data-supertokens~="button"]:disabled {\n border: none;\n cursor: no-drop;\n}\n[data-supertokens~="button"]:active {\n outline: none;\n transition: all 0s;\n background-size: 100%;\n filter: brightness(0.85);\n}\n[data-supertokens~="button"]:focus {\n outline: none;\n}\n[data-supertokens~="backButtonCommon"] {\n width: 16px;\n height: 13px;\n}\n[data-supertokens~="backButton"] {\n cursor: pointer;\n border: none;\n background-color: transparent;\n padding: 0px;\n}\n[data-supertokens~="backButtonPlaceholder"] {\n display: block;\n}\n[data-supertokens~="delayedRender"] {\n animation-duration: 0.1s;\n animation-name: animate-fade;\n animation-delay: 0.2s;\n animation-fill-mode: backwards;\n}\n@keyframes animate-fade {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] {\n display: flex;\n flex-direction: column;\n margin-top: 10px;\n gap: 24px;\n}\n[data-supertokens~="footerLinkGroupVert"] > div {\n cursor: pointer;\n margin: 0;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryText"] {\n font-weight: 400;\n}\n[data-supertokens~="footerLinkGroupVert"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n font-weight: 400;\n position: relative;\n left: -6px; /* half the width of the left arrow */\n}\n@media (max-width: 360px) {\n [data-supertokens~="footerLinkGroupVert"] {\n flex-direction: column;\n }\n [data-supertokens~="footerLinkGroupVert"] > div {\n margin: 0 auto;\n }\n}\n[data-supertokens~="footerLinkGroupVert"] div:only-child {\n margin-left: auto;\n margin-right: auto;\n margin-top: 14px;\n}\n[data-supertokens~="withBackButton"] {\n position: relative;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="dividerWithOr"] {\n padding-top: 5px;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="dividerText"] {\n flex: 1 1;\n font-weight: 400;\n font-size: var(--font-size-1);\n}\n[data-supertokens~="formLabelWithLinkWrapper"] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n[data-supertokens~="formLabelLinkBtn"] {\n width: auto;\n margin-top: 0;\n line-height: 24px;\n font-size: var(--font-size-0);\n}\n[data-supertokens~="formLabelLinkBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="formLabelLinkBtn"]:disabled {\n color: rgb(var(--palette-textPrimary));\n cursor: default;\n text-decoration: none;\n}\n[data-supertokens~="authComponentList"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] {\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-1);\n font-weight: 400;\n margin: 10px 0 25px;\n}\n[data-supertokens~="authPageTitleOAuthClientUrl"] {\n text-decoration: none;\n}\n[data-supertokens~="authPageTitleOAuthClientLogo"] {\n width: 44px;\n height: 44px;\n margin-bottom: 10px;\n}\n[data-supertokens~="authPageTitleOAuthClient"] [data-supertokens~="authPageTitleOAuthClientName"] {\n color: rgb(var(--palette-textTitle));\n}\n[data-supertokens~="buttonWithArrow"] {\n border-radius: 6px;\n border: 1px solid #d0d5dd;\n width: 100%;\n color: rgb(var(--palette-textGray));\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 5px;\n margin: 24px 0;\n min-height: 48px;\n cursor: pointer;\n}\n[data-supertokens~="buttonWithArrow"]:hover {\n background-color: rgb(var(--palette-inputBackground));\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryText"] {\n font-weight: 700;\n font-size: var(--font-size-2);\n color: rgb(var(--palette-textGray));\n margin: 0;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithRightArrow"] ~ svg {\n position: relative;\n left: 2px;\n}\n[data-supertokens~="buttonWithArrow"]:hover [data-supertokens~="secondaryLinkWithLeftArrow"] svg {\n position: relative;\n left: -2px;\n}\n[data-supertokens~="buttonWithArrow"] [data-supertokens~="secondaryLinkWithLeftArrow"] {\n display: flex;\n align-items: center;\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[data-supertokens~="inputContainer"] {\n margin-top: 6px;\n}\n[data-supertokens~="inputWrapper"] {\n box-sizing: border-box;\n width: 100%;\n display: flex;\n align-items: center;\n background-color: rgb(var(--palette-inputBackground));\n height: 34px;\n border-radius: 6px;\n border: 1px solid rgb(var(--palette-inputBorder));\n}\n[data-supertokens~="inputWrapper"][focus-within] {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n[data-supertokens~="inputWrapper"]:focus-within {\n background-color: rgba(var(--palette-inputBackground), 0.25);\n border: 1px solid rgb(var(--palette-primary));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-primary), 0.25);\n outline: none;\n}\n[data-supertokens~="inputError"] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n[data-supertokens~="inputError"][focus-within] {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n[data-supertokens~="inputError"]:focus-within {\n border: 1px solid rgb(var(--palette-error));\n box-shadow: 0 0 0 0.2rem rgba(var(--palette-error), 0.25);\n outline: none;\n}\n[data-supertokens~="input"] {\n box-sizing: border-box;\n padding-left: 15px;\n filter: none;\n color: rgb(var(--palette-textInput));\n background-color: transparent;\n border-radius: 6px;\n font-size: var(--font-size-1);\n border: none;\n padding-right: 25px;\n letter-spacing: 1.2px;\n flex: 9 1 75%;\n width: 75%;\n height: 32px;\n}\n[data-supertokens~="input"]:focus {\n border: none;\n outline: none;\n}\n[data-supertokens~="input"]:-webkit-autofill,\n[data-supertokens~="input"]:-webkit-autofill:hover,\n[data-supertokens~="input"]:-webkit-autofill:focus,\n[data-supertokens~="input"]:-webkit-autofill:active {\n -webkit-text-fill-color: rgb(var(--palette-textInput));\n box-shadow: 0 0 0 30px rgb(var(--palette-inputBackground)) inset;\n}\n[data-supertokens~="inputAdornment"] {\n justify-content: center;\n margin-right: 5px;\n}\n[data-supertokens~="showPassword"] {\n cursor: pointer;\n}\n[data-supertokens~="enterEmailSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n word-break: break-word;\n}\n[data-supertokens~="submitNewPasswordSuccessMessage"] {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n[data-supertokens~="inputErrorMessage"] {\n padding-top: 5px;\n padding-bottom: 5px;\n color: rgb(var(--palette-error));\n line-height: 24px;\n font-weight: 400;\n font-size: var(--font-size-1);\n text-align: left;\n animation: slideTop 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;\n max-width: 330px;\n}\n@media (max-width: 440px) {\n [data-supertokens~="inputErrorMessage"] {\n max-width: 250px;\n }\n}\n[data-supertokens~="inputErrorSymbol"] {\n margin-right: 5px;\n top: 1px;\n position: relative;\n left: 2px;\n}\n[data-supertokens~="label"] {\n text-align: left;\n font-weight: 700;\n font-size: var(--font-size-0);\n line-height: 24px;\n color: rgb(var(--palette-textLabel));\n}\n[data-supertokens~="formRow"] {\n display: flex;\n flex-direction: column;\n padding-top: 0px;\n padding-bottom: 20px;\n}\n[data-supertokens~="formRow"][data-supertokens~="hasError"] {\n padding-bottom: 0;\n}\n[data-supertokens~="formRow"]:last-child {\n padding-bottom: 0;\n}\n[data-supertokens~="sendVerifyEmailIcon"] {\n margin-top: 11px;\n}\n[data-supertokens~="primaryText"][data-supertokens~="sendVerifyEmailText"] {\n text-align: center;\n letter-spacing: 0.8px;\n color: rgb(var(--palette-textPrimary));\n}\n[data-supertokens~="secondaryLinkWithArrow"] {\n margin-top: 10px;\n margin-bottom: 30px;\n cursor: pointer;\n font-weight: 700;\n}\n[data-supertokens~="sendVerifyEmailResend"] {\n margin-top: 13px;\n font-weight: 400;\n}\n[data-supertokens~="sendVerifyEmailResend"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="noFormRow"] {\n padding-bottom: 25px;\n}\n[data-supertokens~="emailVerificationButtonWrapper"] {\n padding-top: 25px;\n max-width: 96px;\n margin: 0 auto;\n}\n[data-supertokens~="resendEmailLink"] {\n display: inline-block;\n}\n[data-supertokens~="resetPasswordEmailForm"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="resetPasswordPasswordForm"] {\n padding-bottom: 20px;\n}\n[data-supertokens~="totp"] [data-supertokens~="container"] {\n padding-top: 24px;\n}\n[data-supertokens~="totp"] [data-supertokens~="divider"] {\n margin-top: 20px;\n margin-bottom: 20px;\n}\n[data-supertokens~="totp"] [data-supertokens~="row"] {\n padding-top: 16px;\n padding-bottom: 8px;\n width: auto;\n margin: 0 50px;\n}\n[data-supertokens~="totpDeviceQR"] {\n border-radius: 12px;\n border: 1px solid rgb(var(--palette-inputBorder));\n padding: 16px;\n max-width: 172px;\n max-height: 172px;\n}\n[data-supertokens~="showTOTPSecret"] {\n display: block;\n color: rgb(var(--palette-textGray));\n font-size: var(--font-size-0);\n margin: 16px 0 12px;\n}\n[data-supertokens~="totpSecret"] {\n display: block;\n border-radius: 6px;\n padding: 7px 15px;\n color: rgb(var(--palette-textLink));\n font-size: var(--font-size-1);\n font-weight: 600;\n letter-spacing: 3.36px;\n background: rgba(var(--palette-textLink), 0.08);\n word-wrap: break-word;\n overflow-y: hidden;\n}\nbutton[data-supertokens~="showTOTPSecretBtn"] {\n font-size: 12px;\n}\n[data-supertokens~="showTOTPSecretBtn"]:hover {\n text-decoration: underline;\n}\n[data-supertokens~="retryCodeBtn"]:disabled {\n border: 0;\n border-radius: 6px;\n color: rgb(var(--palette-error));\n background: rgb(var(--palette-errorBackground));\n}\n'; var ThemeBase = function (_a) { var children = _a.children, diff --git a/lib/build/translation/translations.d.ts b/lib/build/translation/translations.d.ts index ea5e1261c..24274f854 100644 --- a/lib/build/translation/translations.d.ts +++ b/lib/build/translation/translations.d.ts @@ -3,6 +3,7 @@ export declare const defaultTranslationsCommon: { AUTH_PAGE_HEADER_TITLE_SIGN_IN_AND_UP: string; AUTH_PAGE_HEADER_TITLE_SIGN_IN: string; AUTH_PAGE_HEADER_TITLE_SIGN_UP: string; + AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_START: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_SIGN_UP_LINK: string; AUTH_PAGE_HEADER_SUBTITLE_SIGN_IN_END: string; diff --git a/lib/build/types.d.ts b/lib/build/types.d.ts index 07706a714..c7acea0bf 100644 --- a/lib/build/types.d.ts +++ b/lib/build/types.d.ts @@ -1,4 +1,5 @@ import type { DateProviderInput } from "./dateProvider/types"; +import type { AuthSuccessContext } from "./recipe/authRecipe/types"; import type { BaseRecipeModule } from "./recipe/recipeModule/baseRecipeModule"; import type { NormalisedConfig as NormalisedRecipeModuleConfig } from "./recipe/recipeModule/types"; import type { TranslationFunc, TranslationStore } from "./translation/translationHelpers"; @@ -9,7 +10,7 @@ import type { CookieHandlerInput } from "supertokens-web-js/utils/cookieHandler/ import type NormalisedURLDomain from "supertokens-web-js/utils/normalisedURLDomain"; import type NormalisedURLPath from "supertokens-web-js/utils/normalisedURLPath"; import type { WindowHandlerInput } from "supertokens-web-js/utils/windowHandler/types"; -export declare type SuccessRedirectContext = { +declare type SuccessRedirectContextCommon = { recipeId: | "emailpassword" | "thirdparty" @@ -18,18 +19,26 @@ export declare type SuccessRedirectContext = { | "thirdpartyemailpassword" | "emailverification" | "totp"; - action: "SUCCESS"; isNewRecipeUser: boolean; createdNewUser: boolean; newSessionCreated: boolean; +}; +export declare type SuccessRedirectContextInApp = SuccessRedirectContextCommon & { + action: "SUCCESS"; redirectToPath?: string; }; -export declare type GetRedirectionURLContext = +export declare type SuccessRedirectContextOAuth2 = SuccessRedirectContextCommon & { + action: "SUCCESS_OAUTH2"; + frontendRedirectTo: string; +}; +export declare type SuccessRedirectContext = SuccessRedirectContextInApp | SuccessRedirectContextOAuth2; +export declare type GetRedirectionURLContext = NormalisedGetRedirectionURLContext< | { action: "TO_AUTH"; showSignIn?: boolean; } - | SuccessRedirectContext; + | SuccessRedirectContextInApp +>; export declare type ValidationFailureCallback = | (({ userContext, @@ -66,7 +75,7 @@ export declare type SuperTokensConfig = { }; enableDebugLogs?: boolean; getRedirectionURL?: ( - context: GetRedirectionURLContext, + context: NormalisedGetRedirectionURLContext, userContext: UserContext ) => Promise; style?: string; @@ -184,6 +193,7 @@ export declare type UserContext = Record; export declare type AuthComponentProps = { setFactorList: (factorIds: string[]) => void; rebuildAuthPage: () => void; + onAuthSuccess: (successContext: AuthSuccessContext) => Promise; navigate: Navigate | undefined; userContext: UserContext; error: string | undefined; @@ -217,4 +227,7 @@ export declare type PartialAuthComponent = { component: React.FC; }; export declare type AuthComponent = PartialAuthComponent | FullPageAuthComponent; +export declare type NormalisedGetRedirectionURLContext = RecipeContext & { + tenantIdFromQueryParams: string | undefined; +}; export {}; diff --git a/lib/build/ui-entry.js b/lib/build/ui-entry.js index 52083a79c..c91525c6e 100644 --- a/lib/build/ui-entry.js +++ b/lib/build/ui-entry.js @@ -23,6 +23,8 @@ require("supertokens-web-js/utils/sessionClaimValidatorStore"); require("./recipeModule-shared.js"); require("./multifactorauth-shared.js"); require("supertokens-web-js/recipe/session"); +require("./oauth2provider-shared.js"); +require("supertokens-web-js/recipe/oauth2provider"); require("./authRecipe-shared.js"); require("supertokens-web-js/lib/build/normalisedURLPath"); diff --git a/lib/build/ui/index.d.ts b/lib/build/ui/index.d.ts index 3f69b71fd..9137df7c3 100644 --- a/lib/build/ui/index.d.ts +++ b/lib/build/ui/index.d.ts @@ -41,6 +41,13 @@ declare class UI { onSignInUpSwitcherClick: (() => void) | undefined; resetFactorList: () => void; showBackButton: boolean; + oauth2ClientInfo?: + | { + logoUri?: string | undefined; + clientUri?: string | undefined; + clientName: string; + } + | undefined; }>; static AuthPageComponentList: React.ComponentType; static AuthRecipeComponentsOverrideContextProvider: React.FC< diff --git a/lib/build/ui/types.d.ts b/lib/build/ui/types.d.ts index 794478b9c..4555c45d0 100644 --- a/lib/build/ui/types.d.ts +++ b/lib/build/ui/types.d.ts @@ -1,6 +1,7 @@ import type { EmailPasswordPreBuiltUI } from "../recipe/emailpassword/prebuiltui"; import type { EmailVerificationPreBuiltUI } from "../recipe/emailverification/prebuiltui"; import type { MultiFactorAuthPreBuiltUI } from "../recipe/multifactorauth/prebuiltui"; +import type { OAuth2ProviderPreBuiltUI } from "../recipe/oauth2provider/prebuiltui"; import type { PasswordlessPreBuiltUI } from "../recipe/passwordless/prebuiltui"; import type { SessionPreBuiltUI } from "../recipe/session/prebuiltui"; import type { ThirdPartyPreBuiltUI } from "../recipe/thirdparty/prebuiltui"; @@ -19,5 +20,6 @@ export declare type PreBuiltRecipes = ( | typeof EmailVerificationPreBuiltUI | typeof MultiFactorAuthPreBuiltUI | typeof TOTPPreBuiltUI + | typeof OAuth2ProviderPreBuiltUI | typeof SessionPreBuiltUI )[]; diff --git a/lib/build/utils.d.ts b/lib/build/utils.d.ts index 7e87db5b9..9c63de8a9 100644 --- a/lib/build/utils.d.ts +++ b/lib/build/utils.d.ts @@ -8,6 +8,7 @@ import type { Navigate, NormalisedAppInfo, NormalisedFormField, + NormalisedGetRedirectionURLContext, UserContext, } from "./types"; export declare function getRecipeIdFromSearch(search: string): string | null; @@ -17,6 +18,15 @@ export declare function clearErrorQueryParam(): void; export declare function getQueryParams(param: string): string | null; export declare function getURLHash(): string; export declare function getRedirectToPathFromURL(): string | undefined; +export declare function getTenantIdFromQueryParams(): string | undefined; +export declare function getDefaultRedirectionURLForPath( + config: { + appInfo: NormalisedAppInfo; + }, + defaultPath: string, + context: NormalisedGetRedirectionURLContext, + extraQueryParams?: Record +): string; export declare function isTest(): boolean; export declare function normaliseInputAppInfoOrThrowError(appInfo: AppInfoUserInput): NormalisedAppInfo; export declare function validateForm( diff --git a/lib/build/version.d.ts b/lib/build/version.d.ts index 94509572d..f84ac887e 100644 --- a/lib/build/version.d.ts +++ b/lib/build/version.d.ts @@ -1 +1 @@ -export declare const package_version = "0.47.1"; +export declare const package_version = "0.49.0"; diff --git a/lib/ts/components/assets/logoutIcon.tsx b/lib/ts/components/assets/logoutIcon.tsx new file mode 100644 index 000000000..d10c86f17 --- /dev/null +++ b/lib/ts/components/assets/logoutIcon.tsx @@ -0,0 +1,27 @@ +/* Copyright (c) 2024, 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. + */ + +export default function LogoutIcon(): JSX.Element { + return ( + + + + ); +} diff --git a/lib/ts/constants.ts b/lib/ts/constants.ts index 3727b23b1..ab313489b 100644 --- a/lib/ts/constants.ts +++ b/lib/ts/constants.ts @@ -17,6 +17,7 @@ * Consts. */ export const RECIPE_ID_QUERY_PARAM = "rid"; +export const TENANT_ID_QUERY_PARAM = "tenantId"; export const DEFAULT_API_BASE_PATH = "/auth"; diff --git a/lib/ts/recipe/authRecipe/components/feature/authPage/authPage.tsx b/lib/ts/recipe/authRecipe/components/feature/authPage/authPage.tsx index c15b11c1c..5b4e2fbb4 100644 --- a/lib/ts/recipe/authRecipe/components/feature/authPage/authPage.tsx +++ b/lib/ts/recipe/authRecipe/components/feature/authPage/authPage.tsx @@ -25,12 +25,21 @@ import SuperTokens from "../../../../../superTokens"; import { TranslationContextProvider } from "../../../../../translation/translationContext"; import { defaultTranslationsCommon } from "../../../../../translation/translations"; import { UserContextProvider, useUserContext } from "../../../../../usercontext"; -import { getRedirectToPathFromURL, mergeObjects, updateQueryParam, useRethrowInRender } from "../../../../../utils"; +import { + clearQueryParams, + getRedirectToPathFromURL, + getTenantIdFromQueryParams, + mergeObjects, + updateQueryParam, + useOnMountAPICall, + useRethrowInRender, +} from "../../../../../utils"; import MultiFactorAuth from "../../../../multifactorauth/recipe"; import { FactorIds } from "../../../../multifactorauth/types"; import DynamicLoginMethodsSpinner from "../../../../multitenancy/components/features/dynamicLoginMethodsSpinner"; import { DynamicLoginMethodsProvider } from "../../../../multitenancy/dynamicLoginMethodsContext"; import Multitenancy from "../../../../multitenancy/recipe"; +import OAuth2Provider from "../../../../oauth2provider/recipe"; import Session from "../../../../session/recipe"; import SessionAuthWrapper from "../../../../session/sessionAuth"; import useSessionContext from "../../../../session/useSessionContext"; @@ -43,8 +52,9 @@ import type { TranslationStore } from "../../../../../translation/translationHel import type { AuthComponent, Navigate, PartialAuthComponent, UserContext } from "../../../../../types"; import type { GetLoginMethodsResponseNormalized } from "../../../../multitenancy/types"; import type { RecipeRouter } from "../../../../recipeRouter"; -import type { AuthPageThemeProps } from "../../../types"; +import type { AuthPageThemeProps, AuthSuccessContext } from "../../../types"; import type { PropsWithChildren } from "react"; +import type { LoginInfo } from "supertokens-web-js/recipe/oauth2provider/types"; const errorQSMap: Record = { signin: "SOMETHING_WENT_WRONG_ERROR", @@ -102,6 +112,8 @@ const AuthPageInner: React.FC = (props) => { const showStringFromQSRef = useRef(showStringFromQS); const errorFromQSRef = useRef(errorFromQS); + const loginChallenge = search.get("loginChallenge"); + const forceFreshAuth = search.get("forceFreshAuth") === "true"; const sessionContext = useSessionContext(); const userContext = useUserContext(); @@ -110,6 +122,7 @@ const AuthPageInner: React.FC = (props) => { const [loadedDynamicLoginMethods, setLoadedDynamicLoginMethods] = useState< GetLoginMethodsResponseNormalized | undefined >(undefined); + const [oauth2ClientInfo, setOAuth2ClientInfo] = useState(undefined); const [error, setError] = useState(errorFromQS); const [sessionLoadedAndNotRedirecting, setSessionLoadedAndNotRedirecting] = useState(false); const st = SuperTokens.getInstanceOrThrow(); @@ -163,6 +176,31 @@ const AuthPageInner: React.FC = (props) => { ); }, [loadedDynamicLoginMethods, setLoadedDynamicLoginMethods]); + useOnMountAPICall( + async () => { + if (oauth2ClientInfo) { + return; + } + const oauth2Recipe = OAuth2Provider.getInstance(); + if (oauth2Recipe !== undefined && loginChallenge !== null) { + return oauth2Recipe.webJSRecipe.getLoginChallengeInfo({ loginChallenge, userContext }); + } + return undefined; + }, + async (info) => { + if (info !== undefined) { + if (info.status === "OK") { + setOAuth2ClientInfo(info.info); + } else { + setError("SOMETHING_WENT_WRONG_ERROR"); + } + } + }, + () => { + return clearQueryParams(["loginChallenge"]); + } + ); + useEffect(() => { if (sessionLoadedAndNotRedirecting) { return; @@ -175,19 +213,48 @@ const AuthPageInner: React.FC = (props) => { if (sessionContext.doesSessionExist) { if (props.onSessionAlreadyExists !== undefined) { props.onSessionAlreadyExists(); - } else if (props.redirectOnSessionExists !== false) { + } else if (props.redirectOnSessionExists !== false && !forceFreshAuth) { Session.getInstanceOrThrow().config.onHandleEvent({ action: "SESSION_ALREADY_EXISTS", }); - void Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - undefined, - Session.RECIPE_ID, // TODO - getRedirectToPathFromURL(), - userContext, - props.navigate - ) - .catch(rethrowInRender); + const oauth2Recipe = OAuth2Provider.getInstance(); + if (loginChallenge !== null && oauth2Recipe !== undefined) { + (async function () { + const { frontendRedirectTo } = + await oauth2Recipe.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge, + userContext, + }); + return Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + { + // We get here if the user was redirected to the auth screen with an already existing session + // and a loginChallenge (we check the forceFreshAuth queryparam above) + action: "SUCCESS_OAUTH2", + frontendRedirectTo, + // We can use these defaults, since this is not the result of a sign in/up call + createdNewUser: false, + isNewRecipeUser: false, + newSessionCreated: false, + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + recipeId: Session.RECIPE_ID, + }, + Session.RECIPE_ID, + getRedirectToPathFromURL(), + userContext, + props.navigate + ); + })().catch(rethrowInRender); + } else { + void Session.getInstanceOrThrow() + .validateGlobalClaimsAndHandleSuccessRedirection( + undefined, + Session.RECIPE_ID, + getRedirectToPathFromURL(), + userContext, + props.navigate + ) + .catch(rethrowInRender); + } } else { setSessionLoadedAndNotRedirecting(true); } @@ -247,10 +314,50 @@ const AuthPageInner: React.FC = (props) => { rethrowInRender, ]); + const onAuthSuccess = useCallback( + async (ctx: AuthSuccessContext) => { + const oauth2Recipe = OAuth2Provider.getInstance(); + if (loginChallenge === null || oauth2Recipe === undefined) { + return Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + { + ...ctx, + action: "SUCCESS", + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + redirectToPath: getRedirectToPathFromURL(), + }, + ctx.recipeId, + getRedirectToPathFromURL(), + userContext, + props.navigate + ); + } + const { frontendRedirectTo } = await oauth2Recipe.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge, + userContext, + }); + return Session.getInstanceOrThrow().validateGlobalClaimsAndHandleSuccessRedirection( + { + ...ctx, + action: "SUCCESS_OAUTH2", + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + frontendRedirectTo, + }, + ctx.recipeId, + getRedirectToPathFromURL(), + userContext, + props.navigate + ); + }, + [loginChallenge] + ); + const childProps: AuthPageThemeProps | undefined = - authComponentListInfo !== undefined + authComponentListInfo !== undefined && + (loginChallenge === null || oauth2ClientInfo !== undefined || OAuth2Provider.getInstance() === undefined) ? { ...authComponentListInfo, + oauth2ClientInfo, + onAuthSuccess, error, onError: (err) => { setError(err); diff --git a/lib/ts/recipe/authRecipe/components/theme/authPage/authPageHeader.tsx b/lib/ts/recipe/authRecipe/components/theme/authPage/authPageHeader.tsx index 40c4cb375..29a681466 100644 --- a/lib/ts/recipe/authRecipe/components/theme/authPage/authPageHeader.tsx +++ b/lib/ts/recipe/authRecipe/components/theme/authPage/authPageHeader.tsx @@ -26,6 +26,7 @@ export const AuthPageHeader = withOverride( isSignUp, showBackButton, resetFactorList, + oauth2ClientInfo, }: { factorIds: string[]; isSignUp: boolean; @@ -33,11 +34,23 @@ export const AuthPageHeader = withOverride( onSignInUpSwitcherClick: (() => void) | undefined; resetFactorList: () => void; showBackButton: boolean; + oauth2ClientInfo?: { + logoUri?: string; + clientUri?: string; + clientName: string; + }; }): JSX.Element { const t = useTranslation(); return ( + {oauth2ClientInfo?.logoUri && ( + {oauth2ClientInfo.clientName} + )}
{showBackButton ? ( @@ -55,6 +68,24 @@ export const AuthPageHeader = withOverride( {/* empty span for spacing the back button */}
+ {oauth2ClientInfo && + oauth2ClientInfo.clientName !== undefined && + oauth2ClientInfo.clientName.length > 0 && ( +
+ {t("AUTH_PAGE_HEADER_TITLE_SIGN_IN_UP_TO_APP")} + {oauth2ClientInfo.clientUri !== undefined ? ( + + {oauth2ClientInfo.clientName} + + ) : ( + + {oauth2ClientInfo.clientName} + + )} +
+ )} {hasSeparateSignUpView && (!isSignUp ? (
diff --git a/lib/ts/recipe/authRecipe/components/theme/authPage/index.tsx b/lib/ts/recipe/authRecipe/components/theme/authPage/index.tsx index cec9ccd85..88d937b38 100644 --- a/lib/ts/recipe/authRecipe/components/theme/authPage/index.tsx +++ b/lib/ts/recipe/authRecipe/components/theme/authPage/index.tsx @@ -50,6 +50,7 @@ export function AuthPageTheme(props: AuthPageThemeProps): JSX.Element { hasSeparateSignUpView={props.hasSeparateSignUpView} resetFactorList={props.resetFactorList} showBackButton={props.showBackButton} + oauth2ClientInfo={props.oauth2ClientInfo} /> {props.error !== undefined && } diff --git a/lib/ts/recipe/authRecipe/types.ts b/lib/ts/recipe/authRecipe/types.ts index 92c47fcc5..e41837acd 100644 --- a/lib/ts/recipe/authRecipe/types.ts +++ b/lib/ts/recipe/authRecipe/types.ts @@ -17,7 +17,13 @@ import type { AuthPageComponentList } from "./components/theme/authPage/authPage import type { AuthPageFooter } from "./components/theme/authPage/authPageFooter"; import type { AuthPageHeader } from "./components/theme/authPage/authPageHeader"; import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; -import type { AuthComponentProps, Navigate, PartialAuthComponentProps, UserContext } from "../../types"; +import type { + AuthComponentProps, + Navigate, + PartialAuthComponentProps, + SuccessRedirectContext, + UserContext, +} from "../../types"; import type { Config as RecipeModuleConfig, NormalisedConfig as NormalisedRecipeModuleConfig, @@ -47,7 +53,19 @@ type ComponentWithPreloadInfo = { preloadInfo: T; }; +export type AuthSuccessContext = Omit< + SuccessRedirectContext, + "redirectToPath" | "action" | "loginChallenge" | "recipeId" +> & { recipeId: string }; + export type AuthPageThemeProps = { + oauth2ClientInfo?: { + clientLogo?: string; + clientUri?: string; + clientName: string; + }; + onAuthSuccess: (successContext: AuthSuccessContext) => Promise; + showBackButton: boolean; setFactorList: (factorIds: string[]) => void; resetFactorList: () => void; diff --git a/lib/ts/recipe/emailpassword/components/features/signin/index.tsx b/lib/ts/recipe/emailpassword/components/features/signin/index.tsx index 3a7a09119..23b768f50 100644 --- a/lib/ts/recipe/emailpassword/components/features/signin/index.tsx +++ b/lib/ts/recipe/emailpassword/components/features/signin/index.tsx @@ -23,16 +23,18 @@ import { useCallback } from "react"; import AuthComponentWrapper from "../../../../../components/authCompWrapper"; import { useTranslation } from "../../../../../translation/translationContext"; -import { getRedirectToPathFromURL, useRethrowInRender } from "../../../../../utils"; +import { getTenantIdFromQueryParams, useRethrowInRender } from "../../../../../utils"; import { EmailVerificationClaim } from "../../../../emailverification"; import EmailVerification from "../../../../emailverification/recipe"; import { getInvalidClaimsFromResponse } from "../../../../session"; import Session from "../../../../session/recipe"; import useSessionContext from "../../../../session/useSessionContext"; +import EmailPassword from "../../../recipe"; import { Label } from "../../library"; import SignInTheme from "../../themes/signIn"; import type { Navigate, UserContext, PartialAuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { SignInThemeProps } from "../../../types"; import type { ComponentOverrideMap } from "../../../types"; @@ -40,6 +42,7 @@ import type { RecipeInterface } from "supertokens-web-js/recipe/emailpassword"; export function useChildProps( recipe: Recipe, + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, @@ -61,30 +64,26 @@ export function useChildProps( payloadAfterCall = undefined; } - return Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: false, - isNewRecipeUser: false, - newSessionCreated: - session.loading || - !session.doesSessionExist || - (payloadAfterCall !== undefined && - session.accessTokenPayload.sessionHandle !== payloadAfterCall.sessionHandle), - recipeId: recipe!.recipeID, - }, - recipe!.recipeID, - getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender); + return onAuthSuccess({ + createdNewUser: false, + isNewRecipeUser: false, + newSessionCreated: + session.loading || + !session.doesSessionExist || + (payloadAfterCall !== undefined && + session.accessTokenPayload.sessionHandle !== payloadAfterCall.sessionHandle), + recipeId: EmailPassword.RECIPE_ID, + }).catch(rethrowInRender); }, [recipe, userContext, navigate]); return useMemo(() => { const onForgotPasswordClick = () => - recipe.redirect({ action: "RESET_PASSWORD" }, navigate, undefined, userContext); + recipe.redirect( + { action: "RESET_PASSWORD", tenantIdFromQueryParams: getTenantIdFromQueryParams() }, + navigate, + undefined, + userContext + ); const signInAndUpFeature = recipe.config.signInAndUpFeature; const signInFeature = signInAndUpFeature.signInForm; @@ -124,6 +123,7 @@ export function useChildProps( await evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: getTenantIdFromQueryParams(), }, navigate, undefined, @@ -153,6 +153,7 @@ export const SignInFeature: React.FC< > = (props) => { const childProps = useChildProps( props.recipe, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -187,5 +188,13 @@ export default SignInFeature; const getModifiedRecipeImplementation = (origImpl: RecipeInterface): RecipeInterface => { return { ...origImpl, + signIn: async function (input) { + const response = await origImpl.signIn({ ...input, shouldTryLinkingWithSessionUser: false }); + return response; + }, + signUp: async function (input) { + const response = await origImpl.signUp({ ...input, shouldTryLinkingWithSessionUser: false }); + return response; + }, }; }; diff --git a/lib/ts/recipe/emailpassword/components/features/signup/index.tsx b/lib/ts/recipe/emailpassword/components/features/signup/index.tsx index 43f236a5b..aa0c27f19 100644 --- a/lib/ts/recipe/emailpassword/components/features/signup/index.tsx +++ b/lib/ts/recipe/emailpassword/components/features/signup/index.tsx @@ -24,7 +24,7 @@ import STGeneralError from "supertokens-web-js/utils/error"; import AuthComponentWrapper from "../../../../../components/authCompWrapper"; import { useUserContext } from "../../../../../usercontext"; -import { getRedirectToPathFromURL, useRethrowInRender } from "../../../../../utils"; +import { getTenantIdFromQueryParams, useRethrowInRender } from "../../../../../utils"; import { EmailVerificationClaim } from "../../../../emailverification"; import EmailVerification from "../../../../emailverification/recipe"; import { getInvalidClaimsFromResponse } from "../../../../session"; @@ -33,6 +33,7 @@ import useSessionContext from "../../../../session/useSessionContext"; import SignUpTheme from "../../themes/signUp"; import type { Navigate, NormalisedFormField, UserContext, PartialAuthComponentProps } from "../../../../../types"; +import type { AuthSuccessContext } from "../../../../authRecipe/types"; import type Recipe from "../../../recipe"; import type { SignUpThemeProps } from "../../../types"; import type { ComponentOverrideMap, FormFieldThemeProps } from "../../../types"; @@ -41,6 +42,7 @@ import type { User } from "supertokens-web-js/types"; export function useChildProps( recipe: Recipe, + onAuthSuccess: (successContext: AuthSuccessContext) => Promise, error: string | undefined, onError: (err: string) => void, clearError: () => void, @@ -61,25 +63,16 @@ export function useChildProps( } catch { payloadAfterCall = undefined; } - return Session.getInstanceOrThrow() - .validateGlobalClaimsAndHandleSuccessRedirection( - { - action: "SUCCESS", - createdNewUser: result.user.loginMethods.length === 1, - isNewRecipeUser: true, - newSessionCreated: - session.loading || - !session.doesSessionExist || - (payloadAfterCall !== undefined && - session.accessTokenPayload.sessionHandle !== payloadAfterCall.sessionHandle), - recipeId: recipe!.recipeID, - }, - recipe!.recipeID, - getRedirectToPathFromURL(), - userContext, - navigate - ) - .catch(rethrowInRender); + return onAuthSuccess({ + createdNewUser: result.user.loginMethods.length === 1, + isNewRecipeUser: true, + newSessionCreated: + session.loading || + !session.doesSessionExist || + (payloadAfterCall !== undefined && + session.accessTokenPayload.sessionHandle !== payloadAfterCall.sessionHandle), + recipeId: recipe!.recipeID, + }).catch(rethrowInRender); }, [recipe, userContext, navigate] ); @@ -103,6 +96,7 @@ export function useChildProps( await evInstance.redirect( { action: "VERIFY_EMAIL", + tenantIdFromQueryParams: getTenantIdFromQueryParams(), }, navigate, undefined, @@ -138,6 +132,7 @@ export const SignUpFeature: React.FC< } const childProps = useChildProps( props.recipe, + props.onAuthSuccess, props.error, props.onError, props.clearError, @@ -172,6 +167,14 @@ export default SignUpFeature; const getModifiedRecipeImplementation = (origImpl: RecipeInterface): RecipeInterface => { return { ...origImpl, + signIn: async function (input) { + const response = await origImpl.signIn({ ...input, shouldTryLinkingWithSessionUser: false }); + return response; + }, + signUp: async function (input) { + const response = await origImpl.signUp({ ...input, shouldTryLinkingWithSessionUser: false }); + return response; + }, }; }; diff --git a/lib/ts/recipe/emailpassword/components/themes/signIn/index.tsx b/lib/ts/recipe/emailpassword/components/themes/signIn/index.tsx index 298a8d394..61d66b8ec 100644 --- a/lib/ts/recipe/emailpassword/components/themes/signIn/index.tsx +++ b/lib/ts/recipe/emailpassword/components/themes/signIn/index.tsx @@ -57,6 +57,7 @@ export const SignInForm = withOverride( const response = await props.recipeImplementation.signIn({ formFields, + shouldTryLinkingWithSessionUser: false, userContext, }); if (response.status === "WRONG_CREDENTIALS_ERROR") { diff --git a/lib/ts/recipe/emailpassword/components/themes/signUp/index.tsx b/lib/ts/recipe/emailpassword/components/themes/signUp/index.tsx index 9e796e0c4..d07c5c8b5 100644 --- a/lib/ts/recipe/emailpassword/components/themes/signUp/index.tsx +++ b/lib/ts/recipe/emailpassword/components/themes/signUp/index.tsx @@ -57,6 +57,7 @@ export const SignUpForm = withOverride( const res = await props.recipeImplementation.signUp({ formFields, + shouldTryLinkingWithSessionUser: false, userContext, }); diff --git a/lib/ts/recipe/emailpassword/index.ts b/lib/ts/recipe/emailpassword/index.ts index e601cf2ba..52957243b 100644 --- a/lib/ts/recipe/emailpassword/index.ts +++ b/lib/ts/recipe/emailpassword/index.ts @@ -100,6 +100,7 @@ export default class Wrapper { id: string; value: string; }[]; + shouldTryLinkingWithSessionUser?: boolean; options?: RecipeFunctionOptions; userContext?: UserContext; }): Promise< @@ -133,6 +134,7 @@ export default class Wrapper { id: string; value: string; }[]; + shouldTryLinkingWithSessionUser?: boolean; options?: RecipeFunctionOptions; userContext?: UserContext; }): Promise< diff --git a/lib/ts/recipe/emailpassword/recipe.tsx b/lib/ts/recipe/emailpassword/recipe.tsx index e0f05a2ad..367b0186b 100644 --- a/lib/ts/recipe/emailpassword/recipe.tsx +++ b/lib/ts/recipe/emailpassword/recipe.tsx @@ -18,10 +18,9 @@ */ import EmailPasswordWebJS from "supertokens-web-js/recipe/emailpassword"; -import NormalisedURLPath from "supertokens-web-js/utils/normalisedURLPath"; import { SSR_ERROR } from "../../constants"; -import { isTest } from "../../utils"; +import { getDefaultRedirectionURLForPath, isTest } from "../../utils"; import AuthRecipe from "../authRecipe"; import { FactorIds } from "../multifactorauth/types"; @@ -50,7 +49,7 @@ export default class EmailPassword extends AuthRecipe< NormalisedConfig > { static instance?: EmailPassword; - static RECIPE_ID = "emailpassword"; + static RECIPE_ID = "emailpassword" as const; recipeID = EmailPassword.RECIPE_ID; firstFactorIds = [FactorIds.EMAILPASSWORD]; @@ -63,15 +62,11 @@ export default class EmailPassword extends AuthRecipe< public readonly webJSRecipe: WebJSRecipeInterface = EmailPasswordWebJS ) { super(config); - this.recipeID = config.recipeId; } getDefaultRedirectionURL = async (context: GetRedirectionURLContext): Promise => { if (context.action === "RESET_PASSWORD") { - const resetPasswordPath = new NormalisedURLPath(DEFAULT_RESET_PASSWORD_PATH); - return `${this.config.appInfo.websiteBasePath.appendPath(resetPasswordPath).getAsStringDangerous()}?rid=${ - this.config.recipeId - }`; + return getDefaultRedirectionURLForPath(this.config, DEFAULT_RESET_PASSWORD_PATH, context); } return this.getAuthRecipeDefaultRedirectionURL(context); diff --git a/lib/ts/recipe/emailpassword/types.ts b/lib/ts/recipe/emailpassword/types.ts index e67ea3d86..b30f27e3f 100644 --- a/lib/ts/recipe/emailpassword/types.ts +++ b/lib/ts/recipe/emailpassword/types.ts @@ -26,6 +26,7 @@ import type { FormFieldBaseConfig, NormalisedBaseConfig, NormalisedFormField, + NormalisedGetRedirectionURLContext, ThemeBaseProps, UserContext, } from "../../types"; @@ -265,12 +266,12 @@ export type PreAPIHookContext = { userContext: UserContext; }; -export type GetRedirectionURLContext = { +export type GetRedirectionURLContext = NormalisedGetRedirectionURLContext<{ /* * Get Redirection URL Context */ action: "RESET_PASSWORD"; -}; +}>; export type OnHandleEventContext = | AuthRecipeModuleOnHandleEventContext diff --git a/lib/ts/recipe/emailverification/emailVerificationClaim.ts b/lib/ts/recipe/emailverification/emailVerificationClaim.ts index dd68daa42..550cf0dff 100644 --- a/lib/ts/recipe/emailverification/emailVerificationClaim.ts +++ b/lib/ts/recipe/emailverification/emailVerificationClaim.ts @@ -1,5 +1,7 @@ import { EmailVerificationClaimClass as EmailVerificationClaimClassWebJS } from "supertokens-web-js/recipe/emailverification"; +import { getTenantIdFromQueryParams } from "../../utils"; + import EmailVerification from "./recipe"; import type { UserContext, ValidationFailureCallback } from "../../types"; @@ -24,7 +26,10 @@ export class EmailVerificationClaimClass extends EmailVerificationClaimClassWebJ } const recipe = EmailVerification.getInstanceOrThrow(); if (recipe.config.mode === "REQUIRED") { - return recipe.getRedirectUrl({ action: "VERIFY_EMAIL" }, args.userContext); + return recipe.getRedirectUrl( + { action: "VERIFY_EMAIL", tenantIdFromQueryParams: getTenantIdFromQueryParams() }, + args.userContext + ); } return undefined; }, diff --git a/lib/ts/recipe/emailverification/recipe.tsx b/lib/ts/recipe/emailverification/recipe.tsx index bb2cbcb42..07a1f2e89 100644 --- a/lib/ts/recipe/emailverification/recipe.tsx +++ b/lib/ts/recipe/emailverification/recipe.tsx @@ -18,12 +18,11 @@ */ import EmailVerificationWebJS from "supertokens-web-js/recipe/emailverification"; -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 { isTest } from "../../utils"; +import { getDefaultRedirectionURLForPath, isTest } from "../../utils"; import RecipeModule from "../recipeModule"; import { DEFAULT_VERIFY_EMAIL_PATH } from "./constants"; @@ -135,10 +134,7 @@ export default class EmailVerification extends RecipeModule< getDefaultRedirectionURL = async (context: GetRedirectionURLContext): Promise => { if (context.action === "VERIFY_EMAIL") { - const verifyEmailPath = new NormalisedURLPath(DEFAULT_VERIFY_EMAIL_PATH); - return `${this.config.appInfo.websiteBasePath.appendPath(verifyEmailPath).getAsStringDangerous()}?rid=${ - this.config.recipeId - }`; + return getDefaultRedirectionURLForPath(this.config, DEFAULT_VERIFY_EMAIL_PATH, context); } else { return "/"; } diff --git a/lib/ts/recipe/emailverification/types.ts b/lib/ts/recipe/emailverification/types.ts index 224449991..01f3fba7b 100644 --- a/lib/ts/recipe/emailverification/types.ts +++ b/lib/ts/recipe/emailverification/types.ts @@ -15,7 +15,7 @@ import type { SendVerifyEmail } from "./components/themes/emailVerification/sendVerifyEmail"; import type { VerifyEmailLinkClicked } from "./components/themes/emailVerification/verifyEmailLinkClicked"; import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; -import type { FeatureBaseConfig, ThemeBaseProps, UserContext } from "../../types"; +import type { FeatureBaseConfig, NormalisedGetRedirectionURLContext, ThemeBaseProps, UserContext } from "../../types"; import type { Config as RecipeModuleConfig, NormalisedConfig as NormalisedRecipeModuleConfig, @@ -61,9 +61,9 @@ export type NormalisedConfig = { }; } & NormalisedRecipeModuleConfig; -export type GetRedirectionURLContext = { +export type GetRedirectionURLContext = NormalisedGetRedirectionURLContext<{ action: "VERIFY_EMAIL"; -}; +}>; export type PreAndPostAPIHookAction = "VERIFY_EMAIL" | "SEND_VERIFY_EMAIL" | "IS_EMAIL_VERIFIED"; diff --git a/lib/ts/recipe/multifactorauth/recipe.tsx b/lib/ts/recipe/multifactorauth/recipe.tsx index 9d6ef7dcd..d7fd8f0d0 100644 --- a/lib/ts/recipe/multifactorauth/recipe.tsx +++ b/lib/ts/recipe/multifactorauth/recipe.tsx @@ -19,7 +19,6 @@ import MultiFactorAuthWebJS from "supertokens-web-js/recipe/multifactorauth"; import { getNormalisedUserContext } 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 { WindowHandlerReference } from "supertokens-web-js/utils/windowHandler"; @@ -29,7 +28,9 @@ import SuperTokens from "../../superTokens"; import { appendQueryParamsToURL, getCurrentNormalisedUrlPathWithQueryParamsAndFragments, + getDefaultRedirectionURLForPath, getRedirectToPathFromURL, + getTenantIdFromQueryParams, isTest, } from "../../utils"; import RecipeModule from "../recipeModule"; @@ -69,7 +70,10 @@ export default class MultiFactorAuth extends RecipeModule< static MultiFactorAuthClaim = new MultiFactorAuthClaimClass( () => MultiFactorAuth.getInstanceOrThrow(), async (context, userContext) => - (await this.getInstanceOrThrow().getRedirectUrl(context, userContext)) || undefined + (await this.getInstanceOrThrow().getRedirectUrl( + { ...context, tenantIdFromQueryParams: getTenantIdFromQueryParams() }, + userContext + )) || undefined ); public recipeID = MultiFactorAuth.RECIPE_ID; @@ -149,36 +153,22 @@ export default class MultiFactorAuth extends RecipeModule< getDefaultRedirectionURL = async (context: GetRedirectionURLContext, userContext: UserContext): Promise => { if (context.action === "FACTOR_CHOOSER") { - const chooserPath = new NormalisedURLPath(DEFAULT_FACTOR_CHOOSER_PATH); - let url = this.config.appInfo.websiteBasePath.appendPath(chooserPath).getAsStringDangerous(); - const queryParams = new URLSearchParams(); - if (context.nextFactorOptions && context.nextFactorOptions.length > 0) { - queryParams.set("n", context.nextFactorOptions.join(",")); - } - if (context.stepUp) { - queryParams.set("stepUp", "true"); - } - if (queryParams.toString() !== "") { - url += "?" + queryParams.toString(); - } - return url; + const nParam = + context.nextFactorOptions && context.nextFactorOptions.length > 0 + ? context.nextFactorOptions.join(",") + : undefined; + + return getDefaultRedirectionURLForPath(this.config, DEFAULT_FACTOR_CHOOSER_PATH, context, { + n: nParam, + stepUp: context.stepUp ? "true" : undefined, + }); } else if (context.action === "GO_TO_FACTOR") { const redirectInfo = this.getSecondaryFactors(userContext).find((f) => f.id === context.factorId); if (redirectInfo !== undefined) { - let url = this.config.appInfo.websiteBasePath - .appendPath(new NormalisedURLPath(redirectInfo.path)) - .getAsStringDangerous(); - const queryParams = new URLSearchParams(); - if (context.forceSetup) { - queryParams.set("setup", "true"); - } - if (context.stepUp) { - queryParams.set("stepUp", "true"); - } - if (queryParams.toString() !== "") { - url += "?" + queryParams.toString(); - } - return url; + return getDefaultRedirectionURLForPath(this.config, redirectInfo.path, context, { + setup: context.forceSetup ? "true" : undefined, + stepUp: context.stepUp ? "true" : undefined, + }); } throw new Error("Requested redirect to unknown factor id: " + context.factorId); } else { @@ -219,7 +209,13 @@ export default class MultiFactorAuth extends RecipeModule< userContext: UserContext | undefined; }) { let url = await this.getRedirectUrl( - { action: "GO_TO_FACTOR", forceSetup, stepUp, factorId }, + { + action: "GO_TO_FACTOR", + forceSetup, + stepUp, + factorId, + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + }, getNormalisedUserContext(userContext) ); if (url === null) { @@ -262,7 +258,12 @@ export default class MultiFactorAuth extends RecipeModule< userContext: UserContext | undefined; }) { let url = await this.getRedirectUrl( - { action: "FACTOR_CHOOSER", nextFactorOptions, stepUp }, + { + action: "FACTOR_CHOOSER", + nextFactorOptions, + stepUp, + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + }, getNormalisedUserContext(userContext) ); diff --git a/lib/ts/recipe/multifactorauth/types.ts b/lib/ts/recipe/multifactorauth/types.ts index fbcc75693..6dc4b24eb 100644 --- a/lib/ts/recipe/multifactorauth/types.ts +++ b/lib/ts/recipe/multifactorauth/types.ts @@ -18,7 +18,7 @@ import type { FactorChooserHeader } from "./components/themes/factorChooser/fact import type { FactorList } from "./components/themes/factorChooser/factorList"; import type { FactorOption } from "./components/themes/factorChooser/factorOption"; import type { ComponentOverride } from "../../components/componentOverride/componentOverride"; -import type { FeatureBaseConfig, UserContext } from "../../types"; +import type { FeatureBaseConfig, NormalisedGetRedirectionURLContext, UserContext } from "../../types"; import type { Config as RecipeModuleConfig, NormalisedConfig as NormalisedRecipeModuleConfig, @@ -75,7 +75,7 @@ export type NormalisedConfig = { }; } & NormalisedRecipeModuleConfig; -export type GetRedirectionURLContext = +export type GetRedirectionURLContext = NormalisedGetRedirectionURLContext< | { action: "FACTOR_CHOOSER"; nextFactorOptions?: string[]; @@ -86,7 +86,8 @@ export type GetRedirectionURLContext = factorId: string; forceSetup?: boolean; stepUp?: boolean; - }; + } +>; export type PreAndPostAPIHookAction = "GET_MFA_INFO"; diff --git a/lib/ts/recipe/multifactorauth/utils.ts b/lib/ts/recipe/multifactorauth/utils.ts index 2e276e42e..fb1934d29 100644 --- a/lib/ts/recipe/multifactorauth/utils.ts +++ b/lib/ts/recipe/multifactorauth/utils.ts @@ -13,6 +13,7 @@ * under the License. */ +import { logDebugMessage } from "../../logger"; import { normaliseRecipeModuleConfig } from "../recipeModule/utils"; import type MultiFactorAuth from "./recipe"; @@ -48,6 +49,14 @@ export function getAvailableFactors( recipe: MultiFactorAuth, userContext: UserContext ) { + logDebugMessage(`getAvailableFactors: allowed to setup: ${factors.allowedToSetup}`); + logDebugMessage(`getAvailableFactors: already setup: ${factors.alreadySetup}`); + logDebugMessage(`getAvailableFactors: next from factorInfo: ${factors.next}`); + logDebugMessage(`getAvailableFactors: nextArrayQueryParam: ${nextArrayQueryParam}`); + logDebugMessage( + `getAvailableFactors: secondary factors: ${recipe.getSecondaryFactors(userContext).map((f) => f.id)}` + ); + // There are 3 cases here: // 1. The app provided an array of factors to show (nextArrayQueryParam) -> we show whatever is in the array // 2. no app provided list and validator passed -> we show all factors available to set up or complete diff --git a/lib/ts/recipe/oauth2provider/componentOverrideContext.tsx b/lib/ts/recipe/oauth2provider/componentOverrideContext.tsx new file mode 100644 index 000000000..467bd5485 --- /dev/null +++ b/lib/ts/recipe/oauth2provider/componentOverrideContext.tsx @@ -0,0 +1,7 @@ +import { createGenericComponentsOverrideContext } from "../../components/componentOverride/genericComponentOverrideContext"; + +import type { ComponentOverrideMap } from "./types"; + +const [useContext, Provider] = createGenericComponentsOverrideContext(); + +export { useContext as useRecipeComponentOverrideContext, Provider as RecipeComponentsOverrideContextProvider }; diff --git a/lib/ts/recipe/oauth2provider/components/features/oauth2LogoutScreen/index.tsx b/lib/ts/recipe/oauth2provider/components/features/oauth2LogoutScreen/index.tsx new file mode 100644 index 000000000..175a56e8e --- /dev/null +++ b/lib/ts/recipe/oauth2provider/components/features/oauth2LogoutScreen/index.tsx @@ -0,0 +1,136 @@ +/* Copyright (c) 2024, 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. + */ + +/* + * Imports. + */ +import * as React from "react"; +import { Fragment } from "react"; + +import { ComponentOverrideContext } from "../../../../../components/componentOverride/componentOverrideContext"; +import FeatureWrapper from "../../../../../components/featureWrapper"; +import SuperTokens from "../../../../../superTokens"; +import UI from "../../../../../ui"; +import { useUserContext } from "../../../../../usercontext"; +import { getQueryParams, getTenantIdFromQueryParams, useRethrowInRender } from "../../../../../utils"; +import { SessionContext } from "../../../../session"; +import OAuth2Provider from "../../../recipe"; +import { OAuth2LogoutScreenTheme } from "../../themes/oauth2LogoutScreen"; +import { defaultTranslationsOAuth2Provider } from "../../themes/translations"; + +import type { FeatureBaseProps, UserContext } from "../../../../../types"; +import type Recipe from "../../../recipe"; +import type { ComponentOverrideMap } from "../../../types"; + +type Prop = FeatureBaseProps<{ + recipe: Recipe; + userContext?: UserContext; + useComponentOverrides: () => ComponentOverrideMap; +}>; + +export const OAuth2LogoutScreen: React.FC = (props) => { + const rethrowInRender = useRethrowInRender(); + const sessionContext = React.useContext(SessionContext); + const [isLoggingOut, setIsLoggingOut] = React.useState(false); + const recipeComponentOverrides = props.useComponentOverrides(); + let userContext = useUserContext(); + if (props.userContext !== undefined) { + userContext = props.userContext; + } + + const logoutChallenge = getQueryParams("logoutChallenge") ?? undefined; + const navigate = props.navigate ?? UI.getReactRouterDomWithCustomHistory()?.useHistoryCustom(); + + const onLogout = React.useCallback(async () => { + if (logoutChallenge === undefined) { + return; + } + setIsLoggingOut(true); + try { + const { frontendRedirectTo } = await OAuth2Provider.getInstanceOrThrow().webJSRecipe.logOut({ + logoutChallenge, + userContext, + }); + await props.recipe.redirect( + { + recipeId: "oauth2provider", + action: "POST_OAUTH2_LOGOUT_REDIRECT", + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + frontendRedirectTo, + }, + navigate, + {}, + userContext + ); + } catch (err: any) { + rethrowInRender(err); + } + }, [logoutChallenge, navigate, props.recipe, userContext, rethrowInRender]); + + React.useEffect(() => { + // We wait for session loading to finish + if (sessionContext.loading === false) { + // Redirect to the auth page if there is no logoutChallenge + if (logoutChallenge === undefined) { + void SuperTokens.getInstanceOrThrow() + .redirectToAuth({ + userContext, + redirectBack: false, + }) + .catch(rethrowInRender); + } else { + // Call logOut directly if there is no session + if (sessionContext.doesSessionExist === false) { + void onLogout(); + } + } + } + }, [userContext, logoutChallenge, sessionContext, onLogout]); + + const childProps = { + config: props.recipe.config, + showSpinner: sessionContext.loading || sessionContext.doesSessionExist === false, + onLogoutClicked: onLogout, + isLoggingOut, + }; + + if (logoutChallenge === undefined) { + return null; + } + + return ( + + + + {/* No custom theme, use default. */} + {props.children === undefined && } + {/* Otherwise, custom theme is provided, propagate props. */} + {props.children && + React.Children.map(props.children, (child) => { + if (React.isValidElement(child)) { + return React.cloneElement(child, childProps); + } + + return child; + })} + + + + ); +}; + +export default OAuth2LogoutScreen; diff --git a/lib/ts/recipe/oauth2provider/components/features/tryRefreshPage/index.tsx b/lib/ts/recipe/oauth2provider/components/features/tryRefreshPage/index.tsx new file mode 100644 index 000000000..ddb045694 --- /dev/null +++ b/lib/ts/recipe/oauth2provider/components/features/tryRefreshPage/index.tsx @@ -0,0 +1,104 @@ +/* Copyright (c) 2024, 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. + */ + +/* + * Imports. + */ +import * as React from "react"; +import { useContext, Fragment } from "react"; + +import FeatureWrapper from "../../../../../components/featureWrapper"; +import SuperTokens from "../../../../../superTokens"; +import { useUserContext } from "../../../../../usercontext"; +import { getQueryParams, getTenantIdFromQueryParams, useRethrowInRender } from "../../../../../utils"; +import DynamicLoginMethodsSpinner from "../../../../multitenancy/components/features/dynamicLoginMethodsSpinner"; +import { SessionContext } from "../../../../session"; +import { defaultTranslationsOAuth2Provider } from "../../themes/translations"; + +import type { FeatureBaseProps, UserContext } from "../../../../../types"; +import type Recipe from "../../../recipe"; +import type { ComponentOverrideMap } from "../../../types"; + +type Prop = FeatureBaseProps<{ + recipe: Recipe; + userContext?: UserContext; + useComponentOverrides: () => ComponentOverrideMap; +}>; + +export const TryRefreshPage: React.FC = (props) => { + const rethrowInRender = useRethrowInRender(); + const sessionContext = useContext(SessionContext); + const loginChallenge = getQueryParams("loginChallenge") ?? undefined; + let userContext = useUserContext(); + if (props.userContext !== undefined) { + userContext = props.userContext; + } + + React.useEffect(() => { + if (sessionContext.loading === false) { + if (loginChallenge) { + (async function () { + const { frontendRedirectTo } = await props.recipe.webJSRecipe.getRedirectURLToContinueOAuthFlow({ + loginChallenge, + userContext, + }); + return props.recipe.redirect( + { + action: "CONTINUE_OAUTH2_AFTER_REFRESH", + frontendRedirectTo, + tenantIdFromQueryParams: getTenantIdFromQueryParams(), + recipeId: "oauth2provider", + }, + props.navigate, + {}, + userContext + ); + })().catch(rethrowInRender); + } else { + void SuperTokens.getInstanceOrThrow() + .redirectToAuth({ + userContext, + redirectBack: false, + }) + .catch(rethrowInRender); + } + } + }, [loginChallenge, props.recipe, props.navigate, userContext, sessionContext]); + + const childProps = { + config: props.recipe.config, + }; + return ( + + + {/* No custom theme, use default. */} + {props.children === undefined && } + {/* Otherwise, custom theme is provided, propagate props. */} + {props.children && + React.Children.map(props.children, (child) => { + if (React.isValidElement(child)) { + return React.cloneElement(child, childProps); + } + + return child; + })} + + + ); +}; + +export default TryRefreshPage; diff --git a/lib/ts/recipe/oauth2provider/components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner.tsx b/lib/ts/recipe/oauth2provider/components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner.tsx new file mode 100644 index 000000000..75244caa2 --- /dev/null +++ b/lib/ts/recipe/oauth2provider/components/themes/oauth2LogoutScreen/OAuth2LogoutScreenInner.tsx @@ -0,0 +1,41 @@ +/* Copyright (c) 2024, 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. + */ + +import LogoutIcon from "../../../../../components/assets/logoutIcon"; +import { withOverride } from "../../../../../components/componentOverride/withOverride"; +import { useTranslation } from "../../../../../translation/translationContext"; +import { Button } from "../../../../emailpassword/components/library"; + +export const OAuth2LogoutScreenInner = withOverride( + "OAuth2LogoutScreenInner", + function OAuth2LogoutScreenInner(props: { isLoggingOut: boolean; onLogoutClicked: () => void }): JSX.Element { + const t = useTranslation(); + return ( + <> + +
{t("LOGGING_OUT")}
+
{t("LOGOUT_CONFIRMATION")}
+
+