Compare commits
13 Commits
master
...
feat/isola
| Author | SHA1 | Date |
|---|---|---|
|
|
0ece28b8d8 | |
|
|
8dad1ff94d | |
|
|
8d8c5a2431 | |
|
|
3a0839c4c0 | |
|
|
a550f8361e | |
|
|
8cf05effa3 | |
|
|
1c4ea8e925 | |
|
|
504092e7f0 | |
|
|
63021553df | |
|
|
201a2ec160 | |
|
|
30e06e23fa | |
|
|
04805a3f64 | |
|
|
4fa7b07f60 |
|
|
@ -16,9 +16,26 @@
|
|||
|
||||
package io.supertokens.authRecipe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.ResourceDistributor;
|
||||
import io.supertokens.authRecipe.exception.*;
|
||||
import io.supertokens.authRecipe.exception.BulkImportRecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
import io.supertokens.bulkimport.BulkImportUserUtils;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
|
|
@ -26,7 +43,9 @@ import io.supertokens.pluginInterface.RECIPE_ID;
|
|||
import io.supertokens.pluginInterface.Storage;
|
||||
import io.supertokens.pluginInterface.StorageUtils;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.CanBecomePrimaryResult;
|
||||
import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage;
|
||||
import io.supertokens.pluginInterface.bulkimport.BulkImportUser;
|
||||
import io.supertokens.pluginInterface.bulkimport.exceptions.BulkImportBatchInsertException;
|
||||
|
|
@ -44,12 +63,6 @@ import io.supertokens.session.Session;
|
|||
import io.supertokens.storageLayer.StorageLayer;
|
||||
import io.supertokens.useridmapping.UserIdType;
|
||||
import io.supertokens.utils.Utils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/*This files contains functions that are common for all auth recipes*/
|
||||
|
||||
|
|
@ -286,12 +299,40 @@ public class AuthRecipe {
|
|||
tenantIds.addAll(recipeUser.tenantIds);
|
||||
tenantIds.addAll(primaryUser.tenantIds);
|
||||
|
||||
checkIfLoginMethodCanBeLinkedOnTenant(con, appIdentifier, authRecipeStorage, tenantIds, recipeUser.loginMethods[0], primaryUser);
|
||||
Set<String> emails = new HashSet<>();
|
||||
Set<String> phoneNumbers = new HashSet<>();
|
||||
Set<LoginMethod.ThirdParty> thirdParties = new HashSet<>();
|
||||
|
||||
for (LoginMethod currLoginMethod : primaryUser.loginMethods) {
|
||||
checkIfLoginMethodCanBeLinkedOnTenant(con, appIdentifier, authRecipeStorage, tenantIds, currLoginMethod, primaryUser);
|
||||
for (var lm : primaryUser.loginMethods) {
|
||||
if (lm.email != null) {
|
||||
emails.add(lm.email);
|
||||
}
|
||||
if (lm.phoneNumber != null) {
|
||||
phoneNumbers.add(lm.phoneNumber);
|
||||
}
|
||||
if (lm.thirdParty != null) {
|
||||
thirdParties.add(lm.thirdParty);
|
||||
}
|
||||
}
|
||||
for (var lm : recipeUser.loginMethods) {
|
||||
if (lm.email != null) {
|
||||
emails.add(lm.email);
|
||||
}
|
||||
if (lm.phoneNumber != null) {
|
||||
phoneNumbers.add(lm.phoneNumber);
|
||||
}
|
||||
if (lm.thirdParty != null) {
|
||||
thirdParties.add(lm.thirdParty);
|
||||
}
|
||||
}
|
||||
|
||||
io.supertokens.pluginInterface.authRecipe.CanLinkAccountsResult canLinkResult =
|
||||
authRecipeStorage.checkIfLoginMethodsCanBeLinked_Transaction(con, appIdentifier, tenantIds, emails,
|
||||
phoneNumbers, thirdParties, primaryUser.getSupertokensUserId());
|
||||
if (!canLinkResult.ok) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
canLinkResult.primaryUserId, canLinkResult.message);
|
||||
}
|
||||
return new CanLinkAccountsResult(recipeUser.getSupertokensUserId(), primaryUser.getSupertokensUserId(), false);
|
||||
}
|
||||
|
||||
|
|
@ -350,79 +391,6 @@ public class AuthRecipe {
|
|||
return results;
|
||||
}
|
||||
|
||||
private static void checkIfLoginMethodCanBeLinkedOnTenant(TransactionConnection con, AppIdentifier appIdentifier,
|
||||
AuthRecipeSQLStorage authRecipeStorage,
|
||||
Set<String> tenantIds, LoginMethod currLoginMethod,
|
||||
AuthRecipeUserInfo primaryUser)
|
||||
throws StorageQueryException, AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException {
|
||||
// we loop through the union of both the user's tenantIds and check that the criteria for
|
||||
// linking accounts is not violated in any of them. We do a union and not an intersection
|
||||
// cause if we did an intersection, and that yields that account linking is allowed, it could
|
||||
// result in one tenant having two primary users with the same email. For example:
|
||||
// - tenant1 has u1 with email e, and u2 with email e, primary user (one is ep, one is tp)
|
||||
// - tenant2 has u3 with email e, primary user (passwordless)
|
||||
// now if we want to link u3 with u1, we have to deny it cause if we don't, it will result in
|
||||
// u1 and u2 to be primary users with the same email in the same tenant. If we do an
|
||||
// intersection, we will get an empty set, but if we do a union, we will get both the tenants and
|
||||
// do the checks in both.
|
||||
for (String tenantId : tenantIds) {
|
||||
// we do not bother with getting the storage for each tenant here because
|
||||
// we get the tenants from the user itself, and the user can only be shared across
|
||||
// tenants of the same storage - therefore, the storage will be the same.
|
||||
|
||||
if (currLoginMethod.email != null) {
|
||||
AuthRecipeUserInfo[] usersWithSameEmail =
|
||||
authRecipeStorage.listPrimaryUsersByEmail_Transaction(appIdentifier, con, currLoginMethod.email);
|
||||
for (AuthRecipeUserInfo user : usersWithSameEmail) {
|
||||
if (!user.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (user.isPrimaryUser && !user.getSupertokensUserId().equals(primaryUser.getSupertokensUserId())) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
user.getSupertokensUserId(),
|
||||
"This user's email is already associated with another user ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currLoginMethod.phoneNumber != null) {
|
||||
AuthRecipeUserInfo[] usersWithSamePhoneNumber =
|
||||
authRecipeStorage.listPrimaryUsersByPhoneNumber_Transaction(appIdentifier, con,
|
||||
currLoginMethod.phoneNumber);
|
||||
for (AuthRecipeUserInfo user : usersWithSamePhoneNumber) {
|
||||
if (!user.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (user.isPrimaryUser && !user.getSupertokensUserId().equals(primaryUser.getSupertokensUserId())) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
user.getSupertokensUserId(),
|
||||
"This user's phone number is already associated with another user" +
|
||||
" ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currLoginMethod.thirdParty != null) {
|
||||
AuthRecipeUserInfo[] usersWithSameThirdParty = authRecipeStorage
|
||||
.listPrimaryUsersByThirdPartyInfo_Transaction(appIdentifier, con,
|
||||
currLoginMethod.thirdParty.id, currLoginMethod.thirdParty.userId);
|
||||
for (AuthRecipeUserInfo userWithSameThirdParty : usersWithSameThirdParty) {
|
||||
if (!userWithSameThirdParty.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (userWithSameThirdParty.isPrimaryUser &&
|
||||
!userWithSameThirdParty.getSupertokensUserId().equals(primaryUser.getSupertokensUserId())) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
userWithSameThirdParty.getSupertokensUserId(),
|
||||
"This user's third party login is already associated with another" +
|
||||
" user ID");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void bulkCheckIfLoginMethodCanBeLinkedOnTenant(TransactionConnection con, AppIdentifier appIdentifier,
|
||||
AuthRecipeSQLStorage authRecipeStorage,
|
||||
Set<String> tenantIds, BulkImportUser.LoginMethod currLoginMethod,
|
||||
|
|
@ -707,62 +675,14 @@ public class AuthRecipe {
|
|||
// this means that the user has only one login method since it's not a primary user
|
||||
// nor is it linked to a primary user
|
||||
assert (targetUser.loginMethods.length == 1);
|
||||
LoginMethod loginMethod = targetUser.loginMethods[0];
|
||||
|
||||
for (String tenantId : targetUser.tenantIds) {
|
||||
if (loginMethod.email != null) {
|
||||
AuthRecipeUserInfo[] usersWithSameEmail = authRecipeStorage
|
||||
.listPrimaryUsersByEmail_Transaction(appIdentifier, con,
|
||||
loginMethod.email);
|
||||
for (AuthRecipeUserInfo user : usersWithSameEmail) {
|
||||
if (!user.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (user.isPrimaryUser) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
user.getSupertokensUserId(),
|
||||
"This user's email is already associated with another user ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
CanBecomePrimaryResult result = authRecipeStorage.checkIfLoginMethodCanBecomePrimary_Transaction(appIdentifier,
|
||||
con, targetUser.loginMethods[0]);
|
||||
|
||||
if (loginMethod.phoneNumber != null) {
|
||||
AuthRecipeUserInfo[] usersWithSamePhoneNumber = authRecipeStorage
|
||||
.listPrimaryUsersByPhoneNumber_Transaction(appIdentifier, con,
|
||||
loginMethod.phoneNumber);
|
||||
for (AuthRecipeUserInfo user : usersWithSamePhoneNumber) {
|
||||
if (!user.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (user.isPrimaryUser) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
user.getSupertokensUserId(),
|
||||
"This user's phone number is already associated with another user" +
|
||||
" ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loginMethod.thirdParty != null) {
|
||||
AuthRecipeUserInfo[] usersWithSameThirdParty = authRecipeStorage
|
||||
.listPrimaryUsersByThirdPartyInfo_Transaction(appIdentifier, con,
|
||||
loginMethod.thirdParty.id, loginMethod.thirdParty.userId);
|
||||
for (AuthRecipeUserInfo userWithSameThirdParty : usersWithSameThirdParty) {
|
||||
if (!userWithSameThirdParty.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (userWithSameThirdParty.isPrimaryUser) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(
|
||||
userWithSameThirdParty.getSupertokensUserId(),
|
||||
"This user's third party login is already associated with another" +
|
||||
" user ID");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result.ok) {
|
||||
throw new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(result.primaryUserId, result.message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return new CreatePrimaryUserResult(targetUser, false);
|
||||
}
|
||||
|
||||
|
|
@ -945,7 +865,7 @@ public class AuthRecipe {
|
|||
return authRecipeStorage.startTransaction(con -> {
|
||||
|
||||
try {
|
||||
CreatePrimaryUserResult result = canCreatePrimaryUserHelper(con, appIdentifier, authRecipeStorage,
|
||||
CreatePrimaryUserResult result = canCreatePrimaryUserHelper(con, appIdentifier, authRecipeStorage,
|
||||
recipeUserId);
|
||||
if (result.wasAlreadyAPrimaryUser) {
|
||||
return result;
|
||||
|
|
@ -1013,11 +933,11 @@ public class AuthRecipe {
|
|||
}
|
||||
canMakePrimaryUsers.add(result);
|
||||
}
|
||||
authRecipeStorage.makePrimaryUsers_Transaction(appIdentifier, con,
|
||||
canMakePrimaryUsers.stream().map(canMakePrimaryUser -> canMakePrimaryUser.user.id).collect(
|
||||
Collectors.toList()));
|
||||
authRecipeStorage.makePrimaryUsers_Transaction(appIdentifier, con,
|
||||
canMakePrimaryUsers.stream().map(canMakePrimaryUser -> canMakePrimaryUser.user.id).collect(
|
||||
Collectors.toList()));
|
||||
|
||||
authRecipeStorage.commitTransaction(con);
|
||||
authRecipeStorage.commitTransaction(con);
|
||||
|
||||
for(CreatePrimaryUserBulkResult result : results) {
|
||||
if (result.wasAlreadyAPrimaryUser) {
|
||||
|
|
@ -1447,6 +1367,8 @@ public class AuthRecipe {
|
|||
.deleteThirdPartyUser_Transaction(con, appIdentifier, userId, deleteFromUserIdToAppIdTableToo);
|
||||
StorageUtils.getPasswordlessStorage(storage)
|
||||
.deletePasswordlessUser_Transaction(con, appIdentifier, userId, deleteFromUserIdToAppIdTableToo);
|
||||
StorageUtils.getAuthRecipeStorage(storage)
|
||||
.deleteAccountInfoReservations_Transaction(con, appIdentifier, userId);
|
||||
}
|
||||
|
||||
public static boolean deleteNonAuthRecipeUser(TenantIdentifier tenantIdentifier, Storage storage, String userId)
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.authRecipe.exception;
|
||||
|
||||
public class AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException extends Exception {
|
||||
public final String primaryUserId;
|
||||
|
||||
public AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException(String primaryUserId, String description) {
|
||||
super(description);
|
||||
this.primaryUserId = primaryUserId;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.ResourceDistributor;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
|
|
@ -29,9 +29,9 @@ import io.supertokens.emailpassword.EmailPassword;
|
|||
import io.supertokens.emailpassword.PasswordHashing;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
import io.supertokens.multitenancy.Multitenancy;
|
||||
import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithEmailAlreadyExistsException;
|
||||
import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException;
|
||||
import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithEmailAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException;
|
||||
import io.supertokens.output.Logging;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.List;
|
|||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import io.supertokens.Main;
|
||||
|
|
@ -31,7 +32,7 @@ import io.supertokens.ResourceDistributor;
|
|||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.config.Config;
|
||||
import io.supertokens.config.CoreConfig;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailpassword.exceptions.ResetPasswordInvalidTokenException;
|
||||
import io.supertokens.emailpassword.exceptions.UnsupportedPasswordHashingFormatException;
|
||||
import io.supertokens.emailpassword.exceptions.WrongCredentialsException;
|
||||
|
|
@ -667,30 +668,10 @@ public class EmailPassword {
|
|||
}
|
||||
|
||||
if (email != null) {
|
||||
if (user.isPrimaryUser) {
|
||||
for (String tenantId : user.tenantIds) {
|
||||
AuthRecipeUserInfo[] existingUsersWithNewEmail =
|
||||
authRecipeStorage.listPrimaryUsersByEmail_Transaction(
|
||||
appIdentifier, transaction,
|
||||
email);
|
||||
|
||||
for (AuthRecipeUserInfo userWithSameEmail : existingUsersWithNewEmail) {
|
||||
if (!userWithSameEmail.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (userWithSameEmail.isPrimaryUser && !userWithSameEmail.getSupertokensUserId()
|
||||
.equals(user.getSupertokensUserId())) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new EmailChangeNotAllowedException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
epStorage.updateUsersEmail_Transaction(appIdentifier, transaction,
|
||||
userId, email);
|
||||
} catch (DuplicateEmailException e) {
|
||||
epStorage.updateUsersEmail_Transaction(appIdentifier, transaction, userId, email);
|
||||
} catch (DuplicateEmailException | EmailChangeNotAllowedException |
|
||||
PhoneNumberChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.emailpassword.exceptions;
|
||||
|
||||
public class EmailChangeNotAllowedException extends Exception {
|
||||
private static final long serialVersionUID = -7205953190075543040L;
|
||||
}
|
||||
|
|
@ -24,6 +24,8 @@ import io.supertokens.inmemorydb.config.SQLiteConfig;
|
|||
import io.supertokens.inmemorydb.queries.*;
|
||||
import io.supertokens.pluginInterface.*;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.CanBecomePrimaryResult;
|
||||
import io.supertokens.pluginInterface.authRecipe.CanLinkAccountsResult;
|
||||
import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
||||
import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage;
|
||||
import io.supertokens.pluginInterface.bulkimport.BulkImportStorage;
|
||||
|
|
@ -1189,7 +1191,7 @@ public class Start
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateUserEmail_Transaction(AppIdentifier appIdentifier, TransactionConnection con,
|
||||
public void updateUserEmail_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String userId,
|
||||
String thirdPartyId, String thirdPartyUserId,
|
||||
String newEmail) throws StorageQueryException {
|
||||
Connection sqlCon = (Connection) con.getConnection();
|
||||
|
|
@ -1328,6 +1330,38 @@ public class Start
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CanBecomePrimaryResult checkIfLoginMethodCanBecomePrimary_Transaction(AppIdentifier appIdentifier, TransactionConnection con,
|
||||
LoginMethod loginMethod) throws
|
||||
StorageQueryException {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CanLinkAccountsResult checkIfLoginMethodsCanBeLinked_Transaction(TransactionConnection con,
|
||||
AppIdentifier appIdentifier,
|
||||
Set<String> tenantIds, Set<String> emails,
|
||||
Set<String> phoneNumbers,
|
||||
Set<LoginMethod.ThirdParty> thirdParties,
|
||||
String primaryUserId)
|
||||
throws StorageQueryException {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTenantIdToPrimaryUser_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con,
|
||||
String supertokensUserId) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAccountInfoReservations_Transaction(TransactionConnection con, AppIdentifier appIdentifier,
|
||||
String userId) throws StorageQueryException {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLastActive(AppIdentifier appIdentifier, String userId) throws StorageQueryException {
|
||||
try {
|
||||
|
|
@ -3648,7 +3682,7 @@ public class Start
|
|||
public AuthRecipeUserInfo signUpWithCredentialsRegister_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con,
|
||||
String userId, String email, String relyingPartyId, WebAuthNStoredCredential credential)
|
||||
throws StorageQueryException, io.supertokens.pluginInterface.webauthn.exceptions.DuplicateUserIdException, TenantOrAppNotFoundException,
|
||||
DuplicateUserEmailException {
|
||||
DuplicateEmailException {
|
||||
Connection sqlCon = (Connection) con.getConnection();
|
||||
try {
|
||||
return WebAuthNQueries.signUpWithCredentialRegister_Transaction(this, sqlCon, tenantIdentifier, userId, email, relyingPartyId, credential);
|
||||
|
|
@ -3659,7 +3693,7 @@ public class Start
|
|||
|
||||
if (isUniqueConstraintError(serverMessage, config.getWebAuthNUserToTenantTable(),
|
||||
new String[]{"app_id", "tenant_id", "email"})) {
|
||||
throw new DuplicateUserEmailException();
|
||||
throw new DuplicateEmailException();
|
||||
} else if (isPrimaryKeyError(serverMessage, config.getWebAuthNUsersTable(),
|
||||
new String[]{"app_id", "user_id"})
|
||||
|| isPrimaryKeyError(serverMessage, config.getUsersTable(),
|
||||
|
|
@ -3693,7 +3727,7 @@ public class Start
|
|||
@Override
|
||||
public AuthRecipeUserInfo signUp_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con,
|
||||
String userId, String email, String relyingPartyId)
|
||||
throws StorageQueryException, TenantOrAppNotFoundException, DuplicateUserEmailException,
|
||||
throws StorageQueryException, TenantOrAppNotFoundException, DuplicateEmailException,
|
||||
io.supertokens.pluginInterface.webauthn.exceptions.DuplicateUserIdException {
|
||||
Connection sqlCon = (Connection) con.getConnection();
|
||||
try {
|
||||
|
|
@ -3705,7 +3739,7 @@ public class Start
|
|||
|
||||
if (isUniqueConstraintError(serverMessage, config.getWebAuthNUserToTenantTable(),
|
||||
new String[]{"app_id", "tenant_id", "email"})) {
|
||||
throw new DuplicateUserEmailException();
|
||||
throw new DuplicateEmailException();
|
||||
} else if (isPrimaryKeyError(serverMessage, config.getWebAuthNUsersTable(),
|
||||
new String[]{"app_id", "user_id"})
|
||||
|| isPrimaryKeyError(serverMessage, config.getUsersTable(),
|
||||
|
|
@ -3809,7 +3843,7 @@ public class Start
|
|||
@Override
|
||||
public void updateUserEmail(TenantIdentifier tenantIdentifier, String userId, String newEmail)
|
||||
throws StorageQueryException, io.supertokens.pluginInterface.webauthn.exceptions.UserIdNotFoundException,
|
||||
DuplicateUserEmailException {
|
||||
DuplicateEmailException {
|
||||
try {
|
||||
WebAuthNQueries.updateUserEmail(this, tenantIdentifier, userId, newEmail);
|
||||
} catch (StorageQueryException e) {
|
||||
|
|
@ -3819,7 +3853,7 @@ public class Start
|
|||
|
||||
if (isUniqueConstraintError(errorMessage, config.getWebAuthNUserToTenantTable(),
|
||||
new String[]{"app_id", "tenant_id", "email"})) {
|
||||
throw new DuplicateUserEmailException();
|
||||
throw new DuplicateEmailException();
|
||||
} else if (isForeignKeyConstraintError(
|
||||
errorMessage,
|
||||
config.getWebAuthNUserToTenantTable(),
|
||||
|
|
@ -3836,7 +3870,7 @@ public class Start
|
|||
public void updateUserEmail_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con, String userId,
|
||||
String newEmail)
|
||||
throws StorageQueryException, io.supertokens.pluginInterface.webauthn.exceptions.UserIdNotFoundException,
|
||||
DuplicateUserEmailException {
|
||||
DuplicateEmailException {
|
||||
try {
|
||||
Connection sqlCon = (Connection) con.getConnection();
|
||||
WebAuthNQueries.updateUserEmail_Transaction(this, sqlCon, tenantIdentifier, userId, newEmail);
|
||||
|
|
@ -3847,7 +3881,7 @@ public class Start
|
|||
|
||||
if (isUniqueConstraintError(errorMessage, config.getWebAuthNUserToTenantTable(),
|
||||
new String[]{"app_id", "tenant_id", "email"})) {
|
||||
throw new DuplicateUserEmailException();
|
||||
throw new DuplicateEmailException();
|
||||
} else if (isForeignKeyConstraintError(
|
||||
errorMessage,
|
||||
config.getWebAuthNUserToTenantTable(),
|
||||
|
|
|
|||
|
|
@ -16,8 +16,19 @@
|
|||
|
||||
package io.supertokens.multitenancy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.ResourceDistributor;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
|
|
@ -26,13 +37,19 @@ import io.supertokens.config.CoreConfig;
|
|||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlag;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
import io.supertokens.multitenancy.exception.*;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithEmailAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.multitenancy.exception.CannotDeleteNullAppIdException;
|
||||
import io.supertokens.multitenancy.exception.CannotDeleteNullConnectionUriDomainException;
|
||||
import io.supertokens.multitenancy.exception.CannotDeleteNullTenantException;
|
||||
import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException;
|
||||
import io.supertokens.pluginInterface.KeyValueInfo;
|
||||
import io.supertokens.pluginInterface.STORAGE_TYPE;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
import io.supertokens.pluginInterface.StorageUtils;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
||||
import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException;
|
||||
|
|
@ -53,10 +70,6 @@ import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUs
|
|||
import io.supertokens.storageLayer.StorageLayer;
|
||||
import io.supertokens.thirdparty.InvalidProviderConfigException;
|
||||
import io.supertokens.thirdparty.ThirdParty;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public class Multitenancy extends ResourceDistributor.SingletonResource {
|
||||
|
||||
|
|
@ -412,123 +425,23 @@ public class Multitenancy extends ResourceDistributor.SingletonResource {
|
|||
AuthRecipeUserInfo userToAssociate = authRecipeStorage.getPrimaryUserById_Transaction(
|
||||
tenantIdentifier.toAppIdentifier(), con, userId);
|
||||
|
||||
if (userToAssociate != null && userToAssociate.isPrimaryUser) {
|
||||
Set<String> emails = new HashSet<>();
|
||||
Set<String> phoneNumbers = new HashSet<>();
|
||||
Set<LoginMethod.ThirdParty> thirdParties = new HashSet<>();
|
||||
|
||||
// Loop through all the emails, phoneNumbers and thirdPartyInfos and check for conflicts
|
||||
for (LoginMethod lM : userToAssociate.loginMethods) {
|
||||
if (lM.email != null) {
|
||||
emails.add(lM.email);
|
||||
}
|
||||
if (lM.phoneNumber != null) {
|
||||
phoneNumbers.add(lM.phoneNumber);
|
||||
}
|
||||
if (lM.thirdParty != null) {
|
||||
thirdParties.add(lM.thirdParty);
|
||||
}
|
||||
}
|
||||
|
||||
for (String email : emails) {
|
||||
AuthRecipeUserInfo[] usersWithSameEmail = authRecipeStorage.listPrimaryUsersByEmail_Transaction(
|
||||
tenantIdentifier.toAppIdentifier(), con, email);
|
||||
for (AuthRecipeUserInfo userWithSameEmail : usersWithSameEmail) {
|
||||
if (userWithSameEmail.getSupertokensUserId()
|
||||
.equals(userToAssociate.getSupertokensUserId())) {
|
||||
continue; // it's the same user, no need to check anything
|
||||
}
|
||||
if (userWithSameEmail.isPrimaryUser && userWithSameEmail.tenantIds.contains(tenantId) &&
|
||||
!userWithSameEmail.getSupertokensUserId().equals(userId)) {
|
||||
for (LoginMethod lm1 : userWithSameEmail.loginMethods) {
|
||||
if (lm1.tenantIds.contains(tenantId)) {
|
||||
for (LoginMethod lm2 : userToAssociate.loginMethods) {
|
||||
if (lm1.recipeId.equals(lm2.recipeId) && email.equals(lm1.email) &&
|
||||
lm1.email.equals(lm2.email)) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new DuplicateEmailException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new StorageTransactionLogicException(
|
||||
new AnotherPrimaryUserWithEmailAlreadyExistsException(
|
||||
userWithSameEmail.getSupertokensUserId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String phoneNumber : phoneNumbers) {
|
||||
AuthRecipeUserInfo[] usersWithSamePhoneNumber =
|
||||
authRecipeStorage.listPrimaryUsersByPhoneNumber_Transaction(
|
||||
tenantIdentifier.toAppIdentifier(), con, phoneNumber);
|
||||
for (AuthRecipeUserInfo userWithSamePhoneNumber : usersWithSamePhoneNumber) {
|
||||
if (userWithSamePhoneNumber.getSupertokensUserId()
|
||||
.equals(userToAssociate.getSupertokensUserId())) {
|
||||
continue; // it's the same user, no need to check anything
|
||||
}
|
||||
if (userWithSamePhoneNumber.tenantIds.contains(tenantId) &&
|
||||
!userWithSamePhoneNumber.getSupertokensUserId().equals(userId)) {
|
||||
for (LoginMethod lm1 : userWithSamePhoneNumber.loginMethods) {
|
||||
if (lm1.tenantIds.contains(tenantId)) {
|
||||
for (LoginMethod lm2 : userToAssociate.loginMethods) {
|
||||
if (lm1.recipeId.equals(lm2.recipeId) &&
|
||||
phoneNumber.equals(lm1.phoneNumber) &&
|
||||
lm1.phoneNumber.equals(lm2.phoneNumber)) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new DuplicatePhoneNumberException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new StorageTransactionLogicException(
|
||||
new AnotherPrimaryUserWithPhoneNumberAlreadyExistsException(
|
||||
userWithSamePhoneNumber.getSupertokensUserId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (LoginMethod.ThirdParty tp : thirdParties) {
|
||||
AuthRecipeUserInfo[] usersWithSameThirdPartyInfo =
|
||||
authRecipeStorage.listPrimaryUsersByThirdPartyInfo_Transaction(
|
||||
tenantIdentifier.toAppIdentifier(), con, tp.id, tp.userId);
|
||||
for (AuthRecipeUserInfo userWithSameThirdPartyInfo : usersWithSameThirdPartyInfo) {
|
||||
if (userWithSameThirdPartyInfo.getSupertokensUserId()
|
||||
.equals(userToAssociate.getSupertokensUserId())) {
|
||||
continue; // it's the same user, no need to check anything
|
||||
}
|
||||
if (userWithSameThirdPartyInfo.tenantIds.contains(tenantId) &&
|
||||
!userWithSameThirdPartyInfo.getSupertokensUserId().equals(userId)) {
|
||||
for (LoginMethod lm1 : userWithSameThirdPartyInfo.loginMethods) {
|
||||
if (lm1.tenantIds.contains(tenantId)) {
|
||||
for (LoginMethod lm2 : userToAssociate.loginMethods) {
|
||||
if (lm1.recipeId.equals(lm2.recipeId) && tp.equals(lm1.thirdParty) &&
|
||||
lm1.thirdParty.equals(lm2.thirdParty)) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new DuplicateThirdPartyUserException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new StorageTransactionLogicException(
|
||||
new AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException(
|
||||
userWithSameThirdPartyInfo.getSupertokensUserId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// userToAssociate may be null if the user is not associated to any tenants, we can still try and
|
||||
// associate it. This happens only in CDI 3.0 where we allow disassociation from all tenants
|
||||
// This will not happen in CDI >= 4.0 because we will not allow disassociation from all tenants
|
||||
try {
|
||||
if (userToAssociate != null && userToAssociate.isPrimaryUser) {
|
||||
authRecipeStorage.addTenantIdToPrimaryUser_Transaction(tenantIdentifier, con, userToAssociate.getSupertokensUserId());
|
||||
}
|
||||
|
||||
// userToAssociate may be null if the user is not associated to any tenants, we can still try and
|
||||
// associate it. This happens only in CDI 3.0 where we allow disassociation from all tenants
|
||||
// This will not happen in CDI >= 4.0 because we will not allow disassociation from all tenants
|
||||
boolean result = ((MultitenancySQLStorage) storage).addUserIdToTenant_Transaction(tenantIdentifier,
|
||||
con, userId);
|
||||
authRecipeStorage.commitTransaction(con);
|
||||
return result;
|
||||
} catch (TenantOrAppNotFoundException | UnknownUserIdException | DuplicatePhoneNumberException |
|
||||
DuplicateThirdPartyUserException | DuplicateEmailException e) {
|
||||
DuplicateThirdPartyUserException | DuplicateEmailException |
|
||||
AnotherPrimaryUserWithPhoneNumberAlreadyExistsException |
|
||||
AnotherPrimaryUserWithEmailAlreadyExistsException |
|
||||
AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.multitenancy.exception;
|
||||
|
||||
public class AnotherPrimaryUserWithEmailAlreadyExistsException extends Exception {
|
||||
public AnotherPrimaryUserWithEmailAlreadyExistsException(String primaryUserId) {
|
||||
super("Another primary user with email already exists: " + primaryUserId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.multitenancy.exception;
|
||||
|
||||
public class AnotherPrimaryUserWithPhoneNumberAlreadyExistsException extends Exception {
|
||||
public AnotherPrimaryUserWithPhoneNumberAlreadyExistsException(String primaryUserId) {
|
||||
super("Another primary user with phone number already exists: " + primaryUserId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.multitenancy.exception;
|
||||
|
||||
public class AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException extends Exception {
|
||||
public AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException(String primaryUserId) {
|
||||
super("Another primary user with third party info already exists: " + primaryUserId);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ResourceDistributor;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.config.Config;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.multitenancy.Multitenancy;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.passwordless.exceptions.*;
|
||||
|
|
@ -739,7 +739,7 @@ public class Passwordless {
|
|||
FieldUpdate emailUpdate, FieldUpdate phoneNumberUpdate)
|
||||
throws StorageQueryException, UnknownUserIdException, DuplicateEmailException,
|
||||
DuplicatePhoneNumberException, UserWithoutContactInfoException, EmailChangeNotAllowedException,
|
||||
PhoneNumberChangeNotAllowedException {
|
||||
io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException {
|
||||
Storage storage = StorageLayer.getStorage(main);
|
||||
updateUser(ResourceDistributor.getAppForTesting().toAppIdentifier(), storage,
|
||||
userId, emailUpdate, phoneNumberUpdate);
|
||||
|
|
@ -749,7 +749,7 @@ public class Passwordless {
|
|||
FieldUpdate emailUpdate, FieldUpdate phoneNumberUpdate)
|
||||
throws StorageQueryException, UnknownUserIdException, DuplicateEmailException,
|
||||
DuplicatePhoneNumberException, UserWithoutContactInfoException, EmailChangeNotAllowedException,
|
||||
PhoneNumberChangeNotAllowedException {
|
||||
io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException {
|
||||
PasswordlessSQLStorage plStorage = StorageUtils.getPasswordlessStorage(storage);
|
||||
|
||||
// We do not lock the user here, because we decided that even if the device cleanup used outdated information
|
||||
|
|
@ -778,29 +778,10 @@ public class Passwordless {
|
|||
AuthRecipeSQLStorage authRecipeSQLStorage = StorageUtils.getAuthRecipeStorage(storage);
|
||||
plStorage.startTransaction(con -> {
|
||||
if (emailUpdate != null && !Objects.equals(emailUpdate.newValue, lM.email)) {
|
||||
if (user.isPrimaryUser) {
|
||||
for (String tenantId : user.tenantIds) {
|
||||
AuthRecipeUserInfo[] existingUsersWithNewEmail =
|
||||
authRecipeSQLStorage.listPrimaryUsersByEmail_Transaction(
|
||||
appIdentifier, con,
|
||||
emailUpdate.newValue);
|
||||
|
||||
for (AuthRecipeUserInfo userWithSameEmail : existingUsersWithNewEmail) {
|
||||
if (!userWithSameEmail.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (userWithSameEmail.isPrimaryUser &&
|
||||
!userWithSameEmail.getSupertokensUserId().equals(user.getSupertokensUserId())) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new EmailChangeNotAllowedException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
plStorage.updateUserEmail_Transaction(appIdentifier, con, recipeUserId,
|
||||
emailUpdate.newValue);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
if (lM.email != null) {
|
||||
|
|
@ -828,7 +809,7 @@ public class Passwordless {
|
|||
!userWithSamePhoneNumber.getSupertokensUserId()
|
||||
.equals(user.getSupertokensUserId())) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new PhoneNumberChangeNotAllowedException());
|
||||
new io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -868,8 +849,8 @@ public class Passwordless {
|
|||
throw (EmailChangeNotAllowedException) e.actualException;
|
||||
}
|
||||
|
||||
if (e.actualException instanceof PhoneNumberChangeNotAllowedException) {
|
||||
throw (PhoneNumberChangeNotAllowedException) e.actualException;
|
||||
if (e.actualException instanceof io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException) {
|
||||
throw (io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException) e.actualException;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.passwordless.exceptions;
|
||||
|
||||
public class PhoneNumberChangeNotAllowedException extends Exception {
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ package io.supertokens.thirdparty;
|
|||
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.ResourceDistributor;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.multitenancy.Multitenancy;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.pluginInterface.RECIPE_ID;
|
||||
|
|
@ -27,6 +27,7 @@ import io.supertokens.pluginInterface.StorageUtils;
|
|||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
||||
import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException;
|
||||
|
|
@ -296,29 +297,12 @@ public class ThirdParty {
|
|||
}
|
||||
|
||||
if (!email.equals(lM1.email)) {
|
||||
// before updating the email, we must check for if another primary user has the same
|
||||
// email, and if they do, then we do not allow the update.
|
||||
if (userFromDb1.isPrimaryUser) {
|
||||
for (String tenantId : userFromDb1.tenantIds) {
|
||||
AuthRecipeUserInfo[] userBasedOnEmail =
|
||||
authRecipeStorage.listPrimaryUsersByEmail_Transaction(
|
||||
appIdentifier, con, email
|
||||
);
|
||||
for (AuthRecipeUserInfo userWithSameEmail : userBasedOnEmail) {
|
||||
if (!userWithSameEmail.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (userWithSameEmail.isPrimaryUser &&
|
||||
!userWithSameEmail.getSupertokensUserId()
|
||||
.equals(userFromDb1.getSupertokensUserId())) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new EmailChangeNotAllowedException());
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
tpStorage.updateUserEmail_Transaction(appIdentifier, con, lM1.getSupertokensUserId(),
|
||||
thirdPartyId, thirdPartyUserId, email);
|
||||
} catch (EmailChangeNotAllowedException | DuplicateEmailException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
tpStorage.updateUserEmail_Transaction(appIdentifier, con,
|
||||
thirdPartyId, thirdPartyUserId, email);
|
||||
}
|
||||
|
||||
tpStorage.commitTransaction(con);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ import io.supertokens.pluginInterface.StorageUtils;
|
|||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
|
||||
|
|
@ -281,7 +283,7 @@ public class WebAuthN {
|
|||
|
||||
public static WebAuthNSignInUpResult signUp(Storage storage, TenantIdentifier tenantIdentifier,
|
||||
String optionsId, JsonObject credentialDataJson)
|
||||
throws InvalidWebauthNOptionsException, DuplicateUserEmailException, WebauthNVerificationFailedException,
|
||||
throws InvalidWebauthNOptionsException, DuplicateEmailException, WebauthNVerificationFailedException,
|
||||
StorageQueryException, WebauthNOptionsNotExistsException, WebauthNInvalidFormatException{
|
||||
// create a new user in the auth recipe storage
|
||||
// create new credentials
|
||||
|
|
@ -319,7 +321,7 @@ public class WebAuthN {
|
|||
} catch (DuplicateUserIdException duplicateUserIdException) {
|
||||
//ignore and retry
|
||||
} catch (InvalidWebauthNOptionsException | TenantOrAppNotFoundException |
|
||||
DuplicateUserEmailException | WebauthNVerificationFailedException |
|
||||
DuplicateEmailException | WebauthNVerificationFailedException |
|
||||
WebauthNInvalidFormatException | WebauthNOptionsNotExistsException e) {
|
||||
throw new StorageQueryException(e);
|
||||
}
|
||||
|
|
@ -329,8 +331,8 @@ public class WebAuthN {
|
|||
} catch (StorageQueryException exception) {
|
||||
if (exception.getCause() instanceof InvalidWebauthNOptionsException) {
|
||||
throw (InvalidWebauthNOptionsException) exception.getCause();
|
||||
} else if (exception.getCause() instanceof DuplicateUserEmailException) {
|
||||
throw (DuplicateUserEmailException) exception.getCause();
|
||||
} else if (exception.getCause() instanceof DuplicateEmailException) {
|
||||
throw (DuplicateEmailException) exception.getCause();
|
||||
} else if (exception.getCause() instanceof WebauthNVerificationFailedException) {
|
||||
throw (WebauthNVerificationFailedException) exception.getCause();
|
||||
} else if (exception.getCause() instanceof WebauthNOptionsNotExistsException) {
|
||||
|
|
@ -355,22 +357,22 @@ public class WebAuthN {
|
|||
|
||||
@TestOnly
|
||||
public static AuthRecipeUserInfo saveUser(Storage storage, TenantIdentifier tenantIdentifier, String email, String userId, String rpId)
|
||||
throws StorageQueryException, TenantOrAppNotFoundException, DuplicateUserEmailException,
|
||||
throws StorageQueryException, TenantOrAppNotFoundException, DuplicateEmailException,
|
||||
DuplicateUserIdException {
|
||||
WebAuthNSQLStorage webAuthNStorage = StorageUtils.getWebAuthNStorage(storage);
|
||||
try {
|
||||
return webAuthNStorage.startTransaction(con -> {
|
||||
try {
|
||||
return webAuthNStorage.signUp_Transaction(tenantIdentifier, con, userId, email, rpId);
|
||||
} catch (TenantOrAppNotFoundException | DuplicateUserEmailException | DuplicateUserIdException e) {
|
||||
} catch (TenantOrAppNotFoundException | DuplicateEmailException | DuplicateUserIdException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
});
|
||||
} catch (StorageTransactionLogicException e) {
|
||||
if (e.actualException instanceof TenantOrAppNotFoundException) {
|
||||
throw (TenantOrAppNotFoundException) e.actualException;
|
||||
} else if (e.actualException instanceof DuplicateUserEmailException) {
|
||||
throw (DuplicateUserEmailException) e.actualException;
|
||||
} else if (e.actualException instanceof DuplicateEmailException) {
|
||||
throw (DuplicateEmailException) e.actualException;
|
||||
} else if (e.actualException instanceof DuplicateUserIdException) {
|
||||
throw (DuplicateUserIdException) e.actualException;
|
||||
} else {
|
||||
|
|
@ -633,7 +635,7 @@ public class WebAuthN {
|
|||
}
|
||||
|
||||
public static void updateUserEmail(Storage storage, TenantIdentifier tenantIdentifier, String userId, String email)
|
||||
throws StorageQueryException, UserIdNotFoundException, DuplicateUserEmailException,
|
||||
throws StorageQueryException, UserIdNotFoundException, DuplicateEmailException,
|
||||
EmailChangeNotAllowedException, StorageTransactionLogicException, TenantOrAppNotFoundException {
|
||||
WebAuthNSQLStorage webAuthNStorage = StorageUtils.getWebAuthNStorage(storage);
|
||||
AuthRecipeSQLStorage authRecipeStorage = StorageUtils.getAuthRecipeStorage(storage);
|
||||
|
|
@ -659,30 +661,10 @@ public class WebAuthN {
|
|||
}
|
||||
|
||||
if (email != null) {
|
||||
if (user.isPrimaryUser) {
|
||||
for (String tenantId : user.tenantIds) {
|
||||
AuthRecipeUserInfo[] existingUsersWithNewEmail =
|
||||
authRecipeStorage.listPrimaryUsersByEmail_Transaction(
|
||||
tenantIdentifier.toAppIdentifier(), con,
|
||||
email);
|
||||
|
||||
for (AuthRecipeUserInfo userWithSameEmail : existingUsersWithNewEmail) {
|
||||
if (!userWithSameEmail.tenantIds.contains(tenantId)) {
|
||||
continue;
|
||||
}
|
||||
if (userWithSameEmail.isPrimaryUser && !userWithSameEmail.getSupertokensUserId()
|
||||
.equals(user.getSupertokensUserId())) {
|
||||
throw new StorageTransactionLogicException(
|
||||
new EmailChangeNotAllowedException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
webAuthNStorage.updateUserEmail_Transaction(tenantIdentifier, con,
|
||||
userIdFromMapping, email);
|
||||
} catch (UserIdNotFoundException | DuplicateUserEmailException e) {
|
||||
} catch (UserIdNotFoundException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -692,8 +674,8 @@ public class WebAuthN {
|
|||
Throwable cause = e.getCause();
|
||||
if (cause instanceof UserIdNotFoundException){
|
||||
throw (UserIdNotFoundException) cause;
|
||||
} else if (cause instanceof DuplicateUserEmailException) {
|
||||
throw (DuplicateUserEmailException) cause;
|
||||
} else if (cause instanceof DuplicateEmailException) {
|
||||
throw (DuplicateEmailException) cause;
|
||||
} else if (cause instanceof EmailChangeNotAllowedException) {
|
||||
throw (EmailChangeNotAllowedException) cause;
|
||||
} else if (cause instanceof TenantOrAppNotFoundException) {
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
package io.supertokens.webauthn.exception;
|
||||
|
||||
public class EmailChangeNotAllowedException extends Exception {
|
||||
public EmailChangeNotAllowedException() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.pluginInterface.RECIPE_ID;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import io.supertokens.ActiveUsers;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.output.Logging;
|
||||
import io.supertokens.pluginInterface.RECIPE_ID;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import io.supertokens.Main;
|
|||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
import io.supertokens.multitenancy.Multitenancy;
|
||||
import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithEmailAlreadyExistsException;
|
||||
import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException;
|
||||
import io.supertokens.multitenancy.exception.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithEmailAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.RECIPE_ID;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException;
|
||||
|
|
|
|||
|
|
@ -19,11 +19,11 @@ package io.supertokens.webserver.api.passwordless;
|
|||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.StorageAndUserIdMapping;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
import io.supertokens.passwordless.Passwordless.FieldUpdate;
|
||||
import io.supertokens.passwordless.exceptions.PhoneNumberChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException;
|
||||
import io.supertokens.passwordless.exceptions.UserWithoutContactInfoException;
|
||||
import io.supertokens.pluginInterface.RECIPE_ID;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package io.supertokens.webserver.api.thirdparty;
|
|||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.ActiveUsers;
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.pluginInterface.RECIPE_ID;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.ActiveUsers;
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
|
||||
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
|
||||
import io.supertokens.pluginInterface.webauthn.exceptions.DuplicateUserEmailException;
|
||||
import io.supertokens.pluginInterface.webauthn.exceptions.WebauthNOptionsNotExistsException;
|
||||
import io.supertokens.utils.SemVer;
|
||||
import io.supertokens.webauthn.WebAuthN;
|
||||
|
|
@ -86,7 +86,7 @@ public class SignUpWithCredentialRegisterAPI extends WebserverAPI {
|
|||
result.addProperty("status", "INVALID_OPTIONS_ERROR");
|
||||
result.addProperty("reason", e.getMessage());
|
||||
sendJsonResponse(200, result, resp);
|
||||
} catch (DuplicateUserEmailException e) {
|
||||
} catch (DuplicateEmailException e) {
|
||||
JsonObject result = new JsonObject();
|
||||
result.addProperty("status", "EMAIL_ALREADY_EXISTS_ERROR");
|
||||
sendJsonResponse(200, result, resp);
|
||||
|
|
|
|||
|
|
@ -19,14 +19,14 @@ package io.supertokens.webserver.api.webauthn;
|
|||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
|
||||
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
|
||||
import io.supertokens.pluginInterface.webauthn.exceptions.DuplicateUserEmailException;
|
||||
import io.supertokens.pluginInterface.webauthn.exceptions.UserIdNotFoundException;
|
||||
import io.supertokens.webauthn.WebAuthN;
|
||||
import io.supertokens.webauthn.exception.EmailChangeNotAllowedException;
|
||||
import io.supertokens.webserver.InputParser;
|
||||
import io.supertokens.webserver.WebserverAPI;
|
||||
import jakarta.servlet.ServletException;
|
||||
|
|
@ -68,7 +68,7 @@ public class UpdateUserEmailAPI extends WebserverAPI {
|
|||
JsonObject result = new JsonObject();
|
||||
result.addProperty("status", "UNKNOWN_USER_ID_ERROR");
|
||||
sendJsonResponse(200, result, resp);
|
||||
} catch (DuplicateUserEmailException e) {
|
||||
} catch (DuplicateEmailException e) {
|
||||
JsonObject result = new JsonObject();
|
||||
result.addProperty("status", "EMAIL_ALREADY_EXISTS_ERROR");
|
||||
sendJsonResponse(200, result, resp);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.supertokens.ProcessState;
|
|||
import io.supertokens.ResourceDistributor;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.UserPaginationContainer;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package io.supertokens.test;
|
|||
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailpassword.exceptions.WrongCredentialsException;
|
||||
import io.supertokens.pluginInterface.STORAGE_TYPE;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
|
|
|
|||
|
|
@ -69,9 +69,6 @@ public class StorageTest {
|
|||
Utils.reset();
|
||||
}
|
||||
|
||||
@Rule
|
||||
public Retry retry = new Retry(3);
|
||||
|
||||
@Test
|
||||
public void transactionIsolationWithoutAnInitialRowTesting() throws Exception {
|
||||
String[] args = {"../"};
|
||||
|
|
@ -144,10 +141,9 @@ public class StorageTest {
|
|||
KeyValueInfo info = sqlStorage.getKeyValue_Transaction(
|
||||
new TenantIdentifier(null, null, null), con, key);
|
||||
|
||||
if (numberOfIterations.get() != 1) {
|
||||
assert (info == null);
|
||||
} else {
|
||||
assert (info != null);
|
||||
|
||||
if (info != null) {
|
||||
assertTrue(numberOfIterations.get() > 0);
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -184,7 +180,7 @@ public class StorageTest {
|
|||
t2.join();
|
||||
|
||||
assertEquals(endValueOfCon1.get(), endValueOfCon2.get());
|
||||
assertEquals(numberOfIterations.get(), 1);
|
||||
assertTrue(numberOfIterations.get() >= 1);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package io.supertokens.test.accountlinking;
|
|||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
@ -34,7 +34,6 @@ import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
|||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
|
||||
import io.supertokens.pluginInterface.passwordless.exception.DuplicateLinkCodeHashException;
|
||||
import io.supertokens.storageLayer.StorageLayer;
|
||||
import io.supertokens.test.TestingProcessManager;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.ActiveUsers;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
|
|
|
|||
|
|
@ -16,58 +16,68 @@
|
|||
|
||||
package io.supertokens.test.accountlinking;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailpassword.exceptions.WrongCredentialsException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
import io.supertokens.multitenancy.Multitenancy;
|
||||
import io.supertokens.multitenancy.exception.*;
|
||||
import io.supertokens.multitenancy.exception.BadPermissionException;
|
||||
import io.supertokens.multitenancy.exception.CannotModifyBaseConfigException;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
import io.supertokens.passwordless.exceptions.PhoneNumberChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.PhoneNumberChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.STORAGE_TYPE;
|
||||
import io.supertokens.pluginInterface.Storage;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.LoginMethod;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithEmailAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithPhoneNumberAlreadyExistsException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException;
|
||||
import io.supertokens.pluginInterface.exceptions.InvalidConfigException;
|
||||
import io.supertokens.pluginInterface.exceptions.StorageQueryException;
|
||||
import io.supertokens.pluginInterface.multitenancy.*;
|
||||
import io.supertokens.pluginInterface.multitenancy.EmailPasswordConfig;
|
||||
import io.supertokens.pluginInterface.multitenancy.PasswordlessConfig;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantConfig;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
|
||||
import io.supertokens.pluginInterface.multitenancy.ThirdPartyConfig;
|
||||
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
|
||||
import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException;
|
||||
import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUserException;
|
||||
import io.supertokens.storageLayer.StorageLayer;
|
||||
import io.supertokens.test.TestingProcessManager;
|
||||
import io.supertokens.test.Utils;
|
||||
import io.supertokens.thirdparty.InvalidProviderConfigException;
|
||||
import io.supertokens.thirdparty.ThirdParty;
|
||||
import io.supertokens.userroles.UserRoles;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TestRule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class MultitenantTest {
|
||||
@Rule
|
||||
public TestRule watchman = Utils.getOnFailure();
|
||||
|
||||
@Rule
|
||||
public TestRule retryFlaky = Utils.retryFlakyTest();
|
||||
// @Rule
|
||||
// public TestRule retryFlaky = Utils.retryFlakyTest();
|
||||
|
||||
@AfterClass
|
||||
public static void afterTesting() {
|
||||
|
|
@ -79,7 +89,7 @@ public class MultitenantTest {
|
|||
Utils.reset();
|
||||
}
|
||||
|
||||
TenantIdentifier t1, t2, t3, t4;
|
||||
TenantIdentifier t1, t2, t3;
|
||||
|
||||
private void createTenants(Main main)
|
||||
throws StorageQueryException, TenantOrAppNotFoundException, InvalidProviderConfigException,
|
||||
|
|
@ -375,22 +385,21 @@ public class MultitenantTest {
|
|||
t1 = new TenantIdentifier(null, "a1", null);
|
||||
t2 = new TenantIdentifier(null, "a1", "t1");
|
||||
t3 = new TenantIdentifier(null, "a1", "t2");
|
||||
t4 = new TenantIdentifier(null, "a1", "t3");
|
||||
|
||||
TestCase[] testCases = new TestCase[]{
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 0 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new AssociateUserToTenant(t2, 0),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 1 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test@example.com"),
|
||||
new AssociateUserToTenant(t2, 0),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 2 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -398,7 +407,7 @@ public class MultitenantTest {
|
|||
new SignInEmailPasswordUser(t2, 0).expect(new WrongCredentialsException())
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 3 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -408,7 +417,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 2), // Allowed
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 4 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -419,7 +428,7 @@ public class MultitenantTest {
|
|||
new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 5 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -430,7 +439,7 @@ public class MultitenantTest {
|
|||
new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException("", "")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 6 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -440,7 +449,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 2), // Allowed
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 7 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -451,7 +460,7 @@ public class MultitenantTest {
|
|||
new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 8 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -462,7 +471,7 @@ public class MultitenantTest {
|
|||
new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException("", "")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 9 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -472,7 +481,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 2), // Allowed
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 10 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -483,7 +492,7 @@ public class MultitenantTest {
|
|||
new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 11 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -494,7 +503,7 @@ public class MultitenantTest {
|
|||
new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException("", "")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 12 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test2@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -503,7 +512,7 @@ public class MultitenantTest {
|
|||
new UpdatePlessUserEmail(t1, 0, "test2@example.com"),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 13 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -511,10 +520,10 @@ public class MultitenantTest {
|
|||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdatePlessUserEmail(t1, 0, "test3@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
new DuplicateEmailException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 14 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -522,10 +531,10 @@ public class MultitenantTest {
|
|||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdatePlessUserEmail(t1, 1, "test1@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
new DuplicateEmailException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 15 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithPhone(t1, "+1000001"),
|
||||
new CreatePlessUserWithPhone(t1, "+1000003"),
|
||||
new CreatePlessUserWithPhone(t2, "+1000002"),
|
||||
|
|
@ -535,7 +544,7 @@ public class MultitenantTest {
|
|||
new UpdatePlessUserPhone(t1, 0, "+1000003").expect(new PhoneNumberChangeNotAllowedException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 16 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithPhone(t1, "+1000001"),
|
||||
new CreatePlessUserWithPhone(t1, "+1000003"),
|
||||
new CreatePlessUserWithPhone(t2, "+1000002"),
|
||||
|
|
@ -545,7 +554,7 @@ public class MultitenantTest {
|
|||
new UpdatePlessUserPhone(t1, 1, "+1000001").expect(new PhoneNumberChangeNotAllowedException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 17 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -553,10 +562,10 @@ public class MultitenantTest {
|
|||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdateEmailPasswordUserEmail(t1, 0, "test3@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
new DuplicateEmailException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 18 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -564,10 +573,10 @@ public class MultitenantTest {
|
|||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdateEmailPasswordUserEmail(t1, 1, "test1@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
new DuplicateEmailException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 19 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "googleid", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -577,7 +586,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 2), // Allowed
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 20 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "googleid", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -588,7 +597,7 @@ public class MultitenantTest {
|
|||
new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 21 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "googleid", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -599,7 +608,7 @@ public class MultitenantTest {
|
|||
new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException("", "")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 22 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -609,7 +618,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 2), // Allowed
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 23 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -620,7 +629,7 @@ public class MultitenantTest {
|
|||
new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 24 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -631,7 +640,7 @@ public class MultitenantTest {
|
|||
new AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException("", "")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 25 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid1", "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "googleid2", "test2@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -640,7 +649,7 @@ public class MultitenantTest {
|
|||
new CreateThirdPartyUser(t1, "google", "googleid1", "test2@example.com"),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 26 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid1", "test1@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid3", "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -651,7 +660,7 @@ public class MultitenantTest {
|
|||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 27 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid1", "test1@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid3", "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test2@example.com"),
|
||||
|
|
@ -662,30 +671,30 @@ public class MultitenantTest {
|
|||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 28 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithPhone(t1, "+1000001"),
|
||||
new CreatePlessUserWithPhone(t2, "+1000002"),
|
||||
new CreatePlessUserWithPhone(t3, "+1000001"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new LinkAccounts(t1, 0, 1),
|
||||
new MakePrimaryUser(t3, 2),
|
||||
new AssociateUserToTenant(t1, 2).expect(new DuplicatePhoneNumberException()),
|
||||
new AssociateUserToTenant(t1, 2).expect(new AnotherPrimaryUserWithPhoneNumberAlreadyExistsException("")),
|
||||
new AssociateUserToTenant(t2, 2).expect(
|
||||
new AnotherPrimaryUserWithPhoneNumberAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 29 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid1", "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "googleid2", "test2@example.com"),
|
||||
new CreateThirdPartyUser(t3, "google", "googleid1", "test3@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new LinkAccounts(t1, 0, 1),
|
||||
new MakePrimaryUser(t3, 2),
|
||||
new AssociateUserToTenant(t1, 2).expect(new DuplicateThirdPartyUserException()),
|
||||
new AssociateUserToTenant(t1, 2).expect(new io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException("")),
|
||||
new AssociateUserToTenant(t2, 2).expect(
|
||||
new AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException("")),
|
||||
new io.supertokens.pluginInterface.authRecipe.exceptions.AnotherPrimaryUserWithThirdPartyInfoAlreadyExistsException("")),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 30 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid1", "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "googleid2", "test2@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid3", "test3@example.com"),
|
||||
|
|
@ -697,7 +706,7 @@ public class MultitenantTest {
|
|||
new CreateThirdPartyUser(t1, "google", "googleid3", "test1@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 31 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -706,7 +715,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 0).expect(new UnknownUserIdException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 32 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -715,7 +724,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t2, 0).expect(new UnknownUserIdException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 33 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "googleid1", "test@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid2", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -723,7 +732,7 @@ public class MultitenantTest {
|
|||
new UnlinkAccount(t1, 0),
|
||||
new AssociateUserToTenant(t2, 0).expect(new UnknownUserIdException()),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 34 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -743,7 +752,7 @@ public class MultitenantTest {
|
|||
}
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 35 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new DisassociateUserFromTenant(t1, 0),
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
|
|
@ -756,7 +765,7 @@ public class MultitenantTest {
|
|||
new RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException(null, "")),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 36 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
new DisassociateUserFromTenant(t1, 0),
|
||||
new CreateEmailPasswordUser(t1, "test@example.com"),
|
||||
|
|
@ -767,7 +776,7 @@ public class MultitenantTest {
|
|||
new AssociateUserToTenant(t1, 1).expect(new DuplicateEmailException()),
|
||||
new AssociateUserToTenant(t2, 1),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 37 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -792,33 +801,33 @@ public class MultitenantTest {
|
|||
}
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 38 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new UpdatePlessUserEmail(t1, 1, "test1@example.com"),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 39 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new UpdateEmailPasswordUserEmail(t1, 1, "test1@example.com"),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 40 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 1),
|
||||
new UpdatePlessUserEmail(t1, 1, "test1@example.com"),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 41 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 1),
|
||||
new UpdateEmailPasswordUserEmail(t1, 1, "test1@example.com"),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 42 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -826,7 +835,7 @@ public class MultitenantTest {
|
|||
new UpdatePlessUserEmail(t1, 1, "test1@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 43 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -835,19 +844,19 @@ public class MultitenantTest {
|
|||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 44 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test2@example.com"), // allowed
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 45 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 1),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test2@example.com"), // allowed
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 46 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateThirdPartyUser(t1, "google", "googleid", "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -855,7 +864,7 @@ public class MultitenantTest {
|
|||
new CreateThirdPartyUser(t1, "google", "googleid", "test1@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
new TestCase(new TestCaseStep[]{
|
||||
/* 47 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test3@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
|
|
@ -865,6 +874,38 @@ public class MultitenantTest {
|
|||
new CreateThirdPartyUser(t2, "google", "googleid", "test1@example.com").expect(
|
||||
new EmailChangeNotAllowedException()),
|
||||
}),
|
||||
/* 48 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateEmailPasswordUser(t1, "test1@example.com"),
|
||||
new CreateEmailPasswordUser(t2, "test3@example.com"),
|
||||
new CreatePlessUserWithEmail(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdateEmailPasswordUserEmail(t2, 1, "test2@example.com"),
|
||||
new AssociateUserToTenant(t1, 1).expect(new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
/* 49 */ new TestCase(new TestCaseStep[]{
|
||||
new CreatePlessUserWithEmail(t1, "test1@example.com"),
|
||||
new CreatePlessUserWithEmail(t2, "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdatePlessUserEmail(t2, 1, "test2@example.com"),
|
||||
new AssociateUserToTenant(t1, 1).expect(new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
}),
|
||||
|
||||
/* 50 */ new TestCase(new TestCaseStep[]{
|
||||
new CreateThirdPartyUser(t1, "google", "gid1", "test1@example.com"),
|
||||
new CreateThirdPartyUser(t2, "google", "gid3", "test3@example.com"),
|
||||
new CreateEmailPasswordUser(t1, "test2@example.com"),
|
||||
new MakePrimaryUser(t1, 0),
|
||||
new LinkAccounts(t1, 0, 2),
|
||||
new MakePrimaryUser(t2, 1),
|
||||
new UpdateThirdPartyUserEmail(t2, "google", "gid3", "test2@example.com"),
|
||||
new AssociateUserToTenant(t1, 1).expect(new AnotherPrimaryUserWithEmailAlreadyExistsException("")),
|
||||
})
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
|
|
@ -933,7 +974,10 @@ public class MultitenantTest {
|
|||
this.execute(main);
|
||||
fail();
|
||||
} catch (Exception e) {
|
||||
assertEquals(this.e.getClass(), e.getClass());
|
||||
if (!this.e.getClass().equals(e.getClass())) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// assertEquals(this.e.getClass(), e.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1139,6 +1183,27 @@ public class MultitenantTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static class UpdateThirdPartyUserEmail extends TestCaseStep {
|
||||
private final TenantIdentifier tenantIdentifier;
|
||||
private final String thirdPartyId;
|
||||
private final String thirdPartyUserId;
|
||||
private final String email;
|
||||
|
||||
public UpdateThirdPartyUserEmail(TenantIdentifier tenantIdentifier, String thirdPartyId, String thirdPartyUserId,
|
||||
String email) {
|
||||
this.tenantIdentifier = tenantIdentifier;
|
||||
this.thirdPartyId = thirdPartyId;
|
||||
this.thirdPartyUserId = thirdPartyUserId;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Main main) throws Exception {
|
||||
Storage storage = (StorageLayer.getStorage(tenantIdentifier, main));
|
||||
ThirdParty.signInUp(tenantIdentifier, storage, main, thirdPartyId, thirdPartyUserId, email);
|
||||
}
|
||||
}
|
||||
|
||||
private static class UnlinkAccount extends TestCaseStep {
|
||||
TenantIdentifier tenantIdentifier;
|
||||
int userIndex;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
|
|||
|
|
@ -17,13 +17,12 @@
|
|||
package io.supertokens.test.accountlinking.api;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.passwordless.Passwordless;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import io.supertokens.ProcessState;
|
|||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.UserPaginationContainer;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import io.supertokens.authRecipe.AuthRecipe;
|
|||
import io.supertokens.config.Config;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.PasswordHashing;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailpassword.exceptions.ResetPasswordInvalidTokenException;
|
||||
import io.supertokens.emailpassword.exceptions.WrongCredentialsException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
|
|
@ -925,7 +925,7 @@ public class EmailPasswordTest {
|
|||
EmailPassword.updateUsersEmailOrPassword(process.getProcess(), user.getSupertokensUserId(), "someemail1@gmail.com",
|
||||
null);
|
||||
assert (false);
|
||||
} catch (EmailChangeNotAllowedException ignored) {
|
||||
} catch (DuplicateEmailException ignored) {
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1011,7 +1011,7 @@ public class EmailPasswordTest {
|
|||
EmailPassword.updateUsersEmailOrPassword(process.getProcess(), user.getSupertokensUserId(), "someemail1@gmail.com",
|
||||
null);
|
||||
assert (false);
|
||||
} catch (EmailChangeNotAllowedException ignored) {
|
||||
} catch (DuplicateEmailException ignored) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package io.supertokens.test.emailpassword;
|
|||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailpassword.exceptions.WrongCredentialsException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
|
|
@ -369,15 +369,17 @@ public class MultitenantEmailPasswordTest {
|
|||
EmailChangeNotAllowedException {
|
||||
String[] args = {"../"};
|
||||
|
||||
TestingProcessManager.TestingProcess process = TestingProcessManager.startIsolatedProcess(args);
|
||||
TestingProcessManager.TestingProcess process = TestingProcessManager.startIsolatedProcess(args, false);
|
||||
FeatureFlagTestContent.getInstance(process.getProcess())
|
||||
.setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY});
|
||||
process.startProcess();
|
||||
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED));
|
||||
|
||||
if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
createTenants(process);
|
||||
|
||||
TenantIdentifier t1 = new TenantIdentifier(null, process.getAppForTesting().getAppId() + "a1", null);
|
||||
|
|
|
|||
|
|
@ -83,9 +83,8 @@ public class UserPutAPITest4_0 {
|
|||
"http://localhost:3567/recipe/user", body, 1000, 1000, null, SemVer.v4_0.get(),
|
||||
RECIPE_ID.EMAIL_PASSWORD.toString());
|
||||
|
||||
assertEquals("EMAIL_CHANGE_NOT_ALLOWED_ERROR", response.get("status").getAsString());
|
||||
assertEquals("New email is associated with another primary user ID", response.get("reason").getAsString());
|
||||
assertEquals(2, response.entrySet().size());
|
||||
assertEquals("EMAIL_ALREADY_EXISTS_ERROR", response.get("status").getAsString());
|
||||
assertEquals(1, response.entrySet().size());
|
||||
|
||||
process.kill();
|
||||
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ public class HttpRequestForTesting {
|
|||
con = (HttpURLConnection) obj.openConnection();
|
||||
con.setRequestMethod(method);
|
||||
con.setConnectTimeout(connectionTimeoutMS);
|
||||
con.setReadTimeout(readTimeoutMS + 1000);
|
||||
con.setReadTimeout(readTimeoutMS);
|
||||
con.setInstanceFollowRedirects(followRedirects);
|
||||
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
|
||||
if (version != null) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ import java.util.Arrays;
|
|||
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import org.apache.commons.codec.binary.Base32;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
|
@ -67,7 +69,6 @@ import io.supertokens.pluginInterface.webauthn.AccountRecoveryTokenInfo;
|
|||
import io.supertokens.pluginInterface.webauthn.WebAuthNOptions;
|
||||
import io.supertokens.pluginInterface.webauthn.WebAuthNStorage;
|
||||
import io.supertokens.pluginInterface.webauthn.WebAuthNStoredCredential;
|
||||
import io.supertokens.pluginInterface.webauthn.exceptions.DuplicateUserEmailException;
|
||||
import io.supertokens.pluginInterface.webauthn.exceptions.DuplicateUserIdException;
|
||||
import io.supertokens.pluginInterface.webauthn.slqStorage.WebAuthNSQLStorage;
|
||||
import io.supertokens.session.Session;
|
||||
|
|
@ -154,6 +155,7 @@ public class TestAppData {
|
|||
"password");
|
||||
EmailPassword.generatePasswordResetTokenBeforeCdi4_0(app, appStorage, process.getProcess(),
|
||||
epUser.getSupertokensUserId());
|
||||
AuthRecipe.createPrimaryUser(process.getProcess(), app.toAppIdentifier(), appStorage, epUser.getSupertokensUserId());
|
||||
|
||||
ThirdParty.SignInUpResponse tpUser = ThirdParty.signInUp(app, appStorage, process.getProcess(), "google",
|
||||
"googleid", "test@example.com");
|
||||
|
|
@ -225,7 +227,7 @@ public class TestAppData {
|
|||
((WebAuthNSQLStorage) appStorage).signUpWithCredentialsRegister_Transaction(app, con, "userId", "test2@example.com", "example.com", credential);
|
||||
} catch (DuplicateUserIdException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (DuplicateUserEmailException e) {
|
||||
} catch (DuplicateEmailException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public class TestMultitenancyAPIHelper {
|
|||
throws HttpResponseException, IOException {
|
||||
JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/connectionuridomain/list"),
|
||||
null, 1000, 1000, null,
|
||||
null, 1000, 2500, null,
|
||||
SemVer.v3_0.get(), "multitenancy");
|
||||
|
||||
assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
|
||||
|
|
@ -160,7 +160,7 @@ public class TestMultitenancyAPIHelper {
|
|||
throws HttpResponseException, IOException {
|
||||
JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/app/list"),
|
||||
null, 1000, 1000, null,
|
||||
null, 1000, 2500, null,
|
||||
SemVer.v3_0.get(), "multitenancy");
|
||||
|
||||
assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
|
||||
|
|
@ -229,7 +229,7 @@ public class TestMultitenancyAPIHelper {
|
|||
throws HttpResponseException, IOException {
|
||||
JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/recipe/multitenancy/tenant/list"),
|
||||
null, 1000, 1000, null,
|
||||
null, 1000, 2500, null,
|
||||
SemVer.v3_0.get(), "multitenancy");
|
||||
|
||||
assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
|
||||
|
|
@ -260,7 +260,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant"),
|
||||
null, 1000, 1000, null,
|
||||
null, 1000, 2500, null,
|
||||
version.get(), "multitenancy");
|
||||
|
||||
assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
|
||||
|
|
@ -274,7 +274,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant/user"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "multitenancy");
|
||||
|
||||
return response;
|
||||
|
|
@ -287,7 +287,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant/user/remove"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "multitenancy");
|
||||
|
||||
assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
|
||||
|
|
@ -348,7 +348,7 @@ public class TestMultitenancyAPIHelper {
|
|||
}
|
||||
JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(sourceTenant, "/users"),
|
||||
params, 1000, 1000, null,
|
||||
params, 1000, 2500, null,
|
||||
SemVer.v3_0.get(), null);
|
||||
|
||||
assertEquals("OK", response.getAsJsonPrimitive("status").getAsString());
|
||||
|
|
@ -373,7 +373,7 @@ public class TestMultitenancyAPIHelper {
|
|||
requestBody.addProperty("password", password);
|
||||
JsonObject signUpResponse = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signup"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
version.get(), "emailpassword");
|
||||
return signUpResponse;
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ public class TestMultitenancyAPIHelper {
|
|||
requestBody.addProperty("password", password);
|
||||
JsonObject signUpResponse = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signin"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
version.get(), "emailpassword");
|
||||
return signUpResponse;
|
||||
}
|
||||
|
|
@ -424,7 +424,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signinup"), signUpRequestBody,
|
||||
1000, 1000, null,
|
||||
1000, 2500, null,
|
||||
version.get(), "thirdparty");
|
||||
return response;
|
||||
}
|
||||
|
|
@ -456,7 +456,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signinup/code"),
|
||||
createCodeRequestBody, 1000, 1000, null,
|
||||
createCodeRequestBody, 1000, 2500, null,
|
||||
version.get(), "passwordless");
|
||||
|
||||
assertEquals("OK", response.get("status").getAsString());
|
||||
|
|
@ -495,7 +495,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
return HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signinup/code/consume"),
|
||||
consumeCodeRequestBody, 1000, 1000, null,
|
||||
consumeCodeRequestBody, 1000, 2500, null,
|
||||
version.get(), "passwordless");
|
||||
}
|
||||
|
||||
|
|
@ -508,7 +508,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
return HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signinup/code/consume"),
|
||||
consumeCodeRequestBody, 1000, 1000, null,
|
||||
consumeCodeRequestBody, 1000, 2500, null,
|
||||
version.get(), "passwordless");
|
||||
}
|
||||
|
||||
|
|
@ -548,7 +548,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/signinup/code"),
|
||||
createCodeRequestBody, 1000, 1000, null,
|
||||
createCodeRequestBody, 1000, 2500, null,
|
||||
version.get(), "passwordless");
|
||||
|
||||
assertEquals("OK", response.get("status").getAsString());
|
||||
|
|
@ -594,7 +594,7 @@ public class TestMultitenancyAPIHelper {
|
|||
public static void removeLicense(Main main) throws HttpResponseException, IOException {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonDELETERequest(main, "",
|
||||
"http://localhost:3567/ee/license", null,
|
||||
1000, 1000, null,
|
||||
1000, 2500, null,
|
||||
SemVer.v3_0.get(), null);
|
||||
assertEquals("OK", response.get("status").getAsString());
|
||||
}
|
||||
|
|
@ -605,7 +605,7 @@ public class TestMultitenancyAPIHelper {
|
|||
map.put("userId", userId);
|
||||
JsonObject userResponse = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user"),
|
||||
map, 1000, 1000, null, SemVer.v3_0.get(),
|
||||
map, 1000, 2500, null, SemVer.v3_0.get(),
|
||||
"emailpassword");
|
||||
assertEquals("OK", userResponse.getAsJsonPrimitive("status").getAsString());
|
||||
return userResponse.getAsJsonObject("user");
|
||||
|
|
@ -620,7 +620,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/userid/map"), requestBody,
|
||||
1000, 1000, null,
|
||||
1000, 2500, null,
|
||||
SemVer.v3_0.get(), "useridmapping");
|
||||
assertEquals("OK", response.get("status").getAsString());
|
||||
}
|
||||
|
|
@ -631,7 +631,7 @@ public class TestMultitenancyAPIHelper {
|
|||
params.put("userId", userId);
|
||||
JsonObject response = HttpRequestForTesting.sendGETRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/user/id"),
|
||||
params, 1000, 1000, null,
|
||||
params, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "");
|
||||
return response;
|
||||
}
|
||||
|
|
@ -644,7 +644,7 @@ public class TestMultitenancyAPIHelper {
|
|||
requestBody.add("metadataUpdate", metadata);
|
||||
JsonObject resp = HttpRequestForTesting.sendJsonPUTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/metadata"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "usermetadata");
|
||||
return resp;
|
||||
}
|
||||
|
|
@ -655,7 +655,7 @@ public class TestMultitenancyAPIHelper {
|
|||
requestBody.addProperty("userId", userId);
|
||||
JsonObject resp = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/metadata/remove"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "usermetadata");
|
||||
|
||||
return resp;
|
||||
|
|
@ -667,7 +667,7 @@ public class TestMultitenancyAPIHelper {
|
|||
requestBody.addProperty("role", role);
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/role"),
|
||||
requestBody, 1000, 1000, null, WebserverAPI.getLatestCDIVersion().get(),
|
||||
requestBody, 1000, 2500, null, WebserverAPI.getLatestCDIVersion().get(),
|
||||
"userroles");
|
||||
assertEquals("OK", response.get("status").getAsString());
|
||||
}
|
||||
|
|
@ -679,7 +679,7 @@ public class TestMultitenancyAPIHelper {
|
|||
requestBody.addProperty("userId", userId);
|
||||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/role"), requestBody, 1000, 1000,
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/role"), requestBody, 1000, 2500,
|
||||
null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "userroles");
|
||||
|
||||
|
|
@ -704,7 +704,7 @@ public class TestMultitenancyAPIHelper {
|
|||
request.addProperty("role", role);
|
||||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/role/remove"), request, 1000, 1000,
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/role/remove"), request, 1000, 2500,
|
||||
null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "userroles");
|
||||
assertEquals(2, response.entrySet().size());
|
||||
|
|
@ -719,7 +719,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/email/verify/token"),
|
||||
requestBody, 1000, 1000, null,
|
||||
requestBody, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "emailverification");
|
||||
|
||||
assertEquals(response.entrySet().size(), 2);
|
||||
|
|
@ -731,7 +731,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
JsonObject response2 = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/email/verify"),
|
||||
verifyResponseBody, 1000, 1000, null,
|
||||
verifyResponseBody, 1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), "emailverification");
|
||||
|
||||
assertEquals(response2.entrySet().size(), 3);
|
||||
|
|
@ -746,7 +746,7 @@ public class TestMultitenancyAPIHelper {
|
|||
|
||||
HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/user/email/verify/remove"), body,
|
||||
1000, 1000, null,
|
||||
1000, 2500, null,
|
||||
WebserverAPI.getLatestCDIVersion().get(), RECIPE_ID.EMAIL_VERIFICATION.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import com.google.gson.JsonObject;
|
|||
import io.supertokens.Main;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
import io.supertokens.featureflag.exceptions.FeatureNotEnabledException;
|
||||
|
|
|
|||
|
|
@ -32,28 +32,28 @@ public class OAuthAPIHelper {
|
|||
|
||||
public static JsonObject createClient(Main main, JsonObject createClientBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/clients", createClientBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/clients", createClientBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static JsonObject updateClient(Main main, JsonObject updateClientBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/clients", updateClientBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/clients", updateClientBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static JsonObject auth(Main main, JsonObject authBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/auth", authBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/auth", authBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static JsonObject token(Main main, JsonObject tokenBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/token", tokenBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/token", tokenBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@ public class OAuthAPIHelper {
|
|||
}
|
||||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "",
|
||||
url, acceptLoginChallengeBody, 5000, 5000, null,
|
||||
url, acceptLoginChallengeBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
|
@ -95,28 +95,28 @@ public class OAuthAPIHelper {
|
|||
}
|
||||
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPUTRequest(main, "",
|
||||
url, acceptConsentChallengeBody, 5000, 5000, null,
|
||||
url, acceptConsentChallengeBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static JsonObject revoke(Main main, JsonObject revokeRequestBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/token/revoke", revokeRequestBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/token/revoke", revokeRequestBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static JsonObject introspect(Main main, JsonObject introspectRequestBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/introspect", introspectRequestBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/introspect", introspectRequestBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
||||
public static JsonObject revokeClientId(Main main, JsonObject revokeClientIdRequestBody) throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/tokens/revoke", revokeClientIdRequestBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/tokens/revoke", revokeClientIdRequestBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ public class OAuthAPIHelper {
|
|||
public static JsonObject revokeSessionHandle(Main main, JsonObject revokeSessionHandleRequestBody)
|
||||
throws Exception {
|
||||
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "",
|
||||
"http://localhost:3567/recipe/oauth/session/revoke", revokeSessionHandleRequestBody, 5000, 5000, null,
|
||||
"http://localhost:3567/recipe/oauth/session/revoke", revokeSessionHandleRequestBody, 1000, 15000, null,
|
||||
SemVer.v5_2.get(), "");
|
||||
return response;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package io.supertokens.test.passwordless;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.pluginInterface.STORAGE_TYPE;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateUserIdException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException;
|
||||
|
|
@ -381,7 +382,7 @@ public class PasswordlessStorageTest {
|
|||
try {
|
||||
storage.updateUserEmail_Transaction(process.getAppForTesting().toAppIdentifier(), con, userIdNotExists,
|
||||
email3);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
storage.commitTransaction(con);
|
||||
|
|
@ -425,7 +426,7 @@ public class PasswordlessStorageTest {
|
|||
try {
|
||||
storage.updateUserEmail_Transaction(
|
||||
process.getAppForTesting().toAppIdentifier(), con, userIdEmail1, email2);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
storage.commitTransaction(con);
|
||||
|
|
@ -447,7 +448,7 @@ public class PasswordlessStorageTest {
|
|||
storage.startTransaction(con -> {
|
||||
try {
|
||||
storage.updateUserEmail_Transaction(process.getAppForTesting().toAppIdentifier(), con, userIdEmail1, email2);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
storage.commitTransaction(con);
|
||||
|
|
@ -517,7 +518,7 @@ public class PasswordlessStorageTest {
|
|||
storage.startTransaction(con -> {
|
||||
try {
|
||||
storage.updateUserEmail_Transaction(process.getAppForTesting().toAppIdentifier(), con, userIdPhone1, email);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
storage.commitTransaction(con);
|
||||
|
|
@ -568,7 +569,7 @@ public class PasswordlessStorageTest {
|
|||
storage.startTransaction(con -> {
|
||||
try {
|
||||
storage.updateUserEmail_Transaction(process.getAppForTesting().toAppIdentifier(), con, userId, email2);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
storage.commitTransaction(con);
|
||||
|
|
@ -579,7 +580,7 @@ public class PasswordlessStorageTest {
|
|||
storage.startTransaction(con -> {
|
||||
try {
|
||||
storage.updateUserEmail_Transaction(process.getAppForTesting().toAppIdentifier(), con, userId, null);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
try {
|
||||
|
|
@ -606,7 +607,7 @@ public class PasswordlessStorageTest {
|
|||
storage.startTransaction(con -> {
|
||||
try {
|
||||
storage.updateUserEmail_Transaction(process.getAppForTesting().toAppIdentifier(), con, userId, email);
|
||||
} catch (UnknownUserIdException | DuplicateEmailException e) {
|
||||
} catch (UnknownUserIdException | DuplicateEmailException | EmailChangeNotAllowedException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import io.supertokens.passwordless.Passwordless;
|
|||
import io.supertokens.passwordless.exceptions.UserWithoutContactInfoException;
|
||||
import io.supertokens.pluginInterface.STORAGE_TYPE;
|
||||
import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException;
|
||||
import io.supertokens.pluginInterface.multitenancy.AppIdentifier;
|
||||
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailverification.EmailVerification;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
|
|
@ -37,7 +36,6 @@ import io.supertokens.storageLayer.StorageLayer;
|
|||
import io.supertokens.test.TestingProcessManager;
|
||||
import io.supertokens.test.Utils;
|
||||
import io.supertokens.test.httpRequest.HttpRequestForTesting;
|
||||
import io.supertokens.thirdparty.ThirdParty;
|
||||
import io.supertokens.utils.SemVer;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import io.supertokens.Main;
|
|||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.emailpassword.EmailPassword;
|
||||
import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.EmailChangeNotAllowedException;
|
||||
import io.supertokens.emailverification.EmailVerification;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
|
|
|
|||
|
|
@ -193,134 +193,110 @@ public class UserMetadataTest {
|
|||
return;
|
||||
}
|
||||
|
||||
String userId = "userId";
|
||||
// Repeat concurrent test 100 times
|
||||
for (int idx = 0; idx < 100; idx++) {
|
||||
String userId = "userId" + idx;
|
||||
|
||||
JsonObject expected = new JsonObject();
|
||||
JsonObject update1 = new JsonObject();
|
||||
update1.addProperty("a", 1);
|
||||
expected.addProperty("a", 1);
|
||||
JsonObject expected = new JsonObject();
|
||||
JsonObject update1 = new JsonObject();
|
||||
update1.addProperty("a", 1);
|
||||
expected.addProperty("a", 1);
|
||||
|
||||
JsonObject update2 = new JsonObject();
|
||||
update2.addProperty("b", 2);
|
||||
expected.addProperty("b", 2);
|
||||
JsonObject update2 = new JsonObject();
|
||||
update2.addProperty("b", 2);
|
||||
expected.addProperty("b", 2);
|
||||
|
||||
UserMetadataSQLStorage sqlStorage = (UserMetadataSQLStorage) StorageLayer.getStorage(process.getProcess());
|
||||
UserMetadataSQLStorage sqlStorage = (UserMetadataSQLStorage) StorageLayer.getStorage(process.getProcess());
|
||||
|
||||
AtomicReference<String> t1State = new AtomicReference<>("init");
|
||||
AtomicReference<String> t2State = new AtomicReference<>("init");
|
||||
final Object syncObject = new Object();
|
||||
AtomicReference<String> t1State = new AtomicReference<>("init");
|
||||
AtomicReference<String> t2State = new AtomicReference<>("init");
|
||||
final Object syncObject = new Object();
|
||||
|
||||
AtomicInteger tryCount1 = new AtomicInteger(0);
|
||||
AtomicInteger tryCount2 = new AtomicInteger(0);
|
||||
AtomicBoolean success1 = new AtomicBoolean(false);
|
||||
AtomicBoolean success2 = new AtomicBoolean(false);
|
||||
AtomicInteger tryCount1 = new AtomicInteger(0);
|
||||
AtomicInteger tryCount2 = new AtomicInteger(0);
|
||||
AtomicBoolean success1 = new AtomicBoolean(false);
|
||||
AtomicBoolean success2 = new AtomicBoolean(false);
|
||||
|
||||
AppIdentifier appIdentifier = process.getAppForTesting().toAppIdentifier();
|
||||
AppIdentifier appIdentifier = process.getAppForTesting().toAppIdentifier();
|
||||
|
||||
Runnable r1 = () -> {
|
||||
try {
|
||||
sqlStorage.startTransaction(con -> {
|
||||
tryCount1.incrementAndGet();
|
||||
JsonObject originalMetadata = sqlStorage.getUserMetadata_Transaction(appIdentifier, con, userId);
|
||||
Runnable r1 = () -> {
|
||||
try {
|
||||
sqlStorage.startTransaction(con -> {
|
||||
tryCount1.incrementAndGet();
|
||||
|
||||
synchronized (syncObject) {
|
||||
t1State.set("read");
|
||||
syncObject.notifyAll();
|
||||
}
|
||||
JsonObject originalMetadata = sqlStorage.getUserMetadata_Transaction(appIdentifier, con, userId);
|
||||
|
||||
synchronized (syncObject) {
|
||||
while (!t2State.get().equals("read")) {
|
||||
try {
|
||||
syncObject.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
JsonObject updatedMetadata = originalMetadata == null ? new JsonObject() : originalMetadata;
|
||||
MetadataUtils.shallowMergeMetadataUpdate(updatedMetadata, update1);
|
||||
|
||||
try {
|
||||
sqlStorage.setUserMetadata_Transaction(appIdentifier, con, userId,
|
||||
updatedMetadata);
|
||||
} catch (TenantOrAppNotFoundException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
sqlStorage.commitTransaction(con);
|
||||
success1.set(true); // it should come here because we will try three times.
|
||||
return null;
|
||||
});
|
||||
} catch (StorageTransactionLogicException e) {
|
||||
if (e.actualException instanceof TenantOrAppNotFoundException) {
|
||||
throw new IllegalStateException(e.actualException);
|
||||
}
|
||||
|
||||
JsonObject updatedMetadata = originalMetadata == null ? new JsonObject() : originalMetadata;
|
||||
MetadataUtils.shallowMergeMetadataUpdate(updatedMetadata, update1);
|
||||
|
||||
try {
|
||||
sqlStorage.setUserMetadata_Transaction(appIdentifier, con, userId,
|
||||
updatedMetadata);
|
||||
} catch (TenantOrAppNotFoundException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
sqlStorage.commitTransaction(con);
|
||||
success1.set(true); // it should come here because we will try three times.
|
||||
return null;
|
||||
});
|
||||
} catch (StorageTransactionLogicException e) {
|
||||
if (e.actualException instanceof TenantOrAppNotFoundException) {
|
||||
throw new IllegalStateException(e.actualException);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Runnable r2 = () -> {
|
||||
try {
|
||||
sqlStorage.startTransaction(con -> {
|
||||
tryCount2.incrementAndGet();
|
||||
Runnable r2 = () -> {
|
||||
try {
|
||||
sqlStorage.startTransaction(con -> {
|
||||
tryCount2.incrementAndGet();
|
||||
|
||||
JsonObject originalMetadata = sqlStorage.getUserMetadata_Transaction(appIdentifier, con, userId);
|
||||
JsonObject originalMetadata = sqlStorage.getUserMetadata_Transaction(appIdentifier, con, userId);
|
||||
|
||||
synchronized (syncObject) {
|
||||
t2State.set("read");
|
||||
syncObject.notifyAll();
|
||||
}
|
||||
JsonObject updatedMetadata = originalMetadata == null ? new JsonObject() : originalMetadata;
|
||||
MetadataUtils.shallowMergeMetadataUpdate(updatedMetadata, update2);
|
||||
|
||||
synchronized (syncObject) {
|
||||
while (!t1State.get().equals("read")) {
|
||||
try {
|
||||
syncObject.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
try {
|
||||
sqlStorage.setUserMetadata_Transaction(appIdentifier, con, userId,
|
||||
updatedMetadata);
|
||||
} catch (TenantOrAppNotFoundException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
|
||||
sqlStorage.commitTransaction(con);
|
||||
success2.set(true); // it should come here because we will try three times.
|
||||
return null;
|
||||
});
|
||||
} catch (StorageTransactionLogicException e) {
|
||||
if (e.actualException instanceof TenantOrAppNotFoundException) {
|
||||
throw new IllegalStateException(e.actualException);
|
||||
}
|
||||
|
||||
JsonObject updatedMetadata = originalMetadata == null ? new JsonObject() : originalMetadata;
|
||||
MetadataUtils.shallowMergeMetadataUpdate(updatedMetadata, update2);
|
||||
|
||||
try {
|
||||
sqlStorage.setUserMetadata_Transaction(appIdentifier, con, userId,
|
||||
updatedMetadata);
|
||||
} catch (TenantOrAppNotFoundException e) {
|
||||
throw new StorageTransactionLogicException(e);
|
||||
}
|
||||
|
||||
sqlStorage.commitTransaction(con);
|
||||
success2.set(true); // it should come here because we will try three times.
|
||||
return null;
|
||||
});
|
||||
} catch (StorageTransactionLogicException e) {
|
||||
if (e.actualException instanceof TenantOrAppNotFoundException) {
|
||||
throw new IllegalStateException(e.actualException);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
};
|
||||
Thread t1 = new Thread(r1);
|
||||
Thread t2 = new Thread(r2);
|
||||
};
|
||||
Thread t1 = new Thread(r1);
|
||||
Thread t2 = new Thread(r2);
|
||||
|
||||
t1.start();
|
||||
t2.start();
|
||||
t1.start();
|
||||
t2.start();
|
||||
|
||||
t1.join(5000);
|
||||
t2.join(5000);
|
||||
t1.join(5000);
|
||||
t2.join(5000);
|
||||
|
||||
// The empty row did not lock, so we check if the system found a deadlock and that we could resolve it.
|
||||
// The empty row did not lock, so we check if the system found a deadlock and that we could resolve it.
|
||||
|
||||
// Both succeeds in the end
|
||||
assertTrue(success1.get());
|
||||
assertTrue(success2.get());
|
||||
// Both succeeds in the end
|
||||
assertTrue(success1.get());
|
||||
assertTrue(success2.get());
|
||||
|
||||
// One of them had to be retried (not deterministic which)
|
||||
assertEquals(3, tryCount1.get() + tryCount2.get());
|
||||
// assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.DEADLOCK_FOUND));
|
||||
// One of them had to be retried (not deterministic which)
|
||||
assertTrue(3 >= tryCount1.get() + tryCount2.get());
|
||||
// assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.DEADLOCK_FOUND));
|
||||
|
||||
// The end result is as expected
|
||||
assertEquals(expected, sqlStorage.getUserMetadata(appIdentifier, userId));
|
||||
// The end result is as expected
|
||||
assertEquals(expected, sqlStorage.getUserMetadata(appIdentifier, userId));
|
||||
}
|
||||
|
||||
process.kill();
|
||||
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import com.webauthn4j.test.client.ClientPlatform;
|
|||
import com.webauthn4j.util.Base64UrlUtil;
|
||||
import io.supertokens.Main;
|
||||
import io.supertokens.authRecipe.AuthRecipe;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.RecipeUserIdAlreadyLinkedWithPrimaryUserIdException;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package io.supertokens.test.webauthn;
|
|||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.supertokens.ProcessState;
|
||||
import io.supertokens.authRecipe.exception.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.pluginInterface.authRecipe.exceptions.AccountInfoAlreadyAssociatedWithAnotherPrimaryUserIdException;
|
||||
import io.supertokens.authRecipe.exception.InputUserIdIsNotAPrimaryUserException;
|
||||
import io.supertokens.featureflag.EE_FEATURES;
|
||||
import io.supertokens.featureflag.FeatureFlagTestContent;
|
||||
|
|
|
|||
Loading…
Reference in New Issue