diff --git a/CHANGELOG.md b/CHANGELOG.md index 81fed96d3..0b9023899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.0.6] - 2023-10-10 + +- normalized input in few methods of InputParser - https://github.com/supertokens/supertokens-core/issues/594 + ## [7.0.5] - 2023-10-13 - Adds postgres testing to the CICD @@ -2513,4 +2517,4 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Changed - Allow for an unlimited number of SuperTokens instances in production mode -- License changes to reflect the above \ No newline at end of file +- License changes to reflect the above diff --git a/build.gradle b/build.gradle index b1a265136..4937651e6 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,7 @@ compileTestJava { options.encoding = "UTF-8" } // } //} -version = "7.0.5" - +version = "7.0.6" repositories { mavenCentral() diff --git a/jar/core-7.0.5.jar b/jar/core-7.0.6.jar similarity index 92% rename from jar/core-7.0.5.jar rename to jar/core-7.0.6.jar index 5d6d6ea77..3787cdfaf 100644 Binary files a/jar/core-7.0.5.jar and b/jar/core-7.0.6.jar differ diff --git a/src/main/java/io/supertokens/webserver/InputParser.java b/src/main/java/io/supertokens/webserver/InputParser.java index ebf1e86ee..1d97329f5 100644 --- a/src/main/java/io/supertokens/webserver/InputParser.java +++ b/src/main/java/io/supertokens/webserver/InputParser.java @@ -29,6 +29,8 @@ import java.util.Arrays; public class InputParser { + private static final String EMAIL_REGEX = "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"; + public static JsonObject parseJsonObjectOrThrowError(HttpServletRequest request) throws ServletException, IOException { StringBuilder sb = new StringBuilder(); @@ -52,23 +54,34 @@ public static String getQueryParamOrThrowError(HttpServletRequest request, Strin throw new ServletException( new WebserverAPI.BadRequestException("Field name '" + fieldName + "' is missing in GET request")); } + + value = value.trim(); + if (value.matches(EMAIL_REGEX)) { + value = value.toLowerCase(); + } return value; } public static String[] getCommaSeparatedStringArrayQueryParamOrThrowError(HttpServletRequest request, String fieldName, boolean nullable) throws ServletException { - String[] value = null; + String[] values = null; // expect val1,val2,val3 and so on... String queryParamValue = getQueryParamOrThrowError(request, fieldName, nullable); if (queryParamValue != null) { - value = Arrays.stream(queryParamValue.trim().split(",")).map(String::trim).filter(s -> !s.equals("")) + values = Arrays.stream(queryParamValue.trim().split(",")).map(String::trim).filter(s -> !s.equals("")) .toArray(String[]::new); } - if (!nullable && value == null) { + if (!nullable && values == null) { throw new ServletException( new WebserverAPI.BadRequestException("Field name '" + fieldName + "' is missing in GET request")); } - return value; + + return Arrays.stream(values).map(value -> { + if (value.matches(EMAIL_REGEX)) { + return value.toLowerCase(); + } + return value; + }).toArray(String[]::new); } public static Integer getIntQueryParamOrThrowError(HttpServletRequest request, String fieldName, boolean nullable) @@ -137,7 +150,12 @@ public static String parseStringOrThrowError(JsonObject element, String fieldNam if (!stringified.contains("\"")) { throw new Exception(); } - return ((JsonObject) element).get(fieldName).getAsString(); + + String s = element.get(fieldName).getAsString().trim(); + if (s.matches(EMAIL_REGEX)) { + s = s.toLowerCase(); + } + return s; } catch (Exception e) { throw new ServletException( new WebserverAPI.BadRequestException("Field name '" + fieldName + "' is invalid in JSON input")); diff --git a/src/test/java/io/supertokens/test/InputParserTest.java b/src/test/java/io/supertokens/test/InputParserTest.java index 40ea78c7c..5c7e276fb 100644 --- a/src/test/java/io/supertokens/test/InputParserTest.java +++ b/src/test/java/io/supertokens/test/InputParserTest.java @@ -21,6 +21,7 @@ import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.webserver.InputParser; +import jakarta.servlet.http.HttpServletRequest; import org.junit.AfterClass; import org.junit.Before; import org.junit.Rule; @@ -30,6 +31,7 @@ import jakarta.servlet.ServletException; import static org.junit.Assert.*; +import static org.mockito.Mockito.*; public class InputParserTest { @Rule @@ -104,4 +106,51 @@ public void testParseStringOrJSONNullOrThrowError() throws Exception { process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } + + @Test + public void testParseStringOrThrowError() throws Exception { + String[] args = { "../" }; + + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + JsonObject json = new JsonObject(); + json.addProperty("untrimed mixedcase email", "userName@DoMaIn.com "); + json.addProperty("email", "username@domain.com"); + json.addProperty("untrimed mixedcase text", " TexT "); + json.addProperty("mixedcase text", "TeXt"); + + assertEquals(InputParser.parseStringOrThrowError(json, "untrimed mixedcase email", false), "username@domain.com"); + assertEquals(InputParser.parseStringOrThrowError(json, "email", false), "username@domain.com"); + assertEquals(InputParser.parseStringOrThrowError(json, "untrimed mixedcase text", false), "TexT"); + assertEquals(InputParser.parseStringOrThrowError(json, "mixedcase text", false), "TeXt"); + assertNull(InputParser.parseStringOrThrowError(json, "undefined", true)); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + + @Test + public void testGetQueryParamOrThrowError() throws Exception { + String[] args = { "../" }; + + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + HttpServletRequest request = mock(HttpServletRequest.class); + + when(request.getParameter("untrimed mixedcase email")).thenReturn("userName@DoMaIn.com "); + when(request.getParameter("email")).thenReturn("username@domain.com"); + when(request.getParameter("untrimed mixedcase text")).thenReturn(" TexT "); + when(request.getParameter("mixedcase text")).thenReturn("TeXt"); + + assertEquals(InputParser.getQueryParamOrThrowError(request, "untrimed mixedcase email", false), "username@domain.com"); + assertEquals(InputParser.getQueryParamOrThrowError(request, "email", false), "username@domain.com"); + assertEquals(InputParser.getQueryParamOrThrowError(request, "untrimed mixedcase text", false), "TexT"); + assertEquals(InputParser.getQueryParamOrThrowError(request, "mixedcase text", false), "TeXt"); + assertThrows(ServletException.class, () -> InputParser.getQueryParamOrThrowError(request, "undefined", false)); + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } }