Skip to content

Commit

Permalink
fix: sem ver and few test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc committed Feb 20, 2025
1 parent e3bcc00 commit 76af6a0
Show file tree
Hide file tree
Showing 29 changed files with 102 additions and 29 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ local.properties
*.iml
ee/bin
addDevTag
addReleaseTag
addReleaseTag

install-linux.sh
install-windows.bat
4 changes: 4 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,7 @@ core_config_version: 0
# (DIFFERENT_ACROSS_APPS | OPTIONAL | Default: number of available processor cores) int value. If specified,
# the supertokens core will use the specified number of threads to complete the migration of users.
# bulk_migration_parallelism:

# (DIFFERENT_ACROSS_APPS | OPTIONAL | Default: 300000) long value. Time in milliseconds for how long a webauthn
# account recovery token is valid for.
# webauthn_recover_account_token_lifetime:
3 changes: 2 additions & 1 deletion coreDriverInterfaceSupported.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"4.0",
"5.0",
"5.1",
"5.2"
"5.2",
"5.3"
]
}
3 changes: 3 additions & 0 deletions devConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,6 @@ disable_telemetry: true
# the supertokens core will use the specified number of threads to complete the migration of users.
# bulk_migration_parallelism:

# (DIFFERENT_ACROSS_APPS | OPTIONAL | Default: 300000) long value. Time in milliseconds for how long a webauthn
# account recovery token is valid for.
# webauthn_recover_account_token_lifetime:
13 changes: 13 additions & 0 deletions src/main/java/io/supertokens/config/CoreConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,11 @@ public class CoreConfig {
"migration of users. (Default: number of available processor cores).")
private int bulk_migration_parallelism = Runtime.getRuntime().availableProcessors();

@NotConflictingInApp
@JsonProperty
@ConfigDescription("Time in milliseconds for how long a webauthn account recovery token is valid for. [Default: 300000 (5 mins)]")
private long webauthn_recover_account_token_lifetime = 300000;

@IgnoreForAnnotationCheck
private static boolean disableOAuthValidationForTest = false;

Expand Down Expand Up @@ -589,6 +594,10 @@ public int getBulkMigrationParallelism() {
return bulk_migration_parallelism;
}

public long getWebauthnRecoverAccountTokenLifetime() {
return webauthn_recover_account_token_lifetime;
}

private String getConfigFileLocation(Main main) {
return new File(CLIOptions.get(main).getConfigFilePath() == null
? CLIOptions.get(main).getInstallationPath() + "config.yaml"
Expand Down Expand Up @@ -786,6 +795,10 @@ void normalizeAndValidate(Main main, boolean includeConfigFilePath) throws Inval
throw new InvalidConfigException("Provided bulk_migration_parallelism must be >= 1");
}

if (webauthn_recover_account_token_lifetime <= 0) {
throw new InvalidConfigException("Provided webauthn_recover_account_token_lifetime must be > 0");
}

for (String fieldId : CoreConfig.getValidFields()) {
try {
Field field = CoreConfig.class.getDeclaredField(fieldId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,45 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant
}
}

{
// check if we should search through the webauthn table
if (dashboardSearchTags.shouldWebauthnTableBeSearched()) {
String QUERY = "SELECT allAuthUsersTable.*" + " FROM " + getConfig(start).getUsersTable()
+ " AS allAuthUsersTable" +
" JOIN " + getConfig(start).getWebAuthNUserToTenantTable()
+ " AS webauthnTable ON allAuthUsersTable.app_id = webauthnTable.app_id AND "
+ "allAuthUsersTable.tenant_id = webauthnTable.tenant_id AND "
+ "allAuthUsersTable.user_id = webauthnTable.user_id";

// attach email tags to queries
QUERY = QUERY +
" WHERE (webauthnTable.app_id = ? AND webauthnTable.tenant_id = ?) AND"
+ " ( webauthnTable.email LIKE ? OR webauthnTable.email LIKE ? ";
queryList.add(tenantIdentifier.getAppId());
queryList.add(tenantIdentifier.getTenantId());
queryList.add(dashboardSearchTags.emails.get(0) + "%");
queryList.add("%@" + dashboardSearchTags.emails.get(0) + "%");
for (int i = 1; i < dashboardSearchTags.emails.size(); i++) {
QUERY += " OR webauthnTable.email LIKE ? OR webauthnTable.email LIKE ?";
queryList.add(dashboardSearchTags.emails.get(i) + "%");
queryList.add("%@" + dashboardSearchTags.emails.get(i) + "%");
}

QUERY += " )";

// check if we need to append this to an existing search query
if (USER_SEARCH_TAG_CONDITION.length() != 0) {
USER_SEARCH_TAG_CONDITION.append(" UNION ").append("SELECT * FROM ( ").append(QUERY)
.append(" LIMIT 1000) AS webauthnResultTable");

} else {
USER_SEARCH_TAG_CONDITION.append("SELECT * FROM ( ").append(QUERY)
.append(" LIMIT 1000) AS webauthnResultTable");

}
}
}

if (USER_SEARCH_TAG_CONDITION.toString().length() == 0) {
usersFromQuery = new ArrayList<>();
} else {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/io/supertokens/utils/SemVer.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class SemVer implements Comparable<SemVer> {
public static final SemVer v5_0 = new SemVer("5.0");
public static final SemVer v5_1 = new SemVer("5.1");
public static final SemVer v5_2 = new SemVer("5.2");
public static final SemVer v5_3 = new SemVer("5.3");

final private String version;

Expand Down
8 changes: 3 additions & 5 deletions src/main/java/io/supertokens/webauthn/WebAuthN.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.webauthn4j.verifier.exception.VerificationException;
import io.supertokens.Main;
import io.supertokens.authRecipe.AuthRecipe;
import io.supertokens.config.Config;
import io.supertokens.pluginInterface.RECIPE_ID;
import io.supertokens.pluginInterface.Storage;
import io.supertokens.pluginInterface.StorageUtils;
Expand All @@ -46,6 +47,7 @@
import io.supertokens.pluginInterface.webauthn.WebAuthNStoredCredential;
import io.supertokens.pluginInterface.webauthn.exceptions.*;
import io.supertokens.pluginInterface.webauthn.slqStorage.WebAuthNSQLStorage;
import io.supertokens.storageLayer.StorageLayer;
import io.supertokens.utils.Utils;
import io.supertokens.webauthn.data.WebAuthNSignInUpResult;
import io.supertokens.webauthn.data.WebauthNCredentialRecord;
Expand Down Expand Up @@ -147,7 +149,6 @@ public static JsonObject generateSignInOptions(TenantIdentifier tenantIdentifier
return WebauthMapper.mapOptionsResponse(relyingPartyId, timeout, userVerification, optionsId, challenge, savedOptions.createdAt, userPresenceRequired);
}


@NotNull
private static Challenge getChallenge() {
Challenge challenge = new Challenge() {
Expand All @@ -171,8 +172,6 @@ public static WebauthNCredentialResponse registerCredentials(Storage storage, Te
throws InvalidWebauthNOptionsException, StorageQueryException, WebauthNVerificationFailedException,
WebauthNInvalidFormatException, WebauthNOptionsNotExistsException {



WebAuthNStorage webAuthNStorage = (WebAuthNStorage) storage;
WebAuthNOptions generatedOptions = webAuthNStorage.loadOptionsById(tenantIdentifier, optionsId);

Expand Down Expand Up @@ -479,7 +478,6 @@ private static WebAuthNOptions saveGeneratedOptions(TenantIdentifier tenantIdent
return webAuthNStorage.saveGeneratedOptions(tenantIdentifier, savableOptions);
}


public static String generateRecoverAccountToken(Main main, Storage storage, TenantIdentifier tenantIdentifier, String email)
throws NoSuchAlgorithmException, InvalidKeySpecException, TenantOrAppNotFoundException,
StorageQueryException {
Expand Down Expand Up @@ -596,7 +594,7 @@ public static AuthRecipeUserInfo getUserForToken(Storage storage, TenantIdentifi

private static long getRecoverAccountTokenLifetime(TenantIdentifier tenantIdentifier, Main main)
throws TenantOrAppNotFoundException {
return 300000; // TODO add config
return Config.getConfig(tenantIdentifier, main).getWebauthnRecoverAccountTokenLifetime();
}

public static void removeCredential(Storage storage, TenantIdentifier tenantIdentifier,
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/io/supertokens/webserver/WebserverAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ public abstract class WebserverAPI extends HttpServlet {
supportedVersions.add(SemVer.v5_0);
supportedVersions.add(SemVer.v5_1);
supportedVersions.add(SemVer.v5_2);
supportedVersions.add(SemVer.v5_3);
}

public static SemVer getLatestCDIVersion() {
return SemVer.v5_2;
return SemVer.v5_3;
}

public SemVer getLatestCDIVersionForRequest(HttpServletRequest req)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.useridmapping.UserIdMapping;
import io.supertokens.useridmapping.UserIdType;
import io.supertokens.utils.SemVer;
import io.supertokens.webserver.InputParser;
import io.supertokens.webserver.WebserverAPI;
import jakarta.servlet.ServletException;
Expand Down Expand Up @@ -85,7 +86,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
} else {
result.user.setExternalUserId(null);
}
response.add("user", result.user.toJson());
response.add("user", result.user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)));
super.sendJsonResponse(200, response, resp);
} catch (StorageQueryException | TenantOrAppNotFoundException | FeatureNotEnabledException |
BadPermissionException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.useridmapping.UserIdMapping;
import io.supertokens.useridmapping.UserIdType;
import io.supertokens.utils.SemVer;
import io.supertokens.webserver.InputParser;
import io.supertokens.webserver.WebserverAPI;
import jakarta.servlet.ServletException;
Expand Down Expand Up @@ -111,7 +112,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
JsonObject response = new JsonObject();
response.addProperty("status", "OK");
response.addProperty("accountsAlreadyLinked", linkAccountsResult.wasAlreadyLinked);
response.add("user", linkAccountsResult.user.toJson());
response.add("user", linkAccountsResult.user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)));

if (!linkAccountsResult.wasAlreadyLinked) {
try {
Expand Down Expand Up @@ -153,7 +154,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
new AuthRecipeUserInfo[]{e.recipeUser});
response.addProperty("primaryUserId", e.recipeUser.getSupertokensOrExternalUserId());
response.addProperty("description", e.getMessage());
response.add("user", e.recipeUser.toJson());
response.add("user", e.recipeUser.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)));
super.sendJsonResponse(200, response, resp);
} catch (StorageQueryException ex) {
throw new ServletException(ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import io.supertokens.pluginInterface.multitenancy.AppIdentifier;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.storageLayer.StorageLayer;
import io.supertokens.utils.SemVer;
import io.supertokens.utils.Utils;
import io.supertokens.webserver.InputParser;
import io.supertokens.webserver.WebserverAPI;
Expand Down Expand Up @@ -85,7 +86,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S

JsonObject result = new JsonObject();
result.addProperty("status", "OK");
result.add("user", importedUser.toJson());
result.add("user", importedUser.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)));
super.sendJsonResponse(200, result, resp);
} catch (BulkImportBatchInsertException e) {
JsonArray errors = new JsonArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.useridmapping.UserIdMapping;
import io.supertokens.useridmapping.UserIdType;
import io.supertokens.utils.SemVer;
import io.supertokens.webserver.InputParser;
import io.supertokens.webserver.WebserverAPI;
import jakarta.servlet.ServletException;
Expand Down Expand Up @@ -86,7 +87,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
} else {
JsonObject result = new JsonObject();
result.addProperty("status", "OK");
JsonObject userJson = user.toJson();
JsonObject userJson = user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3));

result.add("user", userJson);
super.sendJsonResponse(200, result, resp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.supertokens.pluginInterface.multitenancy.TenantIdentifier;
import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException;
import io.supertokens.useridmapping.UserIdMapping;
import io.supertokens.utils.SemVer;
import io.supertokens.utils.Utils;
import io.supertokens.webserver.InputParser;
import io.supertokens.webserver.WebserverAPI;
Expand Down Expand Up @@ -87,7 +88,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
result.addProperty("status", "OK");
JsonArray usersJson = new JsonArray();
for (AuthRecipeUserInfo userInfo : users) {
usersJson.add(userInfo.toJson());
usersJson.add(userInfo.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)));
}

result.add("users", usersJson);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
jsonObj.add("user", userJson);
usersJson.add(jsonObj);
} else {
usersJson.add(user.toJson());
usersJson.add(user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
JsonObject response = new JsonObject();
response.addProperty("status", "OK");
JsonObject userJson =
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? importUserResponse.user.toJson() :
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? importUserResponse.user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
importUserResponse.user.toJsonWithoutAccountLinking();

if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I

JsonObject result = new JsonObject();
result.addProperty("status", "OK");
JsonObject userJson = getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson() :
JsonObject userJson = getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
user.toJsonWithoutAccountLinking();
if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
userJson.remove("tenantIds");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
result.addProperty("status", "OK");
user.setExternalUserId(null);
JsonObject userJson =
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson() :
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
user.toJsonWithoutAccountLinking();

if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
JsonObject result = new JsonObject();
result.addProperty("status", "OK");
JsonObject userJson =
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson() :
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
user.toJsonWithoutAccountLinking();

if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
JsonObject result = new JsonObject();
result.addProperty("status", "OK");
JsonObject userJson =
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? consumeCodeResponse.user.toJson() :
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? consumeCodeResponse.user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
consumeCodeResponse.user.toJsonWithoutAccountLinking();

if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
result.addProperty("status", "OK");

JsonObject userJson =
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson() :
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
user.toJsonWithoutAccountLinking();

if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO
result.addProperty("status", "OK");
JsonArray usersJson = new JsonArray();
for (AuthRecipeUserInfo userInfo : users) {
usersJson.add(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? userInfo.toJson() :
usersJson.add(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? userInfo.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
userInfo.toJsonWithoutAccountLinking());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
result.addProperty("status", "OK");
result.addProperty("createdNewUser", response.createdNewUser);
JsonObject userJson =
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? response.user.toJson() :
getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0) ? response.user.toJson(getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_3)) :
response.user.toJsonWithoutAccountLinking();

if (getVersionFromRequest(req).lesserThan(SemVer.v3_0)) {
Expand Down
Loading

0 comments on commit 76af6a0

Please sign in to comment.