Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow returning null from getRedirectionURL override #766

Merged
merged 24 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,56 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)

## [0.36.0] - 2023-12-07

### Changes

rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
- `getRedirectionURL` now supports returning `null` to prevent automatic redirection, useful for customizing the behavior after successful sign-in or sign-up. Typically, this is used if you want to embed the sign in / up component in a popup and want to just dismiss the popup post login.
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved

Here's an example of how to use this:

```tsx
EmailPassword.init({
getRedirectionURL: async (context, userContext) => {
if (context.action === "SUCCESS") {
return null;
}
// Returning undefined falls back to the default redirection strategy
return undefined;
},
});
```

- `getRedirectionURL` now receives `userContext` as the second argument.

- `isNewPrimaryUser` boolean property has been added to `GetRedirectionURLContext`. It can be used to check if a new primary user was created particularly in scenarios involving account linking.

- `UserContext` type has been changed to `Record<string, unknown>` from `any`.

- The `PreBuiltUI` components now accept a `navigate` prop, internally utilized by SuperTokens for redirection. This becomes handy when manually rendering the component and desiring client-side navigation instead of a full-page refresh for any redirection. Here's an example using `react-router-dom@v6`:

```tsx
import { SignInUp } from "supertokens-auth-react/recipe/passwordless/prebuiltui";
import { useNavigate } from "react-router-dom";

function CustomSignInUp() {
const navigate = useNavigate();
return <SignInUp navigate={navigate} />;
}
```

### Breaking changes

