diff --git a/src/main/java/io/supertokens/config/CoreConfig.java b/src/main/java/io/supertokens/config/CoreConfig.java index c2ae95601..6be384eaf 100644 --- a/src/main/java/io/supertokens/config/CoreConfig.java +++ b/src/main/java/io/supertokens/config/CoreConfig.java @@ -27,12 +27,12 @@ import io.supertokens.cliOptions.CLIOptions; import io.supertokens.config.annotations.ConfigDescription; import io.supertokens.config.annotations.ConfigYamlOnly; -import io.supertokens.config.annotations.DifferentAcrossTenants; import io.supertokens.config.annotations.EnumProperty; import io.supertokens.config.annotations.IgnoreForAnnotationCheck; import io.supertokens.config.annotations.NotConflictingInApp; import io.supertokens.pluginInterface.LOG_LEVEL; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; +import io.supertokens.storageLayer.StorageLayer; import io.supertokens.utils.SemVer; import io.supertokens.webserver.Utils; import io.supertokens.webserver.WebserverAPI; @@ -77,37 +77,31 @@ public class CoreConfig { @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("Time in milliseconds for how long a password reset token / link is valid for. [Default: 3600000 (1 hour)]") private long password_reset_token_lifetime = 3600000; // in MS @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("Time in milliseconds for how long an email verification token / link is valid for. [Default: 24 * 3600 * 1000 (1 day)]") private long email_verification_token_lifetime = 24 * 3600 * 1000; // in MS @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("The maximum number of code input attempts per login before the user needs to restart. (Default: 5)") private int passwordless_max_code_input_attempts = 5; @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("Time in milliseconds for how long a passwordless code is valid for. [Default: 900000 (15 mins)]") private long passwordless_code_lifetime = 900000; // in MS @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("The maximum number of invalid TOTP attempts that will trigger rate limiting. (Default: 5)") private int totp_max_attempts = 5; @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("The time in seconds for which the user will be rate limited once totp_max_attempts is crossed. [Default: 900 (15 mins)]") private int totp_rate_limit_cooldown_sec = 900; // in seconds (Default 15 mins) @@ -226,13 +220,11 @@ public class CoreConfig { @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("Regex for allowing requests from IP addresses that match with the value. For example, use the value of 127\\.\\d+\\.\\d+\\.\\d+|::1|0:0:0:0:0:0:0:1 to allow only localhost to query the core") private String ip_allow_regex = null; @IgnoreForAnnotationCheck @JsonProperty - @DifferentAcrossTenants @ConfigDescription("Regex for denying requests from IP addresses that match with the value. Comment this value to deny no IP address.") private String ip_deny_regex = null; @@ -638,6 +630,29 @@ void normalizeAndValidate(Main main, boolean includeConfigFilePath) throws Inval } } + try { + String[] allowedPasswordHashingAlgos = CoreConfig.class.getDeclaredField("password_hashing_alg") + .getAnnotation(EnumProperty.class).value(); + + if (!Arrays.asList(allowedPasswordHashingAlgos).contains(password_hashing_alg)) { + throw new InvalidConfigException("password_hashing_alg property is not set correctly"); + } + } catch (NoSuchFieldException e) { + throw new InvalidConfigException("password_hashing_alg field not found"); + } + + try { + String[] allowedLogLevels = CoreConfig.class.getDeclaredField("log_level") + .getAnnotation(EnumProperty.class).value(); + + if (!Arrays.asList(allowedLogLevels).contains(log_level)) { + throw new InvalidConfigException("log_level property is not set correctly"); + } + } catch (NoSuchFieldException e) { + throw new InvalidConfigException("log_level field not found"); + } + + // Normalize if (ip_allow_regex != null) { ip_allow_regex = ip_allow_regex.trim(); @@ -727,8 +742,8 @@ void normalizeAndValidate(Main main, boolean includeConfigFilePath) throws Inval if (supertokens_saas_load_only_cud != null) { try { - supertokens_saas_load_only_cud = - Utils.normalizeAndValidateConnectionUriDomain(supertokens_saas_load_only_cud, true); + supertokens_saas_load_only_cud = Utils + .normalizeAndValidateConnectionUriDomain(supertokens_saas_load_only_cud, true); } catch (ServletException e) { throw new InvalidConfigException("supertokens_saas_load_only_cud is invalid"); } @@ -779,7 +794,7 @@ static void assertThatCertainConfigIsNotSetForAppOrTenants(JsonObject config) th } } - public static JsonArray getConfigFieldsJson() { + public static JsonArray getConfigFieldsJson(Main main) { JsonArray result = new JsonArray(); for (String fieldId : CoreConfig.getValidFields()) { @@ -797,7 +812,7 @@ public static JsonArray getConfigFieldsJson() { ? field.getAnnotation(ConfigDescription.class).value() : ""); fieldJson.addProperty("isDifferentAcrossTenants", - field.isAnnotationPresent(DifferentAcrossTenants.class)); + !field.isAnnotationPresent(NotConflictingInApp.class)); String type = "string"; @@ -824,6 +839,13 @@ public static JsonArray getConfigFieldsJson() { continue; } } + + JsonArray storageFields = StorageLayer.getBaseStorage(main).getConfigFieldsJson(); + + for (JsonElement field : storageFields) { + result.add(field); + } + return result; } diff --git a/src/main/java/io/supertokens/config/annotations/DifferentAcrossTenants.java b/src/main/java/io/supertokens/config/annotations/DifferentAcrossTenants.java deleted file mode 100644 index 36ac35855..000000000 --- a/src/main/java/io/supertokens/config/annotations/DifferentAcrossTenants.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - - package io.supertokens.config.annotations; - - import java.lang.annotation.ElementType; - import java.lang.annotation.Retention; - import java.lang.annotation.RetentionPolicy; - import java.lang.annotation.Target; - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface DifferentAcrossTenants { - } - \ No newline at end of file diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index 129adee22..2f4a28e54 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -16,6 +16,7 @@ package io.supertokens.inmemorydb; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.ProcessState; @@ -2758,6 +2759,11 @@ public Set getValidFieldsInConfig() { return SQLiteConfig.getValidFields(); } + @Override + public JsonArray getConfigFieldsJson() { + return new JsonArray(); + } + @Override public void setLogLevels(Set logLevels) { Config.setLogLevels(this, logLevels); diff --git a/src/main/java/io/supertokens/webserver/api/core/CoreConfigListAPI.java b/src/main/java/io/supertokens/webserver/api/core/CoreConfigListAPI.java index eb89ee8ad..e0dc3a3fc 100644 --- a/src/main/java/io/supertokens/webserver/api/core/CoreConfigListAPI.java +++ b/src/main/java/io/supertokens/webserver/api/core/CoreConfigListAPI.java @@ -47,7 +47,7 @@ protected boolean checkAPIKey(HttpServletRequest req) { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - JsonArray config = CoreConfig.getConfigFieldsJson(); + JsonArray config = CoreConfig.getConfigFieldsJson(main); JsonObject result = new JsonObject(); result.addProperty("status", "OK"); result.add("config", config);