From da838315991adeb3d3384f4a1ab7edebbff4ba8d Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Thu, 14 Sep 2023 17:30:39 +0530 Subject: [PATCH 1/2] fix: tests --- .../io/supertokens/authRecipe/AuthRecipe.java | 34 ++++--- .../java/io/supertokens/inmemorydb/Start.java | 85 +++++++++++----- .../queries/ActiveUsersQueries.java | 22 +++-- .../inmemorydb/queries/DashboardQueries.java | 7 +- .../queries/EmailPasswordQueries.java | 8 +- .../queries/EmailVerificationQueries.java | 6 +- .../inmemorydb/queries/GeneralQueries.java | 30 ++++-- .../queries/MultitenancyQueries.java | 2 +- .../queries/PasswordlessQueries.java | 97 +++++++++---------- .../inmemorydb/queries/SessionQueries.java | 10 +- .../inmemorydb/queries/ThirdPartyQueries.java | 54 ++++++----- .../queries/UserIdMappingQueries.java | 54 ++++++++++- .../queries/UserMetadataQueries.java | 9 +- ...RoleQueries.java => UserRolesQueries.java} | 62 ++++++------ .../useridmapping/UserIdMapping.java | 34 ++++++- .../test/AuthRecipesParallelTest.java | 5 + .../accountlinking/CreatePrimaryUserTest.java | 5 + .../test/accountlinking/LinkAccountsTest.java | 4 + .../api/CreatePrimaryUserAPITest.java | 4 + .../api/LinkAccountsAPITest.java | 4 + .../DeleteUserAPIWithUserIdMappingTest.java | 2 +- .../api/TestMultitenancyAPIHelper.java | 4 +- 22 files changed, 359 insertions(+), 183 deletions(-) rename src/main/java/io/supertokens/inmemorydb/queries/{UserRoleQueries.java => UserRolesQueries.java} (88%) diff --git a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java index 5633ebf1d..8596a28d8 100644 --- a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java +++ b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java @@ -73,7 +73,7 @@ public static boolean unlinkAccounts(Main main, AppIdentifierWithStorage appIden throws StorageQueryException, UnknownUserIdException, InputUserIdIsNotAPrimaryUserException { AuthRecipeSQLStorage storage = (AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage(); try { - return storage.startTransaction(con -> { + UnlinkResult res = storage.startTransaction(con -> { AuthRecipeUserInfo primaryUser = storage.getPrimaryUserById_Transaction(appIdentifierWithStorage, con, recipeUserId); if (primaryUser == null) { @@ -93,28 +93,23 @@ public static boolean unlinkAccounts(Main main, AppIdentifierWithStorage appIden // we are trying to unlink the user ID which is the same as the primary one. if (primaryUser.loginMethods.length == 1) { storage.unlinkAccounts_Transaction(appIdentifierWithStorage, con, primaryUser.getSupertokensUserId(), recipeUserId); - Session.revokeAllSessionsForUser(main, appIdentifierWithStorage, - mappingResult == null ? recipeUserId : mappingResult.externalUserId, - false); - return false; + return new UnlinkResult(mappingResult == null ? recipeUserId : mappingResult.externalUserId, false); } else { // Here we delete the recipe user id cause if we just unlink, then there will be two // distinct users with the same ID - which is a broken state. // The delete will also cause the automatic unlinking. // We need to make sure that it only deletes sessions for recipeUserId and not other linked // users who have their sessions for primaryUserId (that is equal to the recipeUserId) - Session.revokeAllSessionsForUser(main, appIdentifierWithStorage, - mappingResult == null ? recipeUserId : mappingResult.externalUserId, false); deleteUserHelper(con, appIdentifierWithStorage, recipeUserId, false, mappingResult); - return true; + return new UnlinkResult(mappingResult == null ? recipeUserId : mappingResult.externalUserId, true); } } else { storage.unlinkAccounts_Transaction(appIdentifierWithStorage, con, primaryUser.getSupertokensUserId(), recipeUserId); - Session.revokeAllSessionsForUser(main, appIdentifierWithStorage, - mappingResult == null ? recipeUserId : mappingResult.externalUserId, false); - return false; + return new UnlinkResult(mappingResult == null ? recipeUserId : mappingResult.externalUserId, false); } }); + Session.revokeAllSessionsForUser(main, appIdentifierWithStorage, res.userId, false); + return res.wasLinked; } catch (StorageTransactionLogicException e) { if (e.actualException instanceof UnknownUserIdException) { throw (UnknownUserIdException) e.actualException; @@ -788,8 +783,8 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit // in reference to // https://docs.google.com/spreadsheets/d/17hYV32B0aDCeLnSxbZhfRN2Y9b0LC2xUF44vV88RNAA/edit?usp=sharing // we want to check which state the db is in - if (appIdentifierWithStorage.getAuthRecipeStorage() - .doesUserIdExist(appIdentifierWithStorage, userIdMapping.externalUserId)) { + if (((AuthRecipeSQLStorage) appIdentifierWithStorage.getAuthRecipeStorage()) + .doesUserIdExist_Transaction(con, appIdentifierWithStorage, userIdMapping.externalUserId)) { // db is in state A4 // delete only from auth tables userIdToDeleteForAuthRecipe = userId; @@ -823,11 +818,13 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit if (primaryUserIdToDeleteNonAuthRecipe == null) { deleteAuthRecipeUser(con, appIdentifierWithStorage, userToDelete.getSupertokensUserId(), true); + return; } } else { // this is always type supertokens user ID cause it's from a user from the database. io.supertokens.pluginInterface.useridmapping.UserIdMapping mappingResult = io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + con, appIdentifierWithStorage, userToDelete.getSupertokensUserId(), UserIdType.SUPERTOKENS); if (mappingResult != null) { @@ -866,6 +863,7 @@ private static void deleteUserHelper(TransactionConnection con, AppIdentifierWit io.supertokens.pluginInterface.useridmapping.UserIdMapping mappingResult = lM.getSupertokensUserId().equals( userIdToDeleteForAuthRecipe) ? userIdMapping : io.supertokens.useridmapping.UserIdMapping.getUserIdMapping( + con, appIdentifierWithStorage, lM.getSupertokensUserId(), UserIdType.SUPERTOKENS); deleteUserHelper(con, appIdentifierWithStorage, lM.getSupertokensUserId(), false, mappingResult); @@ -963,4 +961,14 @@ public static boolean deleteNonAuthRecipeUser(TenantIdentifierWithStorage return finalDidExist; } + + private static class UnlinkResult { + public final String userId; + public final boolean wasLinked; + + public UnlinkResult(String userId, boolean wasLinked) { + this.userId = userId; + this.wasLinked = wasLinked; + } + } } diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index c60ac5b57..f05d07f8a 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -49,10 +49,7 @@ import io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo; import io.supertokens.pluginInterface.jwt.exceptions.DuplicateKeyIdException; import io.supertokens.pluginInterface.jwt.sqlstorage.JWTRecipeSQLStorage; -import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.MultitenancyStorage; -import io.supertokens.pluginInterface.multitenancy.TenantConfig; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; +import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateClientTypeException; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateTenantException; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateThirdPartyIdException; @@ -80,6 +77,7 @@ import io.supertokens.pluginInterface.useridmapping.UserIdMappingStorage; import io.supertokens.pluginInterface.useridmapping.exception.UnknownSuperTokensUserIdException; import io.supertokens.pluginInterface.useridmapping.exception.UserIdMappingAlreadyExistsException; +import io.supertokens.pluginInterface.useridmapping.sqlStorage.UserIdMappingSQLStorage; import io.supertokens.pluginInterface.usermetadata.UserMetadataStorage; import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage; import io.supertokens.pluginInterface.userroles.UserRolesStorage; @@ -103,7 +101,8 @@ public class Start implements SessionSQLStorage, EmailPasswordSQLStorage, EmailVerificationSQLStorage, ThirdPartySQLStorage, JWTRecipeSQLStorage, PasswordlessSQLStorage, UserMetadataSQLStorage, UserRolesSQLStorage, UserIdMappingStorage, - MultitenancyStorage, MultitenancySQLStorage, TOTPSQLStorage, ActiveUsersStorage, DashboardSQLStorage, AuthRecipeSQLStorage { + UserIdMappingSQLStorage, MultitenancyStorage, MultitenancySQLStorage, TOTPSQLStorage, ActiveUsersStorage, + DashboardSQLStorage, AuthRecipeSQLStorage { private static final Object appenderLock = new Object(); private static final String APP_ID_KEY_NAME = "app_id"; @@ -1183,6 +1182,16 @@ public boolean doesUserIdExist(AppIdentifier appIdentifier, String userId) throw } } + @Override + public boolean doesUserIdExist_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) throws StorageQueryException { + try { + Connection sqlCon = (Connection) con.getConnection(); + return GeneralQueries.doesUserIdExist_Transaction(this, sqlCon, appIdentifier, userId); + } catch (SQLException e) { + throw new StorageQueryException(e); + } + } + @Override public void updateLastActive(AppIdentifier appIdentifier, String userId) throws StorageQueryException { try { @@ -1850,7 +1859,7 @@ public void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, Stri throws StorageQueryException, UnknownRoleException, DuplicateUserRoleMappingException, TenantOrAppNotFoundException { try { - UserRoleQueries.addRoleToUser(this, tenantIdentifier, userId, role); + UserRolesQueries.addRoleToUser(this, tenantIdentifier, userId, role); } catch (SQLException e) { if (e instanceof SQLiteException) { SQLiteConfig config = Config.getConfig(this); @@ -1884,7 +1893,7 @@ public void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, Stri public String[] getRolesForUser(TenantIdentifier tenantIdentifier, String userId) throws StorageQueryException { try { - return UserRoleQueries.getRolesForUser(this, tenantIdentifier, userId); + return UserRolesQueries.getRolesForUser(this, tenantIdentifier, userId); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1893,7 +1902,7 @@ public String[] getRolesForUser(TenantIdentifier tenantIdentifier, String userId private String[] getRolesForUser(AppIdentifier appIdentifier, String userId) throws StorageQueryException { try { - return UserRoleQueries.getRolesForUser(this, appIdentifier, userId); + return UserRolesQueries.getRolesForUser(this, appIdentifier, userId); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1903,7 +1912,7 @@ private String[] getRolesForUser(AppIdentifier appIdentifier, String userId) thr public String[] getUsersForRole(TenantIdentifier tenantIdentifier, String role) throws StorageQueryException { try { - return UserRoleQueries.getUsersForRole(this, tenantIdentifier, role); + return UserRolesQueries.getUsersForRole(this, tenantIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1913,7 +1922,7 @@ public String[] getUsersForRole(TenantIdentifier tenantIdentifier, String role) public String[] getPermissionsForRole(AppIdentifier appIdentifier, String role) throws StorageQueryException { try { - return UserRoleQueries.getPermissionsForRole(this, appIdentifier, role); + return UserRolesQueries.getPermissionsForRole(this, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1923,7 +1932,7 @@ public String[] getPermissionsForRole(AppIdentifier appIdentifier, String role) public String[] getRolesThatHavePermission(AppIdentifier appIdentifier, String permission) throws StorageQueryException { try { - return UserRoleQueries.getRolesThatHavePermission(this, appIdentifier, permission); + return UserRolesQueries.getRolesThatHavePermission(this, appIdentifier, permission); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1932,7 +1941,7 @@ public String[] getRolesThatHavePermission(AppIdentifier appIdentifier, String p @Override public boolean deleteRole(AppIdentifier appIdentifier, String role) throws StorageQueryException { try { - return UserRoleQueries.deleteRole(this, appIdentifier, role); + return UserRolesQueries.deleteRole(this, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1941,7 +1950,7 @@ public boolean deleteRole(AppIdentifier appIdentifier, String role) throws Stora @Override public String[] getRoles(AppIdentifier appIdentifier) throws StorageQueryException { try { - return UserRoleQueries.getRoles(this, appIdentifier); + return UserRolesQueries.getRoles(this, appIdentifier); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1950,7 +1959,7 @@ public String[] getRoles(AppIdentifier appIdentifier) throws StorageQueryExcepti @Override public boolean doesRoleExist(AppIdentifier appIdentifier, String role) throws StorageQueryException { try { - return UserRoleQueries.doesRoleExist(this, appIdentifier, role); + return UserRolesQueries.doesRoleExist(this, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1960,7 +1969,7 @@ public boolean doesRoleExist(AppIdentifier appIdentifier, String role) throws St public int deleteAllRolesForUser(TenantIdentifier tenantIdentifier, String userId) throws StorageQueryException { try { - return UserRoleQueries.deleteAllRolesForUser(this, tenantIdentifier, userId); + return UserRolesQueries.deleteAllRolesForUser(this, tenantIdentifier, userId); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -1972,7 +1981,7 @@ public boolean deleteRoleForUser_Transaction(TenantIdentifier tenantIdentifier, throws StorageQueryException { Connection sqlCon = (Connection) con.getConnection(); try { - return UserRoleQueries.deleteRoleForUser_Transaction(this, sqlCon, tenantIdentifier, userId, + return UserRolesQueries.deleteRoleForUser_Transaction(this, sqlCon, tenantIdentifier, userId, role); } catch (SQLException e) { throw new StorageQueryException(e); @@ -1985,7 +1994,7 @@ public boolean createNewRoleOrDoNothingIfExists_Transaction(AppIdentifier appIde throws StorageQueryException, TenantOrAppNotFoundException { Connection sqlCon = (Connection) con.getConnection(); try { - return UserRoleQueries.createNewRoleOrDoNothingIfExists_Transaction( + return UserRolesQueries.createNewRoleOrDoNothingIfExists_Transaction( this, sqlCon, appIdentifier, role); } catch (SQLException e) { if (e instanceof SQLiteException) { @@ -2011,7 +2020,7 @@ public void addPermissionToRoleOrDoNothingIfExists_Transaction(AppIdentifier app throws StorageQueryException, UnknownRoleException { Connection sqlCon = (Connection) con.getConnection(); try { - UserRoleQueries.addPermissionToRoleOrDoNothingIfExists_Transaction(this, sqlCon, appIdentifier, + UserRolesQueries.addPermissionToRoleOrDoNothingIfExists_Transaction(this, sqlCon, appIdentifier, role, permission); } catch (SQLException e) { if (e instanceof SQLiteException) { @@ -2035,7 +2044,7 @@ public boolean deletePermissionForRole_Transaction(AppIdentifier appIdentifier, throws StorageQueryException { Connection sqlCon = (Connection) con.getConnection(); try { - return UserRoleQueries.deletePermissionForRole_Transaction(this, sqlCon, appIdentifier, role, + return UserRolesQueries.deletePermissionForRole_Transaction(this, sqlCon, appIdentifier, role, permission); } catch (SQLException e) { throw new StorageQueryException(e); @@ -2048,7 +2057,7 @@ public int deleteAllPermissionsForRole_Transaction(AppIdentifier appIdentifier, throws StorageQueryException { Connection sqlCon = (Connection) con.getConnection(); try { - return UserRoleQueries.deleteAllPermissionsForRole_Transaction(this, sqlCon, appIdentifier, + return UserRolesQueries.deleteAllPermissionsForRole_Transaction(this, sqlCon, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); @@ -2060,7 +2069,7 @@ public boolean doesRoleExist_Transaction(AppIdentifier appIdentifier, Transactio throws StorageQueryException { Connection sqlCon = (Connection) con.getConnection(); try { - return UserRoleQueries.doesRoleExist_transaction(this, sqlCon, appIdentifier, role); + return UserRolesQueries.doesRoleExist_transaction(this, sqlCon, appIdentifier, role); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -2071,7 +2080,7 @@ public void deleteAllRolesForUser_Transaction(TransactionConnection con, AppIden throws StorageQueryException { try { Connection sqlCon = (Connection) con.getConnection(); - UserRoleQueries.deleteAllRolesForUser_Transaction(sqlCon, this, appIdentifier, userId); + UserRolesQueries.deleteAllRolesForUser_Transaction(sqlCon, this, appIdentifier, userId); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -2906,4 +2915,36 @@ public int getUsersCountWithMoreThanOneLoginMethod(AppIdentifier appIdentifier) throw new StorageQueryException(e); } } + + + @Override + public UserIdMapping getUserIdMapping_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, boolean isSuperTokensUserId) + throws StorageQueryException { + try { + Connection sqlCon = (Connection) con.getConnection(); + if (isSuperTokensUserId) { + return UserIdMappingQueries.getuseraIdMappingWithSuperTokensUserId_Transaction(this, sqlCon, appIdentifier, + userId); + } + + return UserIdMappingQueries.getUserIdMappingWithExternalUserId_Transaction(this, sqlCon, appIdentifier, userId); + } catch (SQLException e) { + throw new StorageQueryException(e); + } + } + + @Override + public UserIdMapping[] getUserIdMapping_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) + throws StorageQueryException { + try { + Connection sqlCon = (Connection) con.getConnection(); + return UserIdMappingQueries.getUserIdMappingWithEitherSuperTokensUserIdOrExternalUserId_Transaction(this, + sqlCon, + appIdentifier, + userId); + } catch (SQLException e) { + throw new StorageQueryException(e); + } + } + } diff --git a/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java index 819b991eb..48aacda21 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java @@ -23,7 +23,8 @@ static String getQueryToCreateUserLastActiveTable(Start start) { + " );"; } - public static int countUsersActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) throws SQLException, StorageQueryException { + public static int countUsersActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) + throws SQLException, StorageQueryException { String QUERY = "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getUserLastActiveTable() + " WHERE app_id = ? AND last_active_time >= ?"; @@ -60,7 +61,8 @@ public static int countUsersActiveSinceAndHasMoreThanOneLoginMethod(Start start, }); } - public static int countUsersEnabledTotp(Start start, AppIdentifier appIdentifier) throws SQLException, StorageQueryException { + public static int countUsersEnabledTotp(Start start, AppIdentifier appIdentifier) + throws SQLException, StorageQueryException { String QUERY = "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable() + " WHERE app_id = ?"; @@ -74,8 +76,10 @@ public static int countUsersEnabledTotp(Start start, AppIdentifier appIdentifier }); } - public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) throws SQLException, StorageQueryException { - String QUERY = "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable() + " AS totp_users " + public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) + throws SQLException, StorageQueryException { + String QUERY = + "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable() + " AS totp_users " + "INNER JOIN " + Config.getConfig(start).getUserLastActiveTable() + " AS user_last_active " + "ON totp_users.user_id = user_last_active.user_id " + "WHERE user_last_active.app_id = ? AND user_last_active.last_active_time >= ?"; @@ -91,9 +95,12 @@ public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier }); } - public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getUserLastActiveTable() - + "(app_id, user_id, last_active_time) VALUES(?, ?, ?) ON CONFLICT(app_id, user_id) DO UPDATE SET last_active_time = ?"; + + + "(app_id, user_id, last_active_time) VALUES(?, ?, ?) ON CONFLICT(app_id, user_id) DO UPDATE SET " + + "last_active_time = ?"; long now = System.currentTimeMillis(); return update(start, QUERY, pst -> { @@ -124,7 +131,8 @@ public static Long getLastActiveByUserId(Start start, AppIdentifier appIdentifie } } - public static void deleteUserActive_Transaction(Connection con, Start start, AppIdentifier appIdentifier, String userId) + public static void deleteUserActive_Transaction(Connection con, Start start, AppIdentifier appIdentifier, + String userId) throws StorageQueryException, SQLException { String QUERY = "DELETE FROM " + Config.getConfig(start).getUserLastActiveTable() + " WHERE app_id = ? AND user_id = ?"; diff --git a/src/main/java/io/supertokens/inmemorydb/queries/DashboardQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/DashboardQueries.java index 587bfd610..425768e39 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/DashboardQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/DashboardQueries.java @@ -37,9 +37,9 @@ public class DashboardQueries { public static String getQueryToCreateDashboardUsersTable(Start start) { - String tableName = Config.getConfig(start).getDashboardUsersTable(); + String dashboardUsersTable = Config.getConfig(start).getDashboardUsersTable(); // @formatter:off - return "CREATE TABLE IF NOT EXISTS " + tableName + " (" + return "CREATE TABLE IF NOT EXISTS " + dashboardUsersTable + " (" + "app_id VARCHAR(64) DEFAULT 'public'," + "user_id CHAR(36) NOT NULL," + "email VARCHAR(256) NOT NULL," @@ -287,5 +287,4 @@ public DashboardSessionInfo[] extract(ResultSet result) throws SQLException, Sto return temp.toArray(DashboardSessionInfo[]::new); } } - -} \ No newline at end of file +} diff --git a/src/main/java/io/supertokens/inmemorydb/queries/EmailPasswordQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/EmailPasswordQueries.java index ceba78bf5..fb27d870f 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/EmailPasswordQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/EmailPasswordQueries.java @@ -80,6 +80,7 @@ static String getQueryToCreatePasswordResetTokensTable(Start start) { + "app_id VARCHAR(64) DEFAULT 'public'," + "user_id CHAR(36) NOT NULL," + "token VARCHAR(128) NOT NULL UNIQUE," + + "email VARCHAR(256)," // nullable cause of backwards compatibility. + "token_expiry BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, user_id, token)," + "FOREIGN KEY (app_id, user_id) REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() @@ -181,8 +182,9 @@ public static PasswordResetTokenInfo[] getAllPasswordResetTokenInfoForUser_Trans appIdentifier.getAppId() + "~" + userId + Config.getConfig(start).getPasswordResetTokensTable()); - String QUERY = "SELECT user_id, token, token_expiry FROM " + getConfig(start).getPasswordResetTokensTable() - + " WHERE app_id = ? AND user_id = ?"; + String QUERY = + "SELECT user_id, token, token_expiry, email FROM " + getConfig(start).getPasswordResetTokensTable() + + " WHERE app_id = ? AND user_id = ?"; return execute(con, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -526,7 +528,7 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC { // emailpassword_user_to_tenant String QUERY = "INSERT INTO " + getConfig(start).getEmailPasswordUserToTenantTable() + "(app_id, tenant_id, user_id, email)" - + " VALUES(?, ?, ?, ?) " + " ON CONFLICT DO NOTHING"; + + " VALUES(?, ?, ?, ?) " + " ON CONFLICT (app_id, tenant_id, user_id) DO NOTHING"; int numRows = update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); diff --git a/src/main/java/io/supertokens/inmemorydb/queries/EmailVerificationQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/EmailVerificationQueries.java index 3cfc1274e..c571427ba 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/EmailVerificationQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/EmailVerificationQueries.java @@ -239,6 +239,9 @@ public UserIdAndEmail(String userId, String email) { public static List isEmailVerified_transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, List userIdAndEmail) throws SQLException, StorageQueryException { + if (userIdAndEmail.isEmpty()) { + return new ArrayList<>(); + } List emails = new ArrayList<>(); List userIds = new ArrayList<>(); Map userIdToEmailMap = new HashMap<>(); @@ -323,7 +326,8 @@ public static List isEmailVerified(Start start, AppIdentifier appIdentif }); } - public static void deleteUserInfo_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, String userId) + public static void deleteUserInfo_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, + String userId) throws StorageQueryException, SQLException { { String QUERY = "DELETE FROM " + getConfig(start).getEmailVerificationTable() diff --git a/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java index 8989563bb..96ccc6773 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java @@ -75,6 +75,7 @@ static String getQueryToCreateUsersTable(Start start) { + "user_id CHAR(36) NOT NULL," + "primary_or_recipe_user_id CHAR(36) NOT NULL," + "is_linked_or_is_a_primary_user BOOLEAN NOT NULL DEFAULT FALSE," + + "primary_or_recipe_user_time_joined BIGINT UNSIGNED NOT NULL," + "recipe_id VARCHAR(128) NOT NULL," + "time_joined BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, tenant_id, user_id)," @@ -353,22 +354,22 @@ public static void createTablesIfNotExists(Start start, Main main) throws SQLExc if (!doesTableExists(start, Config.getConfig(start).getRolesTable())) { getInstance(main).addState(CREATING_NEW_TABLE, null); - update(start, UserRoleQueries.getQueryToCreateRolesTable(start), NO_OP_SETTER); + update(start, UserRolesQueries.getQueryToCreateRolesTable(start), NO_OP_SETTER); } if (!doesTableExists(start, Config.getConfig(start).getUserRolesPermissionsTable())) { getInstance(main).addState(CREATING_NEW_TABLE, null); - update(start, UserRoleQueries.getQueryToCreateRolePermissionsTable(start), NO_OP_SETTER); + update(start, UserRolesQueries.getQueryToCreateRolePermissionsTable(start), NO_OP_SETTER); // index - update(start, UserRoleQueries.getQueryToCreateRolePermissionsPermissionIndex(start), NO_OP_SETTER); + update(start, UserRolesQueries.getQueryToCreateRolePermissionsPermissionIndex(start), NO_OP_SETTER); } if (!doesTableExists(start, Config.getConfig(start).getUserRolesTable())) { getInstance(main).addState(CREATING_NEW_TABLE, null); - update(start, UserRoleQueries.getQueryToCreateUserRolesTable(start), NO_OP_SETTER); + update(start, UserRolesQueries.getQueryToCreateUserRolesTable(start), NO_OP_SETTER); // index - update(start, UserRoleQueries.getQueryToCreateUserRolesRoleIndex(start), NO_OP_SETTER); + update(start, UserRolesQueries.getQueryToCreateUserRolesRoleIndex(start), NO_OP_SETTER); } if (!doesTableExists(start, Config.getConfig(start).getUserIdMappingTable())) { @@ -1255,10 +1256,12 @@ private static List getPrimaryUserInfoForUserIds(Start start for (AllAuthRecipeUsersResultHolder authRecipeUsersResultHolder : allAuthUsersResult) { String recipeUserId = authRecipeUsersResultHolder.userId; LoginMethod loginMethod = recipeUserIdToLoginMethodMap.get(recipeUserId); + if (loginMethod == null) { // loginMethod will be null for primaryUserId for which the user has been deleted during unlink continue; } + String primaryUserId = authRecipeUsersResultHolder.primaryOrRecipeUserId; AuthRecipeUserInfo curr = userIdToAuthRecipeUserInfo.get(primaryUserId); if (curr == null) { @@ -1565,6 +1568,21 @@ public static AccountLinkingInfo getAccountLinkingInfo_Transaction(Start start, return accountLinkingInfo; } + public static boolean doesUserIdExist_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { + // We query both tables cause there is a case where a primary user ID exists, but its associated + // recipe user ID has been deleted AND there are other recipe user IDs linked to this primary user ID already. + String QUERY = "SELECT 1 FROM " + getConfig(start).getAppIdToUserIdTable() + + " WHERE app_id = ? AND user_id = ? UNION SELECT 1 FROM " + getConfig(start).getUsersTable() + + " WHERE app_id = ? AND primary_or_recipe_user_id = ?"; + return execute(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, userId); + pst.setString(3, appIdentifier.getAppId()); + pst.setString(4, userId); + }, ResultSet::next); + } + private static class AllAuthRecipeUsersResultHolder { String userId; String tenantId; @@ -1609,4 +1627,4 @@ public AccountLinkingInfo(String primaryUserId, boolean isLinked) { this.isLinked = isLinked; } } -} \ No newline at end of file +} diff --git a/src/main/java/io/supertokens/inmemorydb/queries/MultitenancyQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/MultitenancyQueries.java index da667a45b..82af7379d 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/MultitenancyQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/MultitenancyQueries.java @@ -216,7 +216,7 @@ public static void addTenantIdInTargetStorage(Start start, TenantIdentifier tena { String QUERY = "INSERT INTO " + Config.getConfig(start).getTenantsTable() - + "(app_id, tenant_id, created_at_time)" + " VALUES(?, ?, ?) ON CONFLICT DO NOTHING"; + + "(app_id, tenant_id, created_at_time)" + " VALUES(?, ?, ?)"; update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); diff --git a/src/main/java/io/supertokens/inmemorydb/queries/PasswordlessQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/PasswordlessQueries.java index 1112b90a3..54e5a49f3 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/PasswordlessQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/PasswordlessQueries.java @@ -422,7 +422,6 @@ public static AuthRecipeUserInfo createUser(Start start, TenantIdentifier tenant pst.setString(5, phoneNumber); }); } - UserInfoPartial userInfo = new UserInfoPartial(id, email, phoneNumber, timeJoined); fillUserInfoWithTenantIds_transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), userInfo); fillUserInfoWithVerified_transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), userInfo); @@ -463,7 +462,8 @@ private static UserInfoWithTenantId[] getUserInfosWithTenant_Transaction(Start s }); } - public static void deleteUser_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, String userId, boolean deleteUserIdMappingToo) + public static void deleteUser_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, + String userId, boolean deleteUserIdMappingToo) throws StorageQueryException, SQLException { UserInfoWithTenantId[] userInfos = getUserInfosWithTenant_Transaction(start, sqlCon, appIdentifier, userId); @@ -749,13 +749,13 @@ public static List getUsersInfoUsingIdList_Transaction(Start start, return Collections.emptyList(); } - public static UserInfoPartial getUserById_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, - String userId) throws StorageQueryException, SQLException { + private static UserInfoPartial getUserById_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, + String userId) + throws StorageQueryException, SQLException { // we don't need a LOCK here because this is already part of a transaction, and locked on app_id_to_user_id // table String QUERY = "SELECT user_id, email, phone_number, time_joined FROM " - + getConfig(start).getPasswordlessUsersTable() - + " WHERE app_id = ? AND user_id = ?"; + + getConfig(start).getPasswordlessUsersTable() + " WHERE app_id = ? AND user_id = ?"; return execute(sqlCon, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -769,12 +769,11 @@ public static UserInfoPartial getUserById_Transaction(Start start, Connection sq } public static List lockEmail_Transaction(Start start, Connection con, AppIdentifier appIdentifier, - String email) throws SQLException, StorageQueryException { + String email) throws StorageQueryException, SQLException { // normally the query below will use a for update, but sqlite doesn't support it. ((ConnectionWithLocks) con).lock( appIdentifier.getAppId() + "~" + email + Config.getConfig(start).getPasswordlessUsersTable()); - String QUERY = "SELECT user_id FROM " + getConfig(start).getPasswordlessUsersTable() + " WHERE app_id = ? AND email = ?"; return execute(con, QUERY, pst -> { @@ -789,7 +788,7 @@ public static List lockEmail_Transaction(Start start, Connection con, Ap }); } - public static String lockPhone_Transaction(Start start, Connection con, + public static List lockPhone_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String phoneNumber) throws SQLException, StorageQueryException { @@ -804,10 +803,11 @@ public static String lockPhone_Transaction(Start start, Connection con, pst.setString(1, appIdentifier.getAppId()); pst.setString(2, phoneNumber); }, result -> { - if (result.next()) { - return result.getString("user_id"); + List userIds = new ArrayList<>(); + while (result.next()) { + userIds.add(result.getString("user_id")); } - return null; + return userIds; }); } @@ -926,7 +926,7 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC { // passwordless_user_to_tenant String QUERY = "INSERT INTO " + getConfig(start).getPasswordlessUserToTenantTable() + "(app_id, tenant_id, user_id, email, phone_number)" - + " VALUES(?, ?, ?, ?, ?)" + " ON CONFLICT DO NOTHING"; + + " VALUES(?, ?, ?, ?, ?)" + " ON CONFLICT (app_id, tenant_id, user_id) DO NOTHING"; int numRows = update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); @@ -959,7 +959,17 @@ public static boolean removeUserIdFromTenant_Transaction(Start start, Connection // automatically deleted from passwordless_user_to_tenant because of foreign key constraint } - private static List fillUserInfoWithVerified(Start start, + private static UserInfoPartial fillUserInfoWithVerified_transaction(Start start, + Connection sqlCon, + AppIdentifier appIdentifier, + UserInfoPartial userInfo) + throws SQLException, StorageQueryException { + if (userInfo == null) return null; + return fillUserInfoWithVerified_transaction(start, sqlCon, appIdentifier, List.of(userInfo)).get(0); + } + + private static List fillUserInfoWithVerified_transaction(Start start, + Connection sqlCon, AppIdentifier appIdentifier, List userInfos) throws SQLException, StorageQueryException { @@ -972,7 +982,7 @@ private static List fillUserInfoWithVerified(Start start, userIdsAndEmails.add(new EmailVerificationQueries.UserIdAndEmail(userInfo.id, userInfo.email)); } } - List userIdsThatAreVerified = EmailVerificationQueries.isEmailVerified(start, + List userIdsThatAreVerified = EmailVerificationQueries.isEmailVerified_transaction(start, sqlCon, appIdentifier, userIdsAndEmails); Set verifiedUserIdsSet = new HashSet<>(userIdsThatAreVerified); @@ -991,38 +1001,9 @@ private static List fillUserInfoWithVerified(Start start, return userInfos; } - private static UserInfoPartial fillUserInfoWithVerified_transaction(Start start, - Connection sqlCon, - AppIdentifier appIdentifier, - UserInfoPartial userInfo) - throws SQLException, StorageQueryException { - if (userInfo == null) return null; - return fillUserInfoWithVerified_transaction(start, sqlCon, appIdentifier, List.of(userInfo)).get(0); - } - - private static List fillUserInfoWithTenantIds(Start start, - AppIdentifier appIdentifier, - List userInfos) - throws SQLException, StorageQueryException { - String[] userIds = new String[userInfos.size()]; - for (int i = 0; i < userInfos.size(); i++) { - userIds[i] = userInfos.get(i).id; - } - - Map> tenantIdsForUserIds = GeneralQueries.getTenantIdsForUserIds(start, - appIdentifier, - userIds); - List result = new ArrayList<>(); - for (UserInfoPartial userInfo : userInfos) { - userInfo.tenantIds = tenantIdsForUserIds.get(userInfo.id).toArray(new String[0]); - } - return userInfos; - } - - private static List fillUserInfoWithVerified_transaction(Start start, - Connection sqlCon, - AppIdentifier appIdentifier, - List userInfos) + private static List fillUserInfoWithVerified(Start start, + AppIdentifier appIdentifier, + List userInfos) throws SQLException, StorageQueryException { List userIdsAndEmails = new ArrayList<>(); for (UserInfoPartial userInfo : userInfos) { @@ -1033,7 +1014,7 @@ private static List fillUserInfoWithVerified_transaction(Start userIdsAndEmails.add(new EmailVerificationQueries.UserIdAndEmail(userInfo.id, userInfo.email)); } } - List userIdsThatAreVerified = EmailVerificationQueries.isEmailVerified_transaction(start, sqlCon, + List userIdsThatAreVerified = EmailVerificationQueries.isEmailVerified(start, appIdentifier, userIdsAndEmails); Set verifiedUserIdsSet = new HashSet<>(userIdsThatAreVerified); @@ -1079,6 +1060,25 @@ private static List fillUserInfoWithTenantIds_transaction(Start return userInfos; } + private static List fillUserInfoWithTenantIds(Start start, + AppIdentifier appIdentifier, + List userInfos) + throws SQLException, StorageQueryException { + String[] userIds = new String[userInfos.size()]; + for (int i = 0; i < userInfos.size(); i++) { + userIds[i] = userInfos.get(i).id; + } + + Map> tenantIdsForUserIds = GeneralQueries.getTenantIdsForUserIds(start, + appIdentifier, + userIds); + List result = new ArrayList<>(); + for (UserInfoPartial userInfo : userInfos) { + userInfo.tenantIds = tenantIdsForUserIds.get(userInfo.id).toArray(new String[0]); + } + return userInfos; + } + private static class PasswordlessDeviceRowMapper implements RowMapper { private static final PasswordlessDeviceRowMapper INSTANCE = new PasswordlessDeviceRowMapper(); @@ -1160,7 +1160,6 @@ public UserInfoPartial map(ResultSet result) throws Exception { } } - private static class UserInfoWithTenantId { public final String userId; public final String tenantId; diff --git a/src/main/java/io/supertokens/inmemorydb/queries/SessionQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/SessionQueries.java index dbcb6e215..65fa18c1a 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/SessionQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/SessionQueries.java @@ -203,24 +203,24 @@ public static int deleteSession(Start start, TenantIdentifier tenantIdentifier, }); } - public static void deleteSessionsOfUser_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, - String userId) + public static void deleteSessionsOfUser(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getSessionInfoTable() + " WHERE app_id = ? AND user_id = ?"; - update(sqlCon, QUERY.toString(), pst -> { + update(start, QUERY.toString(), pst -> { pst.setString(1, appIdentifier.getAppId()); pst.setString(2, userId); }); } - public static void deleteSessionsOfUser(Start start, AppIdentifier appIdentifier, String userId) + public static void deleteSessionsOfUser_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getSessionInfoTable() + " WHERE app_id = ? AND user_id = ?"; - update(start, QUERY.toString(), pst -> { + update(sqlCon, QUERY.toString(), pst -> { pst.setString(1, appIdentifier.getAppId()); pst.setString(2, userId); }); diff --git a/src/main/java/io/supertokens/inmemorydb/queries/ThirdPartyQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/ThirdPartyQueries.java index 89d876750..3e3848353 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/ThirdPartyQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/ThirdPartyQueries.java @@ -104,8 +104,7 @@ public static AuthRecipeUserInfo signUp(Start start, TenantIdentifier tenantIden { // all_auth_recipe_users String QUERY = "INSERT INTO " + getConfig(start).getUsersTable() - + - "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + " VALUES(?, ?, ?, ?, ?, ?, ?)"; update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); @@ -157,7 +156,8 @@ public static AuthRecipeUserInfo signUp(Start start, TenantIdentifier tenantIden }); } - public static void deleteUser_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, String userId, boolean deleteUserIdMappingToo) + public static void deleteUser_Transaction(Connection sqlCon, Start start, AppIdentifier appIdentifier, + String userId, boolean deleteUserIdMappingToo) throws StorageQueryException, SQLException { if (deleteUserIdMappingToo) { String QUERY = "DELETE FROM " + getConfig(start).getAppIdToUserIdTable() @@ -224,7 +224,7 @@ public static List lockThirdPartyInfo_Transaction(Start start, Connectio // in psql / mysql dbs, this will lock the rows that are in both the tables that meet the ON criteria only. String QUERY = "SELECT user_id " + " FROM " + getConfig(start).getThirdPartyUsersTable() + - " WHERE app_id = ? AND third_party_id = ? AND third_party_user_id = ? FOR UPDATE"; + " WHERE app_id = ? AND third_party_id = ? AND third_party_user_id = ?"; return execute(con, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -301,6 +301,7 @@ public static List getUsersInfoUsingIdList_Transaction(Start start, return Collections.emptyList(); } + public static List listUserIdsByThirdPartyInfo(Start start, AppIdentifier appIdentifier, String thirdPartyId, String thirdPartyUserId) throws SQLException, StorageQueryException { @@ -350,6 +351,7 @@ public static List listUserIdsByThirdPartyInfo_Transaction(Start start, public static String getUserIdByThirdPartyInfo(Start start, TenantIdentifier tenantIdentifier, String thirdPartyId, String thirdPartyUserId) throws SQLException, StorageQueryException { + String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + "FROM " + getConfig(start).getThirdPartyUserToTenantTable() + " AS tp" + " JOIN " + getConfig(start).getUsersTable() + " AS all_users" + @@ -369,27 +371,6 @@ public static String getUserIdByThirdPartyInfo(Start start, TenantIdentifier ten }); } - public static List getPrimaryUserIdUsingEmail_Transaction(Start start, Connection con, - AppIdentifier appIdentifier, String email) - throws StorageQueryException, SQLException { - String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " - + "FROM " + getConfig(start).getThirdPartyUsersTable() + " AS tp" + - " JOIN " + getConfig(start).getAppIdToUserIdTable() + " AS all_users" + - " ON tp.app_id = all_users.app_id AND tp.user_id = all_users.user_id" + - " WHERE tp.app_id = ? AND tp.email = ?"; - - return execute(con, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, email); - }, result -> { - List finalResult = new ArrayList<>(); - while (result.next()) { - finalResult.add(result.getString("user_id")); - } - return finalResult; - }); - } - public static void updateUserEmail_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String thirdPartyId, String thirdPartyUserId, String newEmail) throws SQLException, StorageQueryException { @@ -448,6 +429,27 @@ public static List getPrimaryUserIdUsingEmail(Start start, }); } + public static List getPrimaryUserIdUsingEmail_Transaction(Start start, Connection con, + AppIdentifier appIdentifier, String email) + throws StorageQueryException, SQLException { + String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + + "FROM " + getConfig(start).getThirdPartyUsersTable() + " AS tp" + + " JOIN " + getConfig(start).getAppIdToUserIdTable() + " AS all_users" + + " ON tp.app_id = all_users.app_id AND tp.user_id = all_users.user_id" + + " WHERE tp.app_id = ? AND tp.email = ?"; + + return execute(con, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, email); + }, result -> { + List finalResult = new ArrayList<>(); + while (result.next()) { + finalResult.add(result.getString("user_id")); + } + return finalResult; + }); + } + public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlCon, TenantIdentifier tenantIdentifier, String userId) throws SQLException, StorageQueryException, UnknownUserIdException { @@ -479,7 +481,7 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC { // thirdparty_user_to_tenant String QUERY = "INSERT INTO " + getConfig(start).getThirdPartyUserToTenantTable() + "(app_id, tenant_id, user_id, third_party_id, third_party_user_id)" - + " VALUES(?, ?, ?, ?, ?)" + " ON CONFLICT DO NOTHING"; + + " VALUES(?, ?, ?, ?, ?)" + " ON CONFLICT (app_id, tenant_id, user_id) DO NOTHING"; int numRows = update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); pst.setString(2, tenantIdentifier.getTenantId()); diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserIdMappingQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserIdMappingQueries.java index fd7831c75..2bfad8270 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserIdMappingQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserIdMappingQueries.java @@ -24,6 +24,7 @@ import io.supertokens.pluginInterface.useridmapping.UserIdMapping; import javax.annotation.Nullable; +import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -115,6 +116,25 @@ public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExter } + public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExternalUserId_Transaction(Start start, Connection sqlCon, + AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + + " WHERE app_id = ? AND (supertokens_user_id = ? OR external_user_id = ?)"; + + return execute(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, userId); + pst.setString(3, userId); + }, result -> { + ArrayList userIdMappingArray = new ArrayList<>(); + while (result.next()) { + userIdMappingArray.add(UserIdMappingRowMapper.getInstance().mapOrThrow(result)); + } + return userIdMappingArray.toArray(UserIdMapping[]::new); + }); + + } + public static HashMap getUserIdMappingWithUserIds(Start start, ArrayList userIds) throws SQLException, StorageQueryException { @@ -205,6 +225,37 @@ public static boolean updateOrDeleteExternalUserIdInfoWithExternalUserId(Start s return rowUpdated > 0; } + public static UserIdMapping getuseraIdMappingWithSuperTokensUserId_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { + String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + + " WHERE app_id = ? AND supertokens_user_id = ?"; + return execute(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, userId); + }, result -> { + if (result.next()) { + return UserIdMappingRowMapper.getInstance().mapOrThrow(result); + } + return null; + }); + } + + public static UserIdMapping getUserIdMappingWithExternalUserId_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { + String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + + " WHERE app_id = ? AND external_user_id = ?"; + + return execute(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, userId); + }, result -> { + if (result.next()) { + return UserIdMappingRowMapper.getInstance().mapOrThrow(result); + } + return null; + }); + } + private static class UserIdMappingRowMapper implements RowMapper { private static final UserIdMappingRowMapper INSTANCE = new UserIdMappingRowMapper(); @@ -221,4 +272,5 @@ public UserIdMapping map(ResultSet rs) throws Exception { rs.getString("external_user_id_info")); } } -} \ No newline at end of file + +} diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserMetadataQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserMetadataQueries.java index 4d673562f..bbdb4d9c3 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserMetadataQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserMetadataQueries.java @@ -48,7 +48,8 @@ public static String getQueryToCreateUserMetadataTable(Start start) { // @formatter:on } - public static int deleteUserMetadata(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + public static int deleteUserMetadata(Start start, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getUserMetadataTable() + " WHERE app_id = ? AND user_id = ?"; @@ -70,7 +71,8 @@ public static int deleteUserMetadata_Transaction(Connection sqlCon, Start start, }); } - public static int setUserMetadata_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String userId, JsonObject metadata) + public static int setUserMetadata_Transaction(Start start, Connection con, AppIdentifier appIdentifier, + String userId, JsonObject metadata) throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + getConfig(start).getUserMetadataTable() @@ -103,7 +105,8 @@ public static JsonObject getUserMetadata_Transaction(Start start, Connection con }); } - public static JsonObject getUserMetadata(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + public static JsonObject getUserMetadata(Start start, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { String QUERY = "SELECT user_metadata FROM " + getConfig(start).getUserMetadataTable() + " WHERE app_id = ? AND user_id = ?"; return execute(start, QUERY, pst -> { diff --git a/src/main/java/io/supertokens/inmemorydb/queries/UserRoleQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java similarity index 88% rename from src/main/java/io/supertokens/inmemorydb/queries/UserRoleQueries.java rename to src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java index 0b7bba5b2..dc7fb1710 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/UserRoleQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/UserRolesQueries.java @@ -33,7 +33,7 @@ import static io.supertokens.inmemorydb.QueryExecutorTemplate.update; import static io.supertokens.inmemorydb.config.Config.getConfig; -public class UserRoleQueries { +public class UserRolesQueries { public static String getQueryToCreateRolesTable(Start start) { String tableName = Config.getConfig(start).getRolesTable(); // @formatter:off @@ -101,7 +101,8 @@ public static boolean createNewRoleOrDoNothingIfExists_Transaction(Start start, public static void addPermissionToRoleOrDoNothingIfExists_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String role, - String permission) throws SQLException, StorageQueryException { + String permission) + throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + getConfig(start).getUserRolesPermissionsTable() + " (app_id, role, permission) VALUES(?, ?, ?) ON CONFLICT DO NOTHING"; @@ -112,32 +113,18 @@ public static void addPermissionToRoleOrDoNothingIfExists_Transaction(Start star }); } - public static boolean deleteRole(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { - - try { - return start.startTransaction(con -> { - // Row lock must be taken to delete the role, otherwise the table may be locked for delete - Connection sqlCon = (Connection) con.getConnection(); - ((ConnectionWithLocks) sqlCon).lock(appIdentifier.getAppId() + "~" + role + Config.getConfig(start).getRolesTable()); - - String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() - + " WHERE app_id = ? AND role = ? ;"; - - try { - return update(sqlCon, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, role); - }) == 1; - } catch (SQLException e) { - throw new StorageTransactionLogicException(e); - } - }); - } catch (StorageTransactionLogicException e) { - throw new StorageQueryException(e.actualException); - } + public static boolean deleteRole(Start start, AppIdentifier appIdentifier, String role) + throws SQLException, StorageQueryException { + String QUERY = "DELETE FROM " + getConfig(start).getRolesTable() + + " WHERE app_id = ? AND role = ? ;"; + return update(start, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, role); + }) == 1; } - public static boolean doesRoleExist(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { + public static boolean doesRoleExist(Start start, AppIdentifier appIdentifier, String role) + throws SQLException, StorageQueryException { String QUERY = "SELECT 1 FROM " + getConfig(start).getRolesTable() + " WHERE app_id = ? AND role = ?"; return execute(start, QUERY, pst -> { @@ -146,7 +133,8 @@ public static boolean doesRoleExist(Start start, AppIdentifier appIdentifier, St }, ResultSet::next); } - public static String[] getPermissionsForRole(Start start, AppIdentifier appIdentifier, String role) throws SQLException, StorageQueryException { + public static String[] getPermissionsForRole(Start start, AppIdentifier appIdentifier, String role) + throws SQLException, StorageQueryException { String QUERY = "SELECT permission FROM " + Config.getConfig(start).getUserRolesPermissionsTable() + " WHERE app_id = ? AND role = ?;"; return execute(start, QUERY, pst -> { @@ -161,7 +149,8 @@ public static String[] getPermissionsForRole(Start start, AppIdentifier appIdent }); } - public static String[] getRoles(Start start, AppIdentifier appIdentifier) throws SQLException, StorageQueryException { + public static String[] getRoles(Start start, AppIdentifier appIdentifier) + throws SQLException, StorageQueryException { String QUERY = "SELECT role FROM " + getConfig(start).getRolesTable() + " WHERE app_id = ?"; return execute(start, QUERY, pst -> pst.setString(1, appIdentifier.getAppId()), result -> { ArrayList roles = new ArrayList<>(); @@ -235,9 +224,9 @@ public static boolean deleteRoleForUser_Transaction(Start start, Connection con, return rowUpdatedCount > 0; } - public static boolean doesRoleExist_transaction(Start start, Connection con, AppIdentifier appIdentifier, String role) + public static boolean doesRoleExist_transaction(Start start, Connection con, AppIdentifier appIdentifier, + String role) throws SQLException, StorageQueryException { - ((ConnectionWithLocks) con).lock(appIdentifier.getAppId() + "~" + role + Config.getConfig(start).getRolesTable()); String QUERY = "SELECT 1 FROM " + getConfig(start).getRolesTable() @@ -248,7 +237,8 @@ public static boolean doesRoleExist_transaction(Start start, Connection con, App }, ResultSet::next); } - public static String[] getUsersForRole(Start start, TenantIdentifier tenantIdentifier, String role) throws SQLException, StorageQueryException { + public static String[] getUsersForRole(Start start, TenantIdentifier tenantIdentifier, String role) + throws SQLException, StorageQueryException { String QUERY = "SELECT user_id FROM " + getConfig(start).getUserRolesTable() + " WHERE app_id = ? AND tenant_id = ? AND role = ? "; return execute(start, QUERY, pst -> { @@ -266,7 +256,8 @@ public static String[] getUsersForRole(Start start, TenantIdentifier tenantIdent public static boolean deletePermissionForRole_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String role, - String permission) throws SQLException, StorageQueryException { + String permission) + throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getUserRolesPermissionsTable() + " WHERE app_id = ? AND role = ? AND permission = ? "; @@ -314,7 +305,8 @@ public static String[] getRolesThatHavePermission(Start start, AppIdentifier app }); } - public static int deleteAllRolesForUser(Start start, TenantIdentifier tenantIdentifier, String userId) throws SQLException, StorageQueryException { + public static int deleteAllRolesForUser(Start start, TenantIdentifier tenantIdentifier, String userId) + throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getUserRolesTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?"; return update(start, QUERY, pst -> { @@ -324,7 +316,9 @@ public static int deleteAllRolesForUser(Start start, TenantIdentifier tenantIden }); } - public static int deleteAllRolesForUser_Transaction(Connection con, Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + public static int deleteAllRolesForUser_Transaction(Connection con, Start start, + AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + getConfig(start).getUserRolesTable() + " WHERE app_id = ? AND user_id = ?"; return update(con, QUERY, pst -> { diff --git a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java index c5c5ddbf7..687e8fea2 100644 --- a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java +++ b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java @@ -25,15 +25,18 @@ import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.emailverification.EmailVerificationStorage; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.session.SessionStorage; +import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; import io.supertokens.pluginInterface.totp.TOTPStorage; import io.supertokens.pluginInterface.useridmapping.UserIdMappingStorage; import io.supertokens.pluginInterface.useridmapping.exception.UnknownSuperTokensUserIdException; import io.supertokens.pluginInterface.useridmapping.exception.UserIdMappingAlreadyExistsException; +import io.supertokens.pluginInterface.useridmapping.sqlStorage.UserIdMappingSQLStorage; import io.supertokens.pluginInterface.usermetadata.UserMetadataStorage; import io.supertokens.pluginInterface.userroles.UserRolesStorage; import io.supertokens.storageLayer.StorageLayer; @@ -124,17 +127,38 @@ public static io.supertokens.pluginInterface.useridmapping.UserIdMapping getUser AppIdentifierWithStorage appIdentifierWithStorage, String userId, UserIdType userIdType) throws StorageQueryException { - UserIdMappingStorage storage = appIdentifierWithStorage.getUserIdMappingStorage(); + UserIdMappingSQLStorage storage = (UserIdMappingSQLStorage) appIdentifierWithStorage.getUserIdMappingStorage(); + + try { + return storage.startTransaction(con -> { + return getUserIdMapping(con, appIdentifierWithStorage, userId, userIdType); + }); + } catch (StorageTransactionLogicException e) { + if (e.actualException instanceof StorageQueryException) { + throw (StorageQueryException) e.actualException; + } else { + throw new IllegalStateException(e.actualException); + } + } + } + + public static io.supertokens.pluginInterface.useridmapping.UserIdMapping getUserIdMapping( + TransactionConnection con, + AppIdentifierWithStorage appIdentifierWithStorage, String userId, + UserIdType userIdType) + throws StorageQueryException { + UserIdMappingSQLStorage storage = (UserIdMappingSQLStorage) appIdentifierWithStorage.getUserIdMappingStorage(); if (userIdType == UserIdType.SUPERTOKENS) { - return storage.getUserIdMapping(appIdentifierWithStorage, userId, true); + return storage.getUserIdMapping_Transaction(con, appIdentifierWithStorage, userId, true); } + if (userIdType == UserIdType.EXTERNAL) { - return storage.getUserIdMapping(appIdentifierWithStorage, userId, false); + return storage.getUserIdMapping_Transaction(con, appIdentifierWithStorage, userId, false); } - io.supertokens.pluginInterface.useridmapping.UserIdMapping[] userIdMappings = storage.getUserIdMapping( - appIdentifierWithStorage, userId); + io.supertokens.pluginInterface.useridmapping.UserIdMapping[] userIdMappings = storage.getUserIdMapping_Transaction( + con, appIdentifierWithStorage, userId); if (userIdMappings.length == 0) { return null; diff --git a/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java b/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java index fb6cc9af6..a302bc7a0 100644 --- a/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java +++ b/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java @@ -21,6 +21,7 @@ import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; import io.supertokens.emailpassword.exceptions.WrongCredentialsException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; +import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager; import io.supertokens.test.Utils; import io.supertokens.thirdparty.ThirdParty; @@ -103,6 +104,10 @@ public void timeTakenFor500SignInUpParallel() throws Exception { TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + ExecutorService ex = Executors.newFixedThreadPool(1000); int numberOfThreads = 500; diff --git a/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java b/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java index f46cd3d3e..73325130e 100644 --- a/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/CreatePrimaryUserTest.java @@ -130,6 +130,11 @@ public void testThatCreationOfPrimaryUserRequiresAccountLinkingFeatureToBeEnable TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + if (StorageLayer.isInMemDb(process.getProcess())) { + // Features are enabled by default for inmemory db + return; + } + try { AuthRecipe.createPrimaryUser(process.main, new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(process.main)), ""); diff --git a/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java b/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java index 5298adf7f..aab79a23a 100644 --- a/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/LinkAccountsTest.java @@ -167,6 +167,10 @@ public void testThatLinkingAccountsRequiresAccountLinkingFeatureToBeEnabled() th TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + try { AuthRecipe.linkAccounts(process.main, "", ""); assert (false); diff --git a/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java b/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java index eada034c6..1775db634 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/CreatePrimaryUserAPITest.java @@ -512,6 +512,10 @@ public void createReturnsFailsWithoutFeatureEnabled() throws Exception { return; } + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + AuthRecipeUserInfo user = EmailPassword.signUp(process.getProcess(), "test@example.com", "abcd1234"); JsonObject userObj; diff --git a/src/test/java/io/supertokens/test/accountlinking/api/LinkAccountsAPITest.java b/src/test/java/io/supertokens/test/accountlinking/api/LinkAccountsAPITest.java index 39a252ed7..5fd6a1943 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/LinkAccountsAPITest.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/LinkAccountsAPITest.java @@ -489,6 +489,10 @@ public void linkReturnsFailsWithoutFeatureEnabled() throws Exception { return; } + if (StorageLayer.isInMemDb(process.getProcess())) { + return; + } + AuthRecipeUserInfo user = EmailPassword.signUp(process.getProcess(), "test@example.com", "abcd1234"); AuthRecipeUserInfo user2 = EmailPassword.signUp(process.getProcess(), "test2@example.com", "abcd1234"); diff --git a/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java b/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java index aa5d0e538..b0195e33c 100644 --- a/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java +++ b/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java @@ -142,7 +142,7 @@ public void testDeleteUserBehaviorInIntermediateStateWithUser_1sUserId() throws requestBody.addProperty("userId", userInfo_1.getSupertokensUserId()); JsonObject deleteResponse = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "", - "http://localhost:3567/user/remove", requestBody, 1000, 1000, null, + "http://localhost:3567/user/remove", requestBody, 1000000, 1000000, null, SemVer.v2_15.get(), "emailpassword"); assertEquals("OK", deleteResponse.get("status").getAsString()); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java index fd249ac7a..261a0eb27 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestMultitenancyAPIHelper.java @@ -203,7 +203,7 @@ public static JsonObject getTenant(TenantIdentifier tenantIdentifier, Main main) public static JsonObject associateUserToTenant(TenantIdentifier tenantIdentifier, String userId, Main main) throws HttpResponseException, IOException { JsonObject requestBody = new JsonObject(); - requestBody.addProperty("userId", userId); + requestBody.addProperty("recipeUserId", userId); JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant/user"), @@ -216,7 +216,7 @@ public static JsonObject associateUserToTenant(TenantIdentifier tenantIdentifier public static JsonObject disassociateUserFromTenant(TenantIdentifier tenantIdentifier, String userId, Main main) throws HttpResponseException, IOException { JsonObject requestBody = new JsonObject(); - requestBody.addProperty("userId", userId); + requestBody.addProperty("recipeUserId", userId); JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(main, "", HttpRequestForTesting.getMultitenantUrl(tenantIdentifier, "/recipe/multitenancy/tenant/user/remove"), From ebf7be742a5dab834ffb857d5b3fe756f8dcb58a Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Thu, 14 Sep 2023 17:32:35 +0530 Subject: [PATCH 2/2] fix: tests --- .../test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java b/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java index b0195e33c..aa5d0e538 100644 --- a/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java +++ b/src/test/java/io/supertokens/test/authRecipe/DeleteUserAPIWithUserIdMappingTest.java @@ -142,7 +142,7 @@ public void testDeleteUserBehaviorInIntermediateStateWithUser_1sUserId() throws requestBody.addProperty("userId", userInfo_1.getSupertokensUserId()); JsonObject deleteResponse = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "", - "http://localhost:3567/user/remove", requestBody, 1000000, 1000000, null, + "http://localhost:3567/user/remove", requestBody, 1000, 1000, null, SemVer.v2_15.get(), "emailpassword"); assertEquals("OK", deleteResponse.get("status").getAsString());