Skip to content

Commit

Permalink
fix: backports to core 7.0 (#113)
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc authored Mar 21, 2024
1 parent 9a33054 commit 2470ce0
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 26 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [5.0.8] - 2024-03-21

- Fixes user id mapping queries
- Adds a new `useStaticKey` param to `updateSessionInfo_Transaction`
- This enables smooth switching between `useDynamicAccessTokenSigningKey` settings by allowing refresh calls to
change the signing key type of a session
- Fixes performance issue with user pagination

## [5.0.7] - 2024-02-19

- Fixes vulnerabilities in dependencies
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plugins {
id 'java-library'
}

version = "5.0.7"
version = "5.0.8"

repositories {
mavenCentral()
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/io/supertokens/storage/mysql/Start.java
Original file line number Diff line number Diff line change
Expand Up @@ -615,11 +615,11 @@ public SessionInfo getSessionInfo_Transaction(TenantIdentifier tenantIdentifier,
@Override
public void updateSessionInfo_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con,
String sessionHandle, String refreshTokenHash2,
long expiry) throws StorageQueryException {
long expiry, boolean useStaticKey) throws StorageQueryException {
Connection sqlCon = (Connection) con.getConnection();
try {
SessionQueries.updateSessionInfo_Transaction(this, sqlCon, tenantIdentifier, sessionHandle,
refreshTokenHash2, expiry);
refreshTokenHash2, expiry, useStaticKey);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
Expand Down Expand Up @@ -2185,10 +2185,10 @@ public boolean updateOrDeleteExternalUserIdInfo(AppIdentifier appIdentifier, Str
}

@Override
public HashMap<String, String> getUserIdMappingForSuperTokensIds(ArrayList<String> userIds)
public HashMap<String, String> getUserIdMappingForSuperTokensIds(AppIdentifier appIdentifier, ArrayList<String> userIds)
throws StorageQueryException {
try {
return UserIdMappingQueries.getUserIdMappingWithUserIds(this, userIds);
return UserIdMappingQueries.getUserIdMappingWithUserIds(this, appIdentifier, userIds);
} catch (SQLException e) {
throw new StorageQueryException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ public static List<String> isEmailVerified_transaction(Start start, Connection s
// calculating the verified emails

HashMap<String, String> supertokensUserIdToExternalUserIdMap = UserIdMappingQueries.getUserIdMappingWithUserIds_Transaction(start,
sqlCon, supertokensUserIds);
sqlCon, appIdentifier, supertokensUserIds);
HashMap<String, String> externalUserIdToSupertokensUserIdMap = new HashMap<>();

List<String> supertokensOrExternalUserIdsToQuery = new ArrayList<>();
Expand Down Expand Up @@ -352,7 +352,7 @@ public static List<String> isEmailVerified(Start start, AppIdentifier appIdentif
// We have external user id stored in the email verification table, so we need to fetch the mapped userids for
// calculating the verified emails
HashMap<String, String> supertokensUserIdToExternalUserIdMap = UserIdMappingQueries.getUserIdMappingWithUserIds(start,
supertokensUserIds);
appIdentifier, supertokensUserIds);
HashMap<String, String> externalUserIdToSupertokensUserIdMap = new HashMap<>();
List<String> supertokensOrExternalUserIdsToQuery = new ArrayList<>();
for (String userId : supertokensUserIds) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,11 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant
usersFromQuery = new ArrayList<>();
} else {

// This query is slightly different from one in postgres because we want to use same ordering for
// primary_or_recipe_user_time_joined and primary_or_recipe_user_id because mysql 5.7 does not support
// different ordering for different columns using an index
String finalQuery = "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM ( " + USER_SEARCH_TAG_CONDITION.toString() + " )"
+ " AS finalResultTable ORDER BY primary_or_recipe_user_time_joined " + timeJoinedOrder + ", primary_or_recipe_user_id DESC ";
+ " AS finalResultTable ORDER BY primary_or_recipe_user_time_joined " + timeJoinedOrder + ", primary_or_recipe_user_id " + timeJoinedOrder;
usersFromQuery = execute(start, finalQuery, pst -> {
for (int i = 1; i <= queryList.size(); i++) {
pst.setString(i, queryList.get(i - 1));
Expand Down Expand Up @@ -822,11 +825,17 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant
recipeIdCondition = recipeIdCondition + " AND";
}
String timeJoinedOrderSymbol = timeJoinedOrder.equals("ASC") ? ">" : "<";
String QUERY = "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM " + Config.getConfig(start).getUsersTable() + " WHERE "

// This query is slightly different from one in postgres because we want to use same ordering for
// primary_or_recipe_user_time_joined and primary_or_recipe_user_id because mysql 5.7 does not support
// different ordering for different columns using an index
String QUERY = "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM "
+ Config.getConfig(start).getUsersTable() + " WHERE "
+ recipeIdCondition + " (primary_or_recipe_user_time_joined " + timeJoinedOrderSymbol
+ " ? OR (primary_or_recipe_user_time_joined = ? AND primary_or_recipe_user_id <= ?)) AND app_id = ? AND tenant_id = ?"
+ " ? OR (primary_or_recipe_user_time_joined = ? AND primary_or_recipe_user_id "
+ (timeJoinedOrderSymbol + "=") + " ?)) AND app_id = ? AND tenant_id = ?"
+ " ORDER BY primary_or_recipe_user_time_joined " + timeJoinedOrder
+ ", primary_or_recipe_user_id DESC LIMIT ?";
+ ", primary_or_recipe_user_id " + timeJoinedOrder + " LIMIT ?";
usersFromQuery = execute(start, QUERY, pst -> {
if (includeRecipeIds != null) {
for (int i = 0; i < includeRecipeIds.length; i++) {
Expand All @@ -850,12 +859,16 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant
});
} else {
String recipeIdCondition = RECIPE_ID_CONDITION.toString();
String QUERY = "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM " + Config.getConfig(start).getUsersTable() + " WHERE ";
// This query is slightly different from one in postgres because we want to use same ordering for
// primary_or_recipe_user_time_joined and primary_or_recipe_user_id because mysql 5.7 does not support
// different ordering for different columns using an index
String QUERY = "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM "
+ Config.getConfig(start).getUsersTable() + " WHERE ";
if (!recipeIdCondition.equals("")) {
QUERY += recipeIdCondition + " AND";
}
QUERY += " app_id = ? AND tenant_id = ? ORDER BY primary_or_recipe_user_time_joined " + timeJoinedOrder
+ ", primary_or_recipe_user_id DESC LIMIT ?";
+ ", primary_or_recipe_user_id " + timeJoinedOrder + " LIMIT ?";
usersFromQuery = execute(start, QUERY, pst -> {
if (includeRecipeIds != null) {
for (int i = 0; i < includeRecipeIds.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,19 @@ public static SessionInfo getSessionInfo_Transaction(Start start, Connection con

public static void updateSessionInfo_Transaction(Start start, Connection con, TenantIdentifier tenantIdentifier,
String sessionHandle,
String refreshTokenHash2, long expiry)
String refreshTokenHash2, long expiry, boolean useStaticKey)
throws SQLException, StorageQueryException {
String QUERY = "UPDATE " + Config.getConfig(start).getSessionInfoTable()
+ " SET refresh_token_hash_2 = ?, expires_at = ?"
+ " SET refresh_token_hash_2 = ?, expires_at = ?, use_static_key = ?"
+ " WHERE app_id = ? AND tenant_id = ? AND session_handle = ?";

update(con, QUERY, pst -> {
pst.setString(1, refreshTokenHash2);
pst.setLong(2, expiry);
pst.setString(3, tenantIdentifier.getAppId());
pst.setString(4, tenantIdentifier.getTenantId());
pst.setString(5, sessionHandle);
pst.setBoolean(3, useStaticKey);
pst.setString(4, tenantIdentifier.getAppId());
pst.setString(5, tenantIdentifier.getTenantId());
pst.setString(6, sessionHandle);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExter

}

public static HashMap<String, String> getUserIdMappingWithUserIds(Start start, List<String> userIds)
public static HashMap<String, String> getUserIdMappingWithUserIds(Start start,
AppIdentifier appIdentifier,
List<String> userIds)
throws SQLException, StorageQueryException {

if (userIds.size() == 0) {
Expand All @@ -126,7 +128,8 @@ public static HashMap<String, String> getUserIdMappingWithUserIds(Start start, L

// No need to filter based on tenantId because the id list is already filtered for a tenant
StringBuilder QUERY = new StringBuilder(
"SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE supertokens_user_id IN (");
"SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE " +
"app_id = ? AND supertokens_user_id IN (");
for (int i = 0; i < userIds.size(); i++) {
QUERY.append("?");
if (i != userIds.size() - 1) {
Expand All @@ -136,9 +139,10 @@ public static HashMap<String, String> getUserIdMappingWithUserIds(Start start, L
}
QUERY.append(")");
return execute(start, QUERY.toString(), pst -> {
pst.setString(1, appIdentifier.getAppId());
for (int i = 0; i < userIds.size(); i++) {
// i+1 cause this starts with 1 and not 0
pst.setString(i + 1, userIds.get(i));
// i+2 cause this starts with 1 and not 0, 1 is appId
pst.setString(i + 2, userIds.get(i));
}
}, result -> {
HashMap<String, String> userIdMappings = new HashMap<>();
Expand All @@ -150,7 +154,9 @@ public static HashMap<String, String> getUserIdMappingWithUserIds(Start start, L
});
}

public static HashMap<String, String> getUserIdMappingWithUserIds_Transaction(Start start, Connection sqlCon, List<String> userIds)
public static HashMap<String, String> getUserIdMappingWithUserIds_Transaction(Start start, Connection sqlCon,
AppIdentifier appIdentifier,
List<String> userIds)
throws SQLException, StorageQueryException {

if (userIds.size() == 0) {
Expand All @@ -159,7 +165,8 @@ public static HashMap<String, String> getUserIdMappingWithUserIds_Transaction(St

// No need to filter based on tenantId because the id list is already filtered for a tenant
StringBuilder QUERY = new StringBuilder(
"SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE supertokens_user_id IN (");
"SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND " +
"supertokens_user_id IN (");
for (int i = 0; i < userIds.size(); i++) {
QUERY.append("?");
if (i != userIds.size() - 1) {
Expand All @@ -169,9 +176,10 @@ public static HashMap<String, String> getUserIdMappingWithUserIds_Transaction(St
}
QUERY.append(")");
return execute(sqlCon, QUERY.toString(), pst -> {
pst.setString(1, appIdentifier.getAppId());
for (int i = 0; i < userIds.size(); i++) {
// i+1 cause this starts with 1 and not 0
pst.setString(i + 1, userIds.get(i));
// i+2 cause this starts with 1 and not 0, 1 is appId
pst.setString(i + 2, userIds.get(i));
}
}, result -> {
HashMap<String, String> userIdMappings = new HashMap<>();
Expand Down

0 comments on commit 2470ce0

Please sign in to comment.