Skip to content

Commit 3d9dcf1

Browse files
authored
Merge branch '8.1' into feat/webauthn-base
2 parents 74e6acf + 3eab6c7 commit 3d9dcf1

16 files changed

+223
-91
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ CREATE INDEX IF NOT EXISTS webauthn_account_recovery_token_expires_at_index ON w
9393
CREATE INDEX IF NOT EXISTS webauthn_account_recovery_token_email_index ON webauthn_account_recovery_tokens (app_id, tenant_id, email);
9494
```
9595

96+
## [8.0.3]
97+
98+
- Fixes `StorageTransactionLogicException` in bulk import when not using userRoles and totpDevices in import json.
99+
- Adds `USE_STRUCTURED_LOGGING` environment variable to control the logging format.
96100

97101
## [8.0.2]
98102

src/main/java/io/supertokens/storage/postgresql/QueryExecutorTemplate.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ static <T> T execute(Connection con, String QUERY, PreparedStatementValueSetter
4747

4848
static void executeBatch(Connection connection, String QUERY, List<PreparedStatementValueSetter> setters)
4949
throws SQLException, StorageQueryException {
50-
assert setters != null;
51-
assert !setters.isEmpty();
50+
if(setters == null || setters.isEmpty()) {
51+
return;
52+
}
5253
try (PreparedStatement pst = connection.prepareStatement(QUERY)) {
5354
int counter = 0;
5455
for(PreparedStatementValueSetter setter: setters) {

src/main/java/io/supertokens/storage/postgresql/output/CustomLayout.java

Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
import ch.qos.logback.classic.spi.ILoggingEvent;
2121
import ch.qos.logback.core.CoreConstants;
2222
import ch.qos.logback.core.LayoutBase;
23+
import com.google.gson.Gson;
24+
import com.google.gson.JsonArray;
25+
import com.google.gson.JsonElement;
26+
import com.google.gson.JsonObject;
2327
import io.supertokens.storage.postgresql.utils.Utils;
2428

2529
import java.text.DateFormat;
@@ -29,39 +33,82 @@
2933
class CustomLayout extends LayoutBase<ILoggingEvent> {
3034

3135
private final String processID;
36+
private boolean useStructuredLogging = false;
3237

3338
CustomLayout(String processID) {
3439
super();
3540
this.processID = processID;
41+
this.useStructuredLogging = Boolean.parseBoolean(System.getenv("USE_STRUCTURED_LOGGING"));
3642
}
3743

3844
@Override
3945
public String doLayout(ILoggingEvent event) {
40-
StringBuilder sbuf = new StringBuilder();
41-
46+
JsonObject msgObj = new Gson().fromJson(event.getMessage(), JsonObject.class);
4247
DateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:SSS Z");
43-
sbuf.append(dateFormat.format(new Date(event.getTimeStamp())));
44-
sbuf.append(" | ");
4548

46-
sbuf.append(event.getLevel());
47-
sbuf.append(" | ");
49+
if (useStructuredLogging) {
50+
msgObj.addProperty("timestamp", dateFormat.format(new Date(event.getTimeStamp())));
51+
msgObj.addProperty("level", event.getLevel().toString());
52+
msgObj.addProperty("pid", this.processID);
53+
msgObj.addProperty("threadName", event.getThreadName());
54+
msgObj.addProperty("callerData", event.getCallerData()[1].toString());
55+
56+
return msgObj.toString() + CoreConstants.LINE_SEPARATOR;
57+
} else {
58+
StringBuilder sbuf = new StringBuilder();
59+
60+
if (msgObj.has("exception")) {
61+
JsonArray stackTraceObj = msgObj.get("exception").getAsJsonArray();
62+
sbuf.append(dateFormat.format(new Date(event.getTimeStamp())));
63+
sbuf.append(" | ");
64+
65+
sbuf.append(event.getLevel());
66+
sbuf.append(" | ");
67+
68+
sbuf.append("pid: ");
69+
sbuf.append(this.processID);
70+
sbuf.append(" | ");
71+
72+
sbuf.append("[");
73+
sbuf.append(event.getThreadName());
74+
sbuf.append("] thread");
75+
sbuf.append(" | ");
76+
77+
sbuf.append(event.getCallerData()[1]);
78+
sbuf.append(" | ");
79+
80+
for (JsonElement stackTraceElement : stackTraceObj) {
81+
sbuf.append(stackTraceElement.getAsString());
82+
sbuf.append(CoreConstants.LINE_SEPARATOR);
83+
}
84+
85+
sbuf.append(CoreConstants.LINE_SEPARATOR);
86+
sbuf.append(CoreConstants.LINE_SEPARATOR);
87+
}
88+
89+
sbuf.append(dateFormat.format(new Date(event.getTimeStamp())));
90+
sbuf.append(" | ");
91+
92+
sbuf.append(event.getLevel());
93+
sbuf.append(" | ");
4894

49-
sbuf.append("pid: ");
50-
sbuf.append(this.processID);
51-
sbuf.append(" | ");
95+
sbuf.append("pid: ");
96+
sbuf.append(this.processID);
97+
sbuf.append(" | ");
5298

53-
sbuf.append("[");
54-
sbuf.append(event.getThreadName());
55-
sbuf.append("] thread");
56-
sbuf.append(" | ");
99+
sbuf.append("[");
100+
sbuf.append(event.getThreadName());
101+
sbuf.append("] thread");
102+
sbuf.append(" | ");
57103

58-
sbuf.append(event.getCallerData()[1]);
59-
sbuf.append(" | ");
104+
sbuf.append(event.getCallerData()[1]);
105+
sbuf.append(" | ");
60106

61-
sbuf.append(Utils.maskDBPassword(event.getFormattedMessage()));
62-
sbuf.append(CoreConstants.LINE_SEPARATOR);
63-
sbuf.append(CoreConstants.LINE_SEPARATOR);
107+
sbuf.append(Utils.maskDBPassword(event.getFormattedMessage()));
108+
sbuf.append(CoreConstants.LINE_SEPARATOR);
109+
sbuf.append(CoreConstants.LINE_SEPARATOR);
64110

65-
return sbuf.toString();
111+
return sbuf.toString();
112+
}
66113
}
67114
}

src/main/java/io/supertokens/storage/postgresql/output/Logging.java

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,19 @@
2222
import ch.qos.logback.classic.spi.ILoggingEvent;
2323
import ch.qos.logback.core.ConsoleAppender;
2424
import ch.qos.logback.core.FileAppender;
25+
import com.google.gson.JsonArray;
26+
import com.google.gson.JsonObject;
27+
import com.google.gson.JsonPrimitive;
2528
import io.supertokens.pluginInterface.LOG_LEVEL;
2629
import io.supertokens.storage.postgresql.ResourceDistributor;
2730
import io.supertokens.storage.postgresql.Start;
2831
import io.supertokens.storage.postgresql.config.Config;
2932
import io.supertokens.storage.postgresql.utils.Utils;
3033
import org.slf4j.LoggerFactory;
3134

35+
import java.io.ByteArrayOutputStream;
36+
import java.io.PrintStream;
37+
3238
public class Logging extends ResourceDistributor.SingletonResource {
3339

3440
private static final String RESOURCE_ID = "io.supertokens.storage.postgresql.output.Logging";
@@ -65,24 +71,59 @@ public static void debug(Start start, String msg) {
6571
try {
6672
msg = msg.trim();
6773
if (getInstance(start) != null) {
68-
getInstance(start).infoLogger.debug(msg);
74+
getInstance(start).infoLogger.debug(getFormattedMessage(msg));
6975
}
7076
} catch (NullPointerException ignored) {
7177
}
7278
}
7379

80+
public static String throwableStacktraceToString(Throwable e) {
81+
if (e == null) {
82+
return "";
83+
}
84+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
85+
try (PrintStream ps = new PrintStream(baos)) {
86+
e.printStackTrace(ps);
87+
}
88+
return baos.toString();
89+
}
90+
91+
private static String getFormattedMessage(String msg, Exception e) {
92+
JsonObject msgObj = new JsonObject();
93+
msgObj.addProperty("message", msg);
94+
95+
if (e != null) {
96+
String stackTrace = throwableStacktraceToString(e);
97+
String[] stackTraceArr = stackTrace.split("\n");
98+
JsonArray stackTraceArrObj = new JsonArray();
99+
for (String stackTraceElement : stackTraceArr) {
100+
stackTraceArrObj.add(new JsonPrimitive(stackTraceElement));
101+
}
102+
103+
msgObj.add("exception", stackTraceArrObj);
104+
}
105+
106+
return msgObj.toString();
107+
}
108+
109+
private static String getFormattedMessage(String msg) {
110+
return getFormattedMessage(msg, null);
111+
}
112+
74113
public static void info(Start start, String msg, boolean toConsoleAsWell) {
75114
if (!Config.getLogLevels(start).contains(LOG_LEVEL.INFO)) {
76115
return;
77116
}
78117
try {
79118
msg = msg.trim();
80-
if (getInstance(start) != null) {
81-
getInstance(start).infoLogger.info(msg);
82-
}
83119
if (toConsoleAsWell) {
84120
systemOut(msg);
85121
}
122+
msg = getFormattedMessage(msg);
123+
124+
if (getInstance(start) != null) {
125+
getInstance(start).infoLogger.info(msg);
126+
}
86127
} catch (NullPointerException ignored) {
87128
}
88129
}
@@ -93,6 +134,7 @@ public static void warn(Start start, String msg) {
93134
}
94135
try {
95136
msg = msg.trim();
137+
msg = getFormattedMessage(msg);
96138
if (getInstance(start) != null) {
97139
getInstance(start).errorLogger.warn(msg);
98140
}
@@ -113,7 +155,7 @@ public static void error(Start start, String err, boolean toConsoleAsWell) {
113155
try {
114156
err = err.trim();
115157
if (getInstance(start) != null) {
116-
getInstance(start).errorLogger.error(err);
158+
getInstance(start).errorLogger.error(getFormattedMessage(err));
117159
}
118160
if (toConsoleAsWell || getInstance(start) == null) {
119161
systemErr(err);
@@ -122,7 +164,8 @@ public static void error(Start start, String err, boolean toConsoleAsWell) {
122164
}
123165
}
124166

125-
public static void error(Start start, String message, boolean toConsoleAsWell, Exception e) {
167+
public static void error(Start start, String message, boolean toConsoleAsWell,
168+
Exception e) {
126169
try {
127170
if (!Config.getLogLevels(start).contains(LOG_LEVEL.ERROR)) {
128171
return;
@@ -142,7 +185,7 @@ public static void error(Start start, String message, boolean toConsoleAsWell, E
142185
if (message != null) {
143186
message = message.trim();
144187
if (getInstance(start) != null) {
145-
getInstance(start).errorLogger.error(message);
188+
getInstance(start).errorLogger.error(getFormattedMessage(message, e));
146189
}
147190
if (toConsoleAsWell || getInstance(start) == null) {
148191
systemErr(message);
@@ -220,5 +263,4 @@ private Logger createLoggerForConsole(Start start, String name, LOG_LEVEL logLev
220263

221264
return logger;
222265
}
223-
224266
}

src/main/java/io/supertokens/storage/postgresql/queries/ActiveUsersQueries.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ public static Long getLastActiveByUserId(Start start, AppIdentifier appIdentifie
137137

138138
public static Map<String, Long> getLastActiveByMultipleUserIds(Start start, AppIdentifier appIdentifier, List<String> userIds)
139139
throws StorageQueryException {
140+
if(userIds == null || userIds.isEmpty()) {
141+
return new HashMap<>();
142+
}
140143
String QUERY = "SELECT user_id, last_active_time FROM " + Config.getConfig(start).getUserLastActiveTable()
141144
+ " WHERE app_id = ? AND user_id IN ( " + Utils.generateCommaSeperatedQuestionMarks(userIds.size())+ " )";
142145

src/main/java/io/supertokens/storage/postgresql/queries/EmailPasswordQueries.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ public static List<String> getPrimaryUserIdsUsingMultipleEmails_Transaction(Star
629629
AppIdentifier appIdentifier,
630630
List<String> emails)
631631
throws StorageQueryException, SQLException {
632-
if(emails.isEmpty()){
632+
if(emails == null || emails.isEmpty()){
633633
return new ArrayList<>();
634634
}
635635
String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id "

src/main/java/io/supertokens/storage/postgresql/queries/EmailVerificationQueries.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public UserIdAndEmail(String userId, String email) {
288288
public static List<String> isEmailVerified_transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier,
289289
List<UserIdAndEmail> userIdAndEmail)
290290
throws SQLException, StorageQueryException {
291-
if (userIdAndEmail.isEmpty()) {
291+
if (userIdAndEmail == null || userIdAndEmail.isEmpty()) {
292292
return new ArrayList<>();
293293
}
294294
List<String> emails = new ArrayList<>();
@@ -361,7 +361,7 @@ public static List<String> isEmailVerified(Start start, AppIdentifier appIdentif
361361
List<UserIdAndEmail> userIdAndEmail)
362362
throws SQLException, StorageQueryException {
363363

364-
if (userIdAndEmail.isEmpty()) {
364+
if (userIdAndEmail == null || userIdAndEmail.isEmpty()) {
365365
return new ArrayList<>();
366366
}
367367
List<String> emails = new ArrayList<>();
@@ -515,6 +515,10 @@ public static boolean isUserIdBeingUsedForEmailVerification(Start start, AppIden
515515
public static Set<String> findUserIdsBeingUsedForEmailVerification(Start start, AppIdentifier appIdentifier, List<String> userIds)
516516
throws SQLException, StorageQueryException {
517517

518+
if (userIds == null || userIds.isEmpty()) {
519+
return new HashSet<>();
520+
}
521+
518522
Set<String> foundUserIds = new HashSet<>();
519523

520524
String email_verificiation_tokens_QUERY = "SELECT * FROM " + getConfig(start).getEmailVerificationTokensTable()

src/main/java/io/supertokens/storage/postgresql/queries/GeneralQueries.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,9 @@ public static boolean doesUserIdExist(Start start, TenantIdentifier tenantIdenti
960960

961961
public static List<String> findUserIdsThatExist(Start start, AppIdentifier appIdentifier, List<String> userIds)
962962
throws SQLException, StorageQueryException {
963+
if (userIds == null || userIds.isEmpty()){
964+
return new ArrayList<>();
965+
}
963966
String QUERY = "SELECT user_id FROM " + getConfig(start).getAppIdToUserIdTable()
964967
+ " WHERE app_id = ? AND user_id IN ("+ Utils.generateCommaSeperatedQuestionMarks(userIds.size()) +")";
965968
return execute(start, QUERY, pst -> {
@@ -1736,7 +1739,7 @@ private static List<AuthRecipeUserInfo> getPrimaryUserInfoForUserIds(Start start
17361739
AppIdentifier appIdentifier,
17371740
List<String> userIds)
17381741
throws StorageQueryException, SQLException {
1739-
if (userIds.size() == 0) {
1742+
if (userIds == null || userIds.isEmpty()){
17401743
return new ArrayList<>();
17411744
}
17421745

@@ -1833,7 +1836,7 @@ private static List<AuthRecipeUserInfo> getPrimaryUserInfoForUserIds_Transaction
18331836
AppIdentifier appIdentifier,
18341837
List<String> userIds)
18351838
throws StorageQueryException, SQLException {
1836-
if (userIds.size() == 0) {
1839+
if (userIds == null || userIds.isEmpty()){
18371840
return new ArrayList<>();
18381841
}
18391842

src/main/java/io/supertokens/storage/postgresql/queries/PasswordlessQueries.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ public static PasswordlessCode getCodeByLinkCodeHash(Start start, TenantIdentifi
738738
public static List<LoginMethod> getUsersInfoUsingIdList(Start start, Set<String> ids,
739739
AppIdentifier appIdentifier)
740740
throws SQLException, StorageQueryException {
741-
if (ids.size() > 0) {
741+
if (ids != null && !ids.isEmpty()) {
742742
// No need to filter based on tenantId because the id list is already filtered for a tenant
743743
String QUERY = "SELECT user_id, email, phone_number, time_joined "
744744
+ "FROM " + getConfig(start).getPasswordlessUsersTable() + " WHERE user_id IN (" +
@@ -768,7 +768,7 @@ public static List<LoginMethod> getUsersInfoUsingIdList(Start start, Set<String>
768768
public static List<LoginMethod> getUsersInfoUsingIdList_Transaction(Start start, Connection con, Set<String> ids,
769769
AppIdentifier appIdentifier)
770770
throws SQLException, StorageQueryException {
771-
if (ids.size() > 0) {
771+
if (ids != null && !ids.isEmpty()) {
772772
// No need to filter based on tenantId because the id list is already filtered for a tenant
773773
String QUERY = "SELECT user_id, email, phone_number, time_joined "
774774
+ "FROM " + getConfig(start).getPasswordlessUsersTable() + " WHERE user_id IN (" +
@@ -947,7 +947,7 @@ public static List<String> getPrimaryUserIdsUsingMultipleEmails_Transaction(Star
947947
AppIdentifier appIdentifier,
948948
List<String> emails)
949949
throws StorageQueryException, SQLException {
950-
if(emails.isEmpty()){
950+
if(emails == null || emails.isEmpty()){
951951
return new ArrayList<>();
952952
}
953953
String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id "
@@ -1017,7 +1017,7 @@ public static List<String> listUserIdsByMultiplePhoneNumber_Transaction(Start st
10171017
AppIdentifier appIdentifier,
10181018
@Nonnull List<String> phoneNumbers)
10191019
throws StorageQueryException, SQLException {
1020-
if(phoneNumbers.isEmpty()){
1020+
if(phoneNumbers == null || phoneNumbers.isEmpty()){
10211021
return new ArrayList<>();
10221022
}
10231023
String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id "

0 commit comments

Comments
 (0)