Skip to content

Commit

Permalink
fix: email verified in login methods (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc authored Nov 1, 2023
1 parent 633bde6 commit 71c6fa8
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [5.0.2] - 2023-11-01

- Fixes `verified` in `loginMethods` for users with userId mapping

## [5.0.1] - 2023-10-12

- Fixes user info from primary user id query
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.1"
version = "5.0.2"

repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,26 +238,50 @@ public static List<String> isEmailVerified_transaction(Start start, Connection s
return new ArrayList<>();
}
List<String> emails = new ArrayList<>();
List<String> userIds = new ArrayList<>();
Map<String, String> userIdToEmailMap = new HashMap<>();
List<String> supertokensUserIds = new ArrayList<>();
for (UserIdAndEmail ue : userIdAndEmail) {
emails.add(ue.email);
userIds.add(ue.userId);
supertokensUserIds.add(ue.userId);
}

// 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_Transaction(start,
sqlCon, supertokensUserIds);
HashMap<String, String> externalUserIdToSupertokensUserIdMap = new HashMap<>();

List<String> supertokensOrExternalUserIdsToQuery = new ArrayList<>();
for (String userId : supertokensUserIds) {
if (supertokensUserIdToExternalUserIdMap.containsKey(userId)) {
supertokensOrExternalUserIdsToQuery.add(supertokensUserIdToExternalUserIdMap.get(userId));
externalUserIdToSupertokensUserIdMap.put(supertokensUserIdToExternalUserIdMap.get(userId), userId);
} else {
supertokensOrExternalUserIdsToQuery.add(userId);
externalUserIdToSupertokensUserIdMap.put(userId, userId);
}
}

Map<String, String> supertokensOrExternalUserIdToEmailMap = new HashMap<>();
for (UserIdAndEmail ue : userIdAndEmail) {
if (userIdToEmailMap.containsKey(ue.userId)) {
String supertokensOrExternalUserId = ue.userId;
if (supertokensUserIdToExternalUserIdMap.containsKey(supertokensOrExternalUserId)) {
supertokensOrExternalUserId = supertokensUserIdToExternalUserIdMap.get(supertokensOrExternalUserId);
}
if (supertokensOrExternalUserIdToEmailMap.containsKey(supertokensOrExternalUserId)) {
throw new RuntimeException("Found a bug!");
}
userIdToEmailMap.put(ue.userId, ue.email);
supertokensOrExternalUserIdToEmailMap.put(supertokensOrExternalUserId, ue.email);
}

String QUERY = "SELECT * FROM " + getConfig(start).getEmailVerificationTable()
+ " WHERE app_id = ? AND user_id IN (" + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) +
+ " WHERE app_id = ? AND user_id IN (" + Utils.generateCommaSeperatedQuestionMarks(supertokensOrExternalUserIdsToQuery.size()) +
") AND email IN (" + Utils.generateCommaSeperatedQuestionMarks(emails.size()) + ")";

return execute(sqlCon, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
int index = 2;
for (String userId : userIds) {
for (String userId : supertokensOrExternalUserIdsToQuery) {
pst.setString(index++, userId);
}
for (String email : emails) {
Expand All @@ -266,10 +290,10 @@ public static List<String> isEmailVerified_transaction(Start start, Connection s
}, result -> {
List<String> res = new ArrayList<>();
while (result.next()) {
String userId = result.getString("user_id");
String supertokensOrExternalUserId = result.getString("user_id");
String email = result.getString("email");
if (Objects.equals(userIdToEmailMap.get(userId), email)) {
res.add(userId);
if (Objects.equals(supertokensOrExternalUserIdToEmailMap.get(supertokensOrExternalUserId), email)) {
res.add(externalUserIdToSupertokensUserIdMap.get(supertokensOrExternalUserId));
}
}
return res;
Expand All @@ -283,26 +307,46 @@ public static List<String> isEmailVerified(Start start, AppIdentifier appIdentif
return new ArrayList<>();
}
List<String> emails = new ArrayList<>();
List<String> userIds = new ArrayList<>();
Map<String, String> userIdToEmailMap = new HashMap<>();
List<String> supertokensUserIds = new ArrayList<>();

for (UserIdAndEmail ue : userIdAndEmail) {
emails.add(ue.email);
userIds.add(ue.userId);
supertokensUserIds.add(ue.userId);
}
// 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);
HashMap<String, String> externalUserIdToSupertokensUserIdMap = new HashMap<>();
List<String> supertokensOrExternalUserIdsToQuery = new ArrayList<>();
for (String userId : supertokensUserIds) {
if (supertokensUserIdToExternalUserIdMap.containsKey(userId)) {
supertokensOrExternalUserIdsToQuery.add(supertokensUserIdToExternalUserIdMap.get(userId));
externalUserIdToSupertokensUserIdMap.put(supertokensUserIdToExternalUserIdMap.get(userId), userId);
} else {
supertokensOrExternalUserIdsToQuery.add(userId);
externalUserIdToSupertokensUserIdMap.put(userId, userId);
}
}

Map<String, String> supertokensOrExternalUserIdToEmailMap = new HashMap<>();
for (UserIdAndEmail ue : userIdAndEmail) {
if (userIdToEmailMap.containsKey(ue.userId)) {
String supertokensOrExternalUserId = ue.userId;
if (supertokensUserIdToExternalUserIdMap.containsKey(supertokensOrExternalUserId)) {
supertokensOrExternalUserId = supertokensUserIdToExternalUserIdMap.get(supertokensOrExternalUserId);
}
if (supertokensOrExternalUserIdToEmailMap.containsKey(supertokensOrExternalUserId)) {
throw new RuntimeException("Found a bug!");
}
userIdToEmailMap.put(ue.userId, ue.email);
supertokensOrExternalUserIdToEmailMap.put(supertokensOrExternalUserId, ue.email);
}
String QUERY = "SELECT * FROM " + getConfig(start).getEmailVerificationTable()
+ " WHERE app_id = ? AND user_id IN (" + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) +
+ " WHERE app_id = ? AND user_id IN (" + Utils.generateCommaSeperatedQuestionMarks(supertokensOrExternalUserIdsToQuery.size()) +
") AND email IN (" + Utils.generateCommaSeperatedQuestionMarks(emails.size()) + ")";

return execute(start, QUERY, pst -> {
pst.setString(1, appIdentifier.getAppId());
int index = 2;
for (String userId : userIds) {
for (String userId : supertokensOrExternalUserIdsToQuery) {
pst.setString(index++, userId);
}
for (String email : emails) {
Expand All @@ -311,10 +355,10 @@ public static List<String> isEmailVerified(Start start, AppIdentifier appIdentif
}, result -> {
List<String> res = new ArrayList<>();
while (result.next()) {
String userId = result.getString("user_id");
String supertokensOrExternalUserId = result.getString("user_id");
String email = result.getString("email");
if (Objects.equals(userIdToEmailMap.get(userId), email)) {
res.add(userId);
if (Objects.equals(supertokensOrExternalUserIdToEmailMap.get(supertokensOrExternalUserId), email)) {
res.add(externalUserIdToSupertokensUserIdMap.get(supertokensOrExternalUserId));
}
}
return res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static io.supertokens.storage.mysql.QueryExecutorTemplate.execute;
import static io.supertokens.storage.mysql.QueryExecutorTemplate.update;
Expand Down Expand Up @@ -116,7 +117,7 @@ public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExter

}

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

if (userIds.size() == 0) {
Expand Down Expand Up @@ -149,6 +150,39 @@ public static HashMap<String, String> getUserIdMappingWithUserIds(Start start, A
});
}

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

if (userIds.size() == 0) {
return new HashMap<>();
}

// 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 (");
for (int i = 0; i < userIds.size(); i++) {
QUERY.append("?");
if (i != userIds.size() - 1) {
// not the last element
QUERY.append(",");
}
}
QUERY.append(")");
return execute(sqlCon, QUERY.toString(), pst -> {
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));
}
}, result -> {
HashMap<String, String> userIdMappings = new HashMap<>();
while (result.next()) {
UserIdMapping temp = UserIdMappingRowMapper.getInstance().mapOrThrow(result);
userIdMappings.put(temp.superTokensUserId, temp.externalUserId);
}
return userIdMappings;
});
}

public static boolean deleteUserIdMappingWithSuperTokensUserId(Start start, AppIdentifier appIdentifier, String userId)
throws SQLException, StorageQueryException {
String QUERY = "DELETE FROM " + Config.getConfig(start).getUserIdMappingTable()
Expand Down

0 comments on commit 71c6fa8

Please sign in to comment.