Skip to content

Commit c19b2b9

Browse files
authored
fix: slow queries for account linking (#1103)
* fix: indexes for account linking * fix: typos * fix: mask password in 500 response
1 parent 7b26f5f commit c19b2b9

File tree

7 files changed

+113
-3
lines changed

7 files changed

+113
-3
lines changed

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,41 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88
## [Unreleased]
99

10+
## [10.0.1]
11+
12+
- Fixes slow queries for account linking
13+
- Masks db password in 500 response
14+
15+
### Migration
16+
17+
If using PostgreSQL, run the following SQL script:
18+
19+
```sql
20+
CREATE INDEX IF NOT EXISTS emailpassword_users_email_index ON emailpassword_users (app_id, email);
21+
CREATE INDEX IF NOT EXISTS emailpassword_user_to_tenant_email_index ON emailpassword_user_to_tenant (app_id, tenant_id, email);
22+
23+
CREATE INDEX IF NOT EXISTS passwordless_users_email_index ON passwordless_users (app_id, email);
24+
CREATE INDEX IF NOT EXISTS passwordless_users_phone_number_index ON passwordless_users (app_id, phone_number);
25+
CREATE INDEX IF NOT EXISTS passwordless_user_to_tenant_email_index ON passwordless_user_to_tenant (app_id, tenant_id, email);
26+
CREATE INDEX IF NOT EXISTS passwordless_user_to_tenant_phone_number_index ON passwordless_user_to_tenant (app_id, tenant_id, phone_number);
27+
28+
CREATE INDEX IF NOT EXISTS thirdparty_user_to_tenant_third_party_user_id_index ON thirdparty_user_to_tenant (app_id, tenant_id, third_party_id, third_party_user_id);
29+
```
30+
31+
If using MySQL, run the following SQL script:
32+
33+
```sql
34+
CREATE INDEX emailpassword_users_email_index ON emailpassword_users (app_id, email);
35+
CREATE INDEX emailpassword_user_to_tenant_email_index ON emailpassword_user_to_tenant (app_id, tenant_id, email);
36+
37+
CREATE INDEX passwordless_users_email_index ON passwordless_users (app_id, email);
38+
CREATE INDEX passwordless_users_phone_number_index ON passwordless_users (app_id, phone_number);
39+
CREATE INDEX passwordless_user_to_tenant_email_index ON passwordless_user_to_tenant (app_id, tenant_id, email);
40+
CREATE INDEX passwordless_user_to_tenant_phone_number_index ON passwordless_user_to_tenant (app_id, tenant_id, phone_number);
41+
42+
CREATE INDEX thirdparty_user_to_tenant_third_party_user_id_index ON thirdparty_user_to_tenant (app_id, tenant_id, third_party_id, third_party_user_id);
43+
```
44+
1045
## [10.0.0]
1146

1247
### Added

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ compileTestJava { options.encoding = "UTF-8" }
1919
// }
2020
//}
2121

22-
version = "10.0.0"
22+
version = "10.0.1"
2323

2424
repositories {
2525
mavenCentral()

src/main/java/io/supertokens/inmemorydb/queries/EmailPasswordQueries.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ static String getQueryToCreateUsersTable(Start start) {
5858
+ ");";
5959
}
6060

61+
static String getQueryToCreateEmailPasswordUsersEmailIndex(Start start) {
62+
return "CREATE INDEX emailpassword_users_email_index ON "
63+
+ Config.getConfig(start).getEmailPasswordUsersTable() + "(app_id, email);";
64+
}
65+
6166
static String getQueryToCreateEmailPasswordUserToTenantTable(Start start) {
6267
String emailPasswordUserToTenantTable = Config.getConfig(start).getEmailPasswordUserToTenantTable();
6368
// @formatter:off
@@ -75,6 +80,11 @@ static String getQueryToCreateEmailPasswordUserToTenantTable(Start start) {
7580
// @formatter:on
7681
}
7782

83+
static String getQueryToCreateEmailPasswordUserToTenantEmailIndex(Start start) {
84+
return "CREATE INDEX emailpassword_user_to_tenant_email_index ON "
85+
+ Config.getConfig(start).getEmailPasswordUserToTenantTable() + "(app_id, tenant_id, email);";
86+
}
87+
7888
static String getQueryToCreatePasswordResetTokensTable(Start start) {
7989
return "CREATE TABLE IF NOT EXISTS " + Config.getConfig(start).getPasswordResetTokensTable() + " ("
8090
+ "app_id VARCHAR(64) DEFAULT 'public',"

src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,19 @@ public static void createTablesIfNotExists(Start start, Main main) throws SQLExc
292292
if (!doesTableExists(start, Config.getConfig(start).getEmailPasswordUsersTable())) {
293293
getInstance(main).addState(CREATING_NEW_TABLE, null);
294294
update(start, EmailPasswordQueries.getQueryToCreateUsersTable(start), NO_OP_SETTER);
295+
296+
// index
297+
update(start, EmailPasswordQueries.getQueryToCreateEmailPasswordUsersEmailIndex(start), NO_OP_SETTER);
295298
}
296299

297300
if (!doesTableExists(start, Config.getConfig(start).getEmailPasswordUserToTenantTable())) {
298301
getInstance(main).addState(CREATING_NEW_TABLE, null);
299302
update(start, EmailPasswordQueries.getQueryToCreateEmailPasswordUserToTenantTable(start),
300303
NO_OP_SETTER);
304+
305+
// index
306+
update(start, EmailPasswordQueries.getQueryToCreateEmailPasswordUserToTenantEmailIndex(start),
307+
NO_OP_SETTER);
301308
}
302309

303310
if (!doesTableExists(start, Config.getConfig(start).getPasswordResetTokensTable())) {
@@ -322,6 +329,7 @@ public static void createTablesIfNotExists(Start start, Main main) throws SQLExc
322329
if (!doesTableExists(start, Config.getConfig(start).getThirdPartyUsersTable())) {
323330
getInstance(main).addState(CREATING_NEW_TABLE, null);
324331
update(start, ThirdPartyQueries.getQueryToCreateUsersTable(start), NO_OP_SETTER);
332+
325333
// index
326334
update(start, ThirdPartyQueries.getQueryToThirdPartyUserEmailIndex(start), NO_OP_SETTER);
327335
update(start, ThirdPartyQueries.getQueryToThirdPartyUserIdIndex(start), NO_OP_SETTER);
@@ -330,6 +338,9 @@ public static void createTablesIfNotExists(Start start, Main main) throws SQLExc
330338
if (!doesTableExists(start, Config.getConfig(start).getThirdPartyUserToTenantTable())) {
331339
getInstance(main).addState(CREATING_NEW_TABLE, null);
332340
update(start, ThirdPartyQueries.getQueryToCreateThirdPartyUserToTenantTable(start), NO_OP_SETTER);
341+
342+
// index
343+
update(start, ThirdPartyQueries.getQueryToCreateThirdPartyUserToTenantThirdPartyUserIdIndex(start), NO_OP_SETTER);
333344
}
334345

335346
if (!doesTableExists(start, Config.getConfig(start).getJWTSigningKeysTable())) {
@@ -340,12 +351,20 @@ public static void createTablesIfNotExists(Start start, Main main) throws SQLExc
340351
if (!doesTableExists(start, Config.getConfig(start).getPasswordlessUsersTable())) {
341352
getInstance(main).addState(CREATING_NEW_TABLE, null);
342353
update(start, PasswordlessQueries.getQueryToCreateUsersTable(start), NO_OP_SETTER);
354+
355+
// index
356+
update(start, PasswordlessQueries.getQueryToCreatePasswordlessUsersEmailIndex(start), NO_OP_SETTER);
357+
update(start, PasswordlessQueries.getQueryToCreatePasswordlessUsersPhoneNumberIndex(start), NO_OP_SETTER);
343358
}
344359

345360
if (!doesTableExists(start, Config.getConfig(start).getPasswordlessUserToTenantTable())) {
346361
getInstance(main).addState(CREATING_NEW_TABLE, null);
347362
update(start, PasswordlessQueries.getQueryToCreatePasswordlessUserToTenantTable(start),
348363
NO_OP_SETTER);
364+
365+
// index
366+
update(start, PasswordlessQueries.getQueryToCreatePasswordlessUserToTenantEmailIndex(start), NO_OP_SETTER);
367+
update(start, PasswordlessQueries.getQueryToCreatePasswordlessUserToTenantPhoneNumberIndex(start), NO_OP_SETTER);
349368
}
350369

351370
if (!doesTableExists(start, Config.getConfig(start).getPasswordlessDevicesTable())) {

src/main/java/io/supertokens/inmemorydb/queries/PasswordlessQueries.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ public static String getQueryToCreateUsersTable(Start start) {
6060
+ ");";
6161
}
6262

63+
static String getQueryToCreatePasswordlessUsersEmailIndex(Start start) {
64+
return "CREATE INDEX passwordless_users_email_index ON "
65+
+ Config.getConfig(start).getPasswordlessUsersTable() + "(app_id, email);";
66+
}
67+
68+
static String getQueryToCreatePasswordlessUsersPhoneNumberIndex(Start start) {
69+
return "CREATE INDEX passwordless_users_phone_number_index ON "
70+
+ Config.getConfig(start).getPasswordlessUsersTable() + "(app_id, phone_number);";
71+
}
72+
6373
static String getQueryToCreatePasswordlessUserToTenantTable(Start start) {
6474
String passwordlessUserToTenantTable = Config.getConfig(start).getPasswordlessUserToTenantTable();
6575
// @formatter:off
@@ -79,6 +89,16 @@ static String getQueryToCreatePasswordlessUserToTenantTable(Start start) {
7989
// @formatter:on
8090
}
8191

92+
static String getQueryToCreatePasswordlessUserToTenantEmailIndex(Start start) {
93+
return "CREATE INDEX passwordless_user_to_tenant_email_index ON "
94+
+ Config.getConfig(start).getPasswordlessUserToTenantTable() + "(app_id, tenant_id, email);";
95+
}
96+
97+
static String getQueryToCreatePasswordlessUserToTenantPhoneNumberIndex(Start start) {
98+
return "CREATE INDEX passwordless_user_to_tenant_phone_number_index ON "
99+
+ Config.getConfig(start).getPasswordlessUserToTenantTable() + "(app_id, tenant_id, phone_number);";
100+
}
101+
82102
public static String getQueryToCreateDevicesTable(Start start) {
83103
return "CREATE TABLE IF NOT EXISTS " + Config.getConfig(start).getPasswordlessDevicesTable() + " ("
84104
+ "app_id VARCHAR(64) DEFAULT 'public',"

src/main/java/io/supertokens/inmemorydb/queries/ThirdPartyQueries.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ static String getQueryToCreateThirdPartyUserToTenantTable(Start start) {
8585
// @formatter:on
8686
}
8787

88+
static String getQueryToCreateThirdPartyUserToTenantThirdPartyUserIdIndex(Start start) {
89+
return "CREATE INDEX thirdparty_user_to_tenant_third_party_user_id_index ON "
90+
+ Config.getConfig(start).getThirdPartyUserToTenantTable() + "(app_id, tenant_id, third_party_id, third_party_user_id);";
91+
}
92+
8893
public static AuthRecipeUserInfo signUp(Start start, TenantIdentifier tenantIdentifier, String id, String email,
8994
LoginMethod.ThirdParty thirdParty, long timeJoined)
9095
throws StorageQueryException, StorageTransactionLogicException {

src/main/java/io/supertokens/webserver/WebserverAPI.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import java.io.IOException;
4747
import java.util.HashSet;
4848
import java.util.Set;
49+
import java.util.regex.Matcher;
50+
import java.util.regex.Pattern;
4951
import java.util.regex.PatternSyntaxException;
5052

5153
public abstract class WebserverAPI extends HttpServlet {
@@ -532,10 +534,14 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
532534
} else if (rootCause instanceof BadPermissionException) {
533535
sendTextResponse(403, rootCause.getMessage(), resp);
534536
} else {
535-
sendTextResponse(500, rootCause.toString(), resp);
537+
String msg = rootCause.toString();
538+
msg = maskDBPassword(msg);
539+
sendTextResponse(500, msg, resp);
536540
}
537541
} else {
538-
sendTextResponse(500, e.toString(), resp);
542+
String msg = e.toString();
543+
msg = maskDBPassword(msg);
544+
sendTextResponse(500, msg, resp);
539545
}
540546
}
541547
Logging.info(main, tenantIdentifier, "API ended: " + req.getRequestURI() + ". Method: " + req.getMethod(),
@@ -550,6 +556,21 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
550556
}
551557
}
552558

559+
public static String maskDBPassword(String log) {
560+
String regex = "(\\|db_pass\\|)(.*?)(\\|db_pass\\|)";
561+
562+
Matcher matcher = Pattern.compile(regex).matcher(log);
563+
StringBuffer maskedLog = new StringBuffer();
564+
565+
while (matcher.find()) {
566+
String maskedPassword = "*".repeat(8);
567+
matcher.appendReplacement(maskedLog, "|" + maskedPassword + "|");
568+
}
569+
570+
matcher.appendTail(maskedLog);
571+
return maskedLog.toString();
572+
}
573+
553574
protected String getRIDFromRequest(HttpServletRequest req) {
554575
return req.getHeader("rId");
555576
}

0 commit comments

Comments
 (0)