- `user` property has been removed from `GetRedirectionURLContext`.To get the `user` object from backend, you can follow hte instructions [here](https://supertokens.com/docs/thirdpartyemailpassword/common-customizations/get-user-info).

- The `CloseTabScreen` [component](https://supertokens.com/img/otp-magic-link-same-time.png), previously featured in the passwordless recipe visible when a user signs in from another tab using a magic link, has been removed. Users will continue to see the 'Enter OTP' screen until they refresh. If you were [overriding](https://supertokens.com/docs/passwordless/advanced-customizations/react-component-override/usage) this component using `PasswordlessCloseTabScreen_Override`, you no longer need to do so.

- If your workflow involves custom validation, such as Phone Number verification, after signing in, ensure your code aligns with the updated examples found in [with-phone-password](https://github.com/supertokens/supertokens-auth-react/tree/master/examples/with-phone-password) or [with-thirdpartyemailpassword-passwordless](https://github.com/supertokens/supertokens-auth-react/tree/master/examples/with-thirdpartyemailpassword-passwordless).

Changes:

- The need to manually set `props.featureState.successInAnotherTab` to `false` to avoid displaying the `CloseTabScreen` component has been eliminated.
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved

## [0.35.9] - 2023-12-06

- Fixes ThirdPartyEmailPassword rendering sign in/up switcher even with disabled email password. Instead it'll now render `SignInAndUpHeader_Override` in this case (overrideable as `ThirdPartySignInAndUpHeader`). Overriding `ThirdPartyEmailPasswordHeader_Override` should still cover all cases.
Expand Down
12 changes: 12 additions & 0 deletions examples/for-tests-react-16/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ function getEmailPasswordConfigs({ disableDefaultUI }) {
console.log(`ST_LOGS EMAIL_PASSWORD GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("emailpassword", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down Expand Up @@ -733,6 +736,9 @@ function getThirdPartyPasswordlessConfigs({ staticProviderList, disableDefaultUI
console.log(`ST_LOGS THIRDPARTYPASSWORDLESS GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("thirdpartypasswordless", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down Expand Up @@ -817,6 +823,9 @@ function getPasswordlessConfigs({ disableDefaultUI }) {
console.log(`ST_LOGS PASSWORDLESS GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("passwordless", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down Expand Up @@ -883,6 +892,9 @@ function getThirdPartyConfigs({ staticProviderList, disableDefaultUI, thirdParty
console.log(`ST_LOGS THIRD_PARTY GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("thirdparty", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down
2 changes: 2 additions & 0 deletions examples/for-tests-react-16/src/testContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export function getTestContext() {
staticProviderList: localStorage.getItem("staticProviderList"),
mockTenantId: localStorage.getItem("mockTenantId"),
clientType: localStorage.getItem("clientType") || undefined,
disableRedirectionAfterSuccessfulSignInUp:
localStorage.getItem("disableRedirectionAfterSuccessfulSignInUp") === "true",
};
return ret;
}
Expand Down
12 changes: 12 additions & 0 deletions examples/for-tests/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,9 @@ function getEmailPasswordConfigs({ disableDefaultUI, formFieldType }) {
console.log(`ST_LOGS EMAIL_PASSWORD GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("emailpassword", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
rishabhpoddar marked this conversation as resolved.
Show resolved Hide resolved
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down Expand Up @@ -956,6 +959,9 @@ function getThirdPartyPasswordlessConfigs({ staticProviderList, disableDefaultUI
console.log(`ST_LOGS THIRDPARTYPASSWORDLESS GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("thirdpartypasswordless", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down Expand Up @@ -1049,6 +1055,9 @@ function getPasswordlessConfigs({ disableDefaultUI }) {
console.log(`ST_LOGS PASSWORDLESS GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("passwordless", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down Expand Up @@ -1137,6 +1146,9 @@ function getThirdPartyConfigs({ staticProviderList, disableDefaultUI, thirdParty
console.log(`ST_LOGS THIRD_PARTY GET_REDIRECTION_URL ${context.action}`);
if (context.action === "SUCCESS") {
setIsNewUserToStorage("thirdparty", context.isNewRecipeUser);
if (testContext.disableRedirectionAfterSuccessfulSignInUp) {
return null;
}
return context.redirectToPath || "/dashboard";
}
},
Expand Down
2 changes: 2 additions & 0 deletions examples/for-tests/src/testContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export function getTestContext() {
signIn: localStorage.getItem("SIGNIN_SETTING_TYPE"),
signUp: localStorage.getItem("SIGNUP_SETTING_TYPE"),
},
disableRedirectionAfterSuccessfulSignInUp:
localStorage.getItem("disableRedirectionAfterSuccessfulSignInUp") === "true",
};
return ret;
}
Expand Down
1 change: 1 addition & 0 deletions examples/with-one-login-per-subdomain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project was bootstrapped with [Create React App](https://github.com/faceboo
127.0.0.1 tenant1.example.com
127.0.0.1 tenant2.example.com
127.0.0.1 tenant3.example.com
127.0.0.1 example.com
```

## Available Scripts
Expand Down
10 changes: 5 additions & 5 deletions examples/with-phone-password/src/PhoneVerification/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState, useEffect } from "react";
import Session, { useSessionContext } from "supertokens-auth-react/recipe/session";
import { useSessionContext } from "supertokens-auth-react/recipe/session";
import { SignInUp, SignInUpTheme } from "supertokens-auth-react/recipe/passwordless/prebuiltui";
import * as reactRouterDom from "react-router-dom";

const CustomSignInUpTheme: typeof SignInUpTheme = (props) => {
let [showDefaultUI, setShowDefaultUI] = useState(false);
Expand Down Expand Up @@ -35,18 +36,17 @@ const CustomSignInUpTheme: typeof SignInUpTheme = (props) => {
};
}, []);

// If this was active, we'd not show the OTP screen because it'd detect an active session.
props.featureState.successInAnotherTab = false;

if (showDefaultUI) {
return <SignInUpTheme {...props} />;
}
return <></>;
};

export default function PhoneVerification() {
const navigate = reactRouterDom.useNavigate();

return (
<SignInUp redirectOnSessionExists={false}>
<SignInUp redirectOnSessionExists={false} navigate={navigate}>
{
// @ts-ignore We ignore the error about missing props, since they'll be set by the feature component
<CustomSignInUpTheme />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ const CustomSignInUpTheme: typeof PasswordlessPreBuiltUI.SignInUpTheme = (props)
};
}, []);

// If this was active, we'd not show the OTP screen because it'd detect an active session.
props.featureState.successInAnotherTab = false;

if (showDefaultUI) {
return <PasswordlessPreBuiltUI.SignInUpTheme {...props} />;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/build/SuperTokensBranding.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion lib/build/components/supertokensWrapper.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 0 additions & 57 deletions lib/build/checkedRoundIcon.js → lib/build/emailLargeIcon.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading