From e1fcd0c48074304982291ae467ef7c7577bca482 Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Tue, 27 Feb 2024 12:45:53 +0530 Subject: [PATCH] Merge 7.0 (#940) * fix: adds test for user pagination from old version (#893) * adding dev-v7.0.15 tag to this commit to ensure building * fix: core config validation (#894) * fix: core config validation * fix: core config validation * fix: PR comments * fix: PR comments * fix: test * fix: startup test * fix: using ConfigMapper * fix: test * fix: config mapper * fix: core config * adding dev-v7.0.16 tag to this commit to ensure building * fix: null handling in config mapper (#897) * fix: core config validation * fix: core config validation * fix: PR comments * fix: PR comments * fix: test * fix: startup test * fix: using ConfigMapper * fix: test * fix: config mapper * fix: core config * fix: null handling * fix: test defaults * adding dev-v7.0.16 tag to this commit to ensure building * Add t4-app in release checklist (#899) * Update README.md * Add Dockerfile for ubuntu 22.04 (#904) * fix: error logs should be printed to StdErr (#918) * fix: Load only cud (#917) * fix: update config and validateAndNormalize * fix: impl * fix: PR comments * fix: cleanup * fix: cleanup * fix: pr comments * fix: pr comments * fix: tests * fix: changelog * fix: 400 error * fix: cuds from db * fix: connection pool issue (#919) * adding dev-v7.0.17 tag to this commit to ensure building * fix: Test fix (#921) * fix: test * fix: tests * adding dev-v7.0.17 tag to this commit to ensure building * fix: CICD tests (#925) * fix: tests * fix: adding retry * fix: kill * fix: typo * fix: cicd * fix: cicd * adding dev-v7.0.17 tag to this commit to ensure building * fix: Vulnerability fix (#928) * fix: updated dependencies * fix: updated dependencies * chore: version and changelog * fix: update impl deps * fix: telemetry data * fix: changelog * fix: cleanup * fix: active user storage * fix: active users storage test * fix: changelog * fix: versions * adding dev-v7.0.18 tag to this commit to ensure building * fix: Cicd tests fix (#932) * fix: CICD fix * fix: test fix * fix: test for mongo * adding dev-v7.0.18 tag to this commit to ensure building * fix: dependencies (#933) * fix: dependency fix * fix: dep fix * adding dev-v7.0.18 tag to this commit to ensure building * fix: dependencies (#934) * adding dev-v7.0.18 tag to this commit to ensure building * fix: 31 days of mau (#936) * fix: MAU computation (#937) * fix: mau * fix: typo * adding dev-v7.0.18 tag to this commit to ensure building * fix: mau related tests (#938) * adding dev-v7.0.18 tag to this commit to ensure building * fix: Tests (#939) * fix: mau related tests * fix: test * adding dev-v7.0.18 tag to this commit to ensure building --------- Co-authored-by: rishabhpoddar Co-authored-by: Ankit Tiwari --- .circleci/Dockerfile-ubuntu22 | 57 ++++ .github/ISSUE_TEMPLATE/release.md | 1 + CHANGELOG.md | 20 ++ README.md | 1 + build.gradle | 10 +- cli/build.gradle | 4 +- cli/implementationDependencies.json | 30 +- cli/jar/cli.jar | Bin 47546 -> 47546 bytes config.yaml | 5 + devConfig.yaml | 4 + downloader/jar/downloader.jar | Bin 15229 -> 15229 bytes ee/build.gradle | 8 +- ee/jar/ee.jar | Bin 14423 -> 14354 bytes .../java/io/supertokens/ee/EEFeatureFlag.java | 32 +- .../java/io/supertokens/ee/test/EETest.java | 2 +- .../ee/test/api/GetFeatureFlagAPITest.java | 4 +- implementationDependencies.json | 66 ++-- jar/{core-7.0.14.jar => core-7.0.18.jar} | Bin 735393 -> 741367 bytes .../java/io/supertokens/config/Config.java | 15 +- .../io/supertokens/config/CoreConfig.java | 41 ++- .../cronjobs/telemetry/Telemetry.java | 59 +++- .../multitenancy/MultitenancyHelper.java | 46 ++- .../java/io/supertokens/output/Logging.java | 7 +- .../storageLayer/StorageLayer.java | 11 +- .../io/supertokens/utils/ConfigMapper.java | 140 +++++++++ .../supertokens/webserver/WebserverAPI.java | 30 +- .../api/multitenancy/BaseCreateOrUpdate.java | 10 + .../api/passwordless/ConsumeCodeAPI.java | 4 + .../test/AuthRecipesParallelTest.java | 94 +++--- .../io/supertokens/test/ConfigMapperTest.java | 296 ++++++++++++++++++ .../io/supertokens/test/ConfigTest2_21.java | 19 ++ .../io/supertokens/test/FeatureFlagTest.java | 12 +- .../io/supertokens/test/PathRouterTest.java | 46 ++- .../io/supertokens/test/StorageLayerTest.java | 2 +- .../io/supertokens/test/TelemetryTest.java | 28 +- .../test/accountlinking/TestGetUserSpeed.java | 55 +++- .../api/UserPaginationTest.java | 44 ++- .../test/dashboard/DashboardTest.java | 8 +- .../test/multitenant/ConfigTest.java | 4 +- .../test/multitenant/LoadOnlyCUDTest.java | 281 +++++++++++++++++ 40 files changed, 1294 insertions(+), 202 deletions(-) create mode 100644 .circleci/Dockerfile-ubuntu22 rename jar/{core-7.0.14.jar => core-7.0.18.jar} (84%) create mode 100644 src/main/java/io/supertokens/utils/ConfigMapper.java create mode 100644 src/test/java/io/supertokens/test/ConfigMapperTest.java create mode 100644 src/test/java/io/supertokens/test/multitenant/LoadOnlyCUDTest.java diff --git a/.circleci/Dockerfile-ubuntu22 b/.circleci/Dockerfile-ubuntu22 new file mode 100644 index 000000000..1f60f940d --- /dev/null +++ b/.circleci/Dockerfile-ubuntu22 @@ -0,0 +1,57 @@ +FROM ubuntu:22.04 + +RUN apt-get update && apt-get upgrade -y + +RUN apt-get install build-essential -y + +RUN echo "mysql-server mysql-server/root_password password root" | debconf-set-selections + +RUN echo "mysql-server mysql-server/root_password_again password root" | debconf-set-selections + +RUN apt install mysql-server -y + +RUN usermod -d /var/lib/mysql/ mysql + +RUN [ -d /var/run/mysqld ] || mkdir -p /var/run/mysqld + +ADD ./runMySQL.sh /runMySQL.sh + +RUN chmod +x /runMySQL.sh + +RUN apt-get install -y git-core + +RUN apt-get install -y wget + +# Install OpenJDK 12 +RUN wget https://download.java.net/java/GA/jdk12.0.2/e482c34c86bd4bf8b56c0b35558996b9/10/GPL/openjdk-12.0.2_linux-x64_bin.tar.gz + +RUN mkdir /usr/java + +RUN mv openjdk-12.0.2_linux-x64_bin.tar.gz /usr/java + +RUN cd /usr/java && tar -xzvf openjdk-12.0.2_linux-x64_bin.tar.gz + +RUN echo 'JAVA_HOME=/usr/java/jdk-12.0.2' >> /etc/profile +RUN echo 'PATH=$PATH:$HOME/bin:$JAVA_HOME/bin' >> /etc/profile + +RUN apt-get install jq -y + +RUN apt-get install curl -y + +RUN apt-get install unzip -y + +# Install OpenJDK 15.0.1 +RUN wget https://download.java.net/java/GA/jdk15.0.1/51f4f36ad4ef43e39d0dfdbaf6549e32/9/GPL/openjdk-15.0.1_linux-x64_bin.tar.gz + +RUN mv openjdk-15.0.1_linux-x64_bin.tar.gz /usr/java + +RUN cd /usr/java && tar -xzvf openjdk-15.0.1_linux-x64_bin.tar.gz + +RUN echo 'JAVA_HOME=/usr/java/jdk-15.0.1' >> /etc/profile +RUN echo 'PATH=$PATH:$HOME/bin:$JAVA_HOME/bin' >> /etc/profile +RUN echo 'export JAVA_HOME' >> /etc/profile +RUN echo 'export JRE_HOME' >> /etc/profile +RUN echo 'export PATH' >> /etc/profile + +RUN update-alternatives --install "/usr/bin/java" "java" "/usr/java/jdk-12.0.2/bin/java" 1 +RUN update-alternatives --install "/usr/bin/javac" "javac" "/usr/java/jdk-12.0.2/bin/javac" 1 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md index 36e7a663b..2afb2131f 100644 --- a/.github/ISSUE_TEMPLATE/release.md +++ b/.github/ISSUE_TEMPLATE/release.md @@ -69,6 +69,7 @@ labels: - [ ] SuperTokens Jackson SAML example update - [ ] Supabase docs - [ ] Capacitor template app: https://github.com/RobSchilderr/capacitor-supertokens-nextjs-turborepo + - [ ] T4 App: https://github.com/timothymiller/t4-app ### 📚 Documentation (test site) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8a84e87b..71b6d5c90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,26 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - TODO - copy once postgres / mysql changelog is done +## [7.0.18] - 2024-02-19 + +- Fixes vulnerabilities in dependencies +- Updates telemetry payload +- Fixes Active User tracking to use the right storage + +## [7.0.17] - 2024-02-06 + +- Fixes issue where error logs were printed to StdOut instead of StdErr. +- Adds new config `supertokens_saas_load_only_cud` that makes the core instance load a particular CUD only, irrespective of the CUDs present in the db. +- Fixes connection pool handling when connection pool size changes for a tenant. + +## [7.0.16] - 2023-12-04 + +- Returns 400, instead of 500, for badly typed core config while creating CUD, App or Tenant + +## [7.0.15] - 2023-11-28 + +- Adds test for user pagination from old version + ## [7.0.14] - 2023-11-21 - Updates test user query speed diff --git a/README.md b/README.md index 4ad80fde7..4a96a5bb2 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,7 @@ Melvyn Hills Melvyn Hills
Cléo Rebert

Daniil Borovoy
+
Krzysztof Witkowski
diff --git a/build.gradle b/build.gradle index 3722d4d2d..806add897 100644 --- a/build.gradle +++ b/build.gradle @@ -33,22 +33,22 @@ dependencies { implementation group: 'com.google.code.gson', name: 'gson', version: '2.3.1' // https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml - implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.0' + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.16.1' // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core - implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.0' + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.16.1' // https://mvnrepository.com/artifact/ch.qos.logback/logback-classic - implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' + implementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.4.14' // https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core - implementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '10.1.1' + implementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '10.1.18' // https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305 implementation group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' // https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc - implementation group: 'org.xerial', name: 'sqlite-jdbc', version: '3.30.1' + implementation group: 'org.xerial', name: 'sqlite-jdbc', version: '3.45.1.0' // https://mvnrepository.com/artifact/org.mindrot/jbcrypt implementation group: 'org.mindrot', name: 'jbcrypt', version: '0.4' diff --git a/cli/build.gradle b/cli/build.gradle index 904dc0065..52e2ab2d5 100644 --- a/cli/build.gradle +++ b/cli/build.gradle @@ -19,10 +19,10 @@ dependencies { implementation group: 'com.google.code.gson', name: 'gson', version: '2.3.1' // https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml - implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.10.0' + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.16.1' // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core - implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.0' + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.16.1' // https://mvnrepository.com/artifact/de.mkammerer/argon2-jvm implementation group: 'de.mkammerer', name: 'argon2-jvm', version: '2.11' diff --git a/cli/implementationDependencies.json b/cli/implementationDependencies.json index 645cacaf4..665c92fff 100644 --- a/cli/implementationDependencies.json +++ b/cli/implementationDependencies.json @@ -7,29 +7,29 @@ "src": "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.3.1/gson-2.3.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.10.0/jackson-dataformat-yaml-2.10.0.jar", - "name": "Jackson Dataformat 2.10.0", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.10.0/jackson-dataformat-yaml-2.10.0-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.16.1/jackson-dataformat-yaml-2.16.1.jar", + "name": "Jackson Dataformat 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.16.1/jackson-dataformat-yaml-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/1.24/snakeyaml-1.24.jar", - "name": "SnakeYAML 1.24", - "src": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/1.24/snakeyaml-1.24-sources.jar" + "jar": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/2.2/snakeyaml-2.2.jar", + "name": "SnakeYAML 2.2", + "src": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/2.2/snakeyaml-2.2-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.0/jackson-core-2.10.0.jar", - "name": "Jackson core 2.10.0", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.10.0/jackson-core-2.10.0-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.16.1/jackson-core-2.16.1.jar", + "name": "Jackson core 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.16.1/jackson-core-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.0/jackson-databind-2.10.0.jar", - "name": "Jackson databind 2.10.0", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.10.0/jackson-databind-2.10.0-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.16.1/jackson-databind-2.16.1.jar", + "name": "Jackson databind 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.16.1/jackson-databind-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.0/jackson-annotations-2.10.0.jar", - "name": "Jackson annotation 2.10.0", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.10.0/jackson-annotations-2.10.0-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.16.1/jackson-annotations-2.16.1.jar", + "name": "Jackson annotation 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.16.1/jackson-annotations-2.16.1-sources.jar" }, { "jar": "https://repo1.maven.org/maven2/de/mkammerer/argon2-jvm/2.11/argon2-jvm-2.11.jar", diff --git a/cli/jar/cli.jar b/cli/jar/cli.jar index a740872477e73ab59b7d12533cb86407488d7956..679236a42d96bb6b860fc324648613cc7ff56934 100644 GIT binary patch delta 988 zcmdn>nQ7N&CcXe~W)?061`ZAe&G6`miF~RoVA|YM9Yiw#0TYM-0%jo2%-3gTK-02Z z8=~c!KA4`&$!G^=Z1!fH%nA_-4mO$`$IdZXhMfl@rNf>o29cU7>jDwFE8D;e5lYl{ zh6t_D-o*tGN;C6^2<uYxdMuMdMTTsP!E7+W_$t>N7WwWe}oDn#nh#&ih7cT*sQ zv1k+23SXebN}Hh;$8Ls-9^UK@QOCChYDD=KsC^f=ctWJ)wnjl1HCv&cc(N7hEvs#z z5UI)Apyu4$21(nQ7N&CcXe~W)?061`ZB}rofu;iF~RoVA|YM9Yiw#0TYM-0%jo2%-3gTK-02Z z8=~c!KA4`&$!G^=Z1!fH%nA_-4mO$`$IdZXhMfl@rNf>o29cU7>jDwFE8D;e5lYl{ zh6t_D-o*tGN;C6^2<uYxdMuMdMTTsP!E7+W_$t>N7WwWe}oDn#nh#&ih7cT*sQ zv1k+23SXebN}Hh;$8Ls-9^UK@QOCChYDD=KsC^f=ctWJ)wnjl1HCv&cc(N7hEvs#z z5UI)Apyu4$21(5YHw!SXU<0!z?_qZm0+}+SQF6m?76yhLoD2-M43iDbWhVET@l1YaCcfF9gOwGg zSZlJcInU%iULJ@!^LTG?L0DB1y-W}mw{#_hHMv995h8R}b{bSNUEvs%WvJZB4VIm} zOV0tK?4KShR42Qk9Yn~}u!bQw9gz?V=A~)H=R2L#rXle;ztTT0iFus|_Kp0_W z0T9M2vvdeU)Ep|3X`ToXIcJ^?Vc1$kLKw3w{2`3D7MT!6lqJ-_U6y_j5gscjBhD%V OB67;g2f~oDP6hy@)_-vT delta 440 zcmexc_P2~Lz?+$ci-CcIgP|p`CVV2FDhrr4_f!Yb3_!pHB7lGyh%@u`nHkWuEZ2r; zxn>5YHw!SXU<0!z?_qZm0+}+SQF6m?76yhLoD2-M43iDbWhVET@l1YaCcfF9gOwGg zSZlJcInU%iULJ@!^LTG?L0DB1y-W}mw{#_hHMv995h8R}b{bSNUEvs%WvJZB4VIm} zOV0tK?4KShR42Qk9Yn~}u!bQw9gz?V=A~)H=R2L#rXle;ztTT0iFus|_Kp0_W z0T9M2vvdeU)Ep|3X`ToXIcJ^?Vc1$kLKw3w{2`3D7MT!6lqJ-_U6y_j5gscjBhD%V OB67;g2f~oDP6hxpP?13Z diff --git a/ee/build.gradle b/ee/build.gradle index 94aeed97c..9e91d7a57 100644 --- a/ee/build.gradle +++ b/ee/build.gradle @@ -35,10 +35,10 @@ dependencies { testImplementation group: 'org.mockito', name: 'mockito-core', version: '3.1.0' // https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core - testImplementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '10.1.1' + testImplementation group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '10.1.18' // https://mvnrepository.com/artifact/ch.qos.logback/logback-classic - testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3' + testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.4.14' // https://mvnrepository.com/artifact/com.google.code.gson/gson testImplementation group: 'com.google.code.gson', name: 'gson', version: '2.3.1' @@ -46,10 +46,10 @@ dependencies { testImplementation 'com.tngtech.archunit:archunit-junit4:0.22.0' // https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml - testImplementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.0' + testImplementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.16.1' // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core - testImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.0' + testImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.16.1' testImplementation group: 'org.jetbrains', name: 'annotations', version: '13.0' } diff --git a/ee/jar/ee.jar b/ee/jar/ee.jar index f12f374dcc61765d97bf33876d5f716085b369c5..1795fb9d7da6f103fd23eae9443988ffa676ff66 100644 GIT binary patch delta 11387 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 Ag8%>k delta 11463 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 bNdNWa@)AI0|Jx^(`p%06OUV7NF8Tie#K-rY diff --git a/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java b/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java index 79af8d666..cac2c5cb9 100644 --- a/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java +++ b/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java @@ -200,17 +200,18 @@ private JsonObject getMFAStats() throws StorageQueryException, TenantOrAppNotFou Storage[] storages = StorageLayer.getStoragesForApp(main, this.appIdentifier); int totalUserCountWithMoreThanOneLoginMethod = 0; - int[] maus = new int[30]; + int[] maus = new int[31]; long now = System.currentTimeMillis(); - long today = now - (now % (24 * 60 * 60 * 1000L)); for (Storage storage : storages) { totalUserCountWithMoreThanOneLoginMethod += ((AuthRecipeStorage)storage).getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(this.appIdentifier); - for (int i = 0; i < 30; i++) { - long timestamp = today - (i * 24 * 60 * 60 * 1000L); - maus[i] += ((ActiveUsersStorage)storage).countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(appIdentifier, timestamp); + for (int i = 1; i <= 31; i++) { + long timestamp = now - (i * 24 * 60 * 60 * 1000L); + + // `maus[i-1]` since i starts from 1 + maus[i-1] += ((ActiveUsersStorage)storage).countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(appIdentifier, timestamp); } } @@ -283,7 +284,7 @@ private JsonObject getAccountLinkingStats() throws StorageQueryException { if (!usesAccountLinking) { result.addProperty("totalUserCountWithMoreThanOneLoginMethod", 0); JsonArray mauArray = new JsonArray(); - for (int i = 0; i < 30; i++) { + for (int i = 0; i < 31; i++) { mauArray.add(new JsonPrimitive(0)); } result.add("mauWithMoreThanOneLoginMethod", mauArray); @@ -291,17 +292,18 @@ private JsonObject getAccountLinkingStats() throws StorageQueryException { } int totalUserCountWithMoreThanOneLoginMethod = 0; - int[] maus = new int[30]; + int[] maus = new int[31]; long now = System.currentTimeMillis(); - long today = now - (now % (24 * 60 * 60 * 1000L)); for (Storage storage : storages) { totalUserCountWithMoreThanOneLoginMethod += ((AuthRecipeStorage)storage).getUsersCountWithMoreThanOneLoginMethod(this.appIdentifier); - for (int i = 0; i < 30; i++) { - long timestamp = today - (i * 24 * 60 * 60 * 1000L); - maus[i] += ((ActiveUsersStorage)storage).countUsersThatHaveMoreThanOneLoginMethodAndActiveSince(appIdentifier, timestamp); + for (int i = 1; i <= 31; i++) { + long timestamp = now - (i * 24 * 60 * 60 * 1000L); + + // `maus[i-1]` because i starts from 1 + maus[i-1] += ((ActiveUsersStorage)storage).countUsersThatHaveMoreThanOneLoginMethodAndActiveSince(appIdentifier, timestamp); } } @@ -312,10 +314,10 @@ private JsonObject getAccountLinkingStats() throws StorageQueryException { private JsonArray getMAUs() throws StorageQueryException, TenantOrAppNotFoundException { JsonArray mauArr = new JsonArray(); - for (int i = 0; i < 30; i++) { - long now = System.currentTimeMillis(); - long today = now - (now % (24 * 60 * 60 * 1000L)); - long timestamp = today - (i * 24 * 60 * 60 * 1000L); + long now = System.currentTimeMillis(); + + for (int i = 1; i <= 31; i++) { + long timestamp = now - (i * 24 * 60 * 60 * 1000L); ActiveUsersStorage activeUsersStorage = (ActiveUsersStorage) StorageLayer.getStorage( this.appIdentifier.getAsPublicTenantIdentifier(), main); int mau = activeUsersStorage.countUsersActiveSince(this.appIdentifier, timestamp); diff --git a/ee/src/test/java/io/supertokens/ee/test/EETest.java b/ee/src/test/java/io/supertokens/ee/test/EETest.java index 3a896b253..7418b24ec 100644 --- a/ee/src/test/java/io/supertokens/ee/test/EETest.java +++ b/ee/src/test/java/io/supertokens/ee/test/EETest.java @@ -1326,7 +1326,7 @@ protected URLConnection openConnection(URL u) { JsonObject paidFeatureUsageStats = j.getAsJsonObject("paidFeatureUsageStats"); JsonArray mauArr = paidFeatureUsageStats.get("maus").getAsJsonArray(); assertEquals(paidFeatureUsageStats.entrySet().size(), 1); - assertEquals(mauArr.size(), 30); + assertEquals(mauArr.size(), 31); assertEquals(mauArr.get(0).getAsInt(), 0); assertEquals(mauArr.get(29).getAsInt(), 0); } diff --git a/ee/src/test/java/io/supertokens/ee/test/api/GetFeatureFlagAPITest.java b/ee/src/test/java/io/supertokens/ee/test/api/GetFeatureFlagAPITest.java index d2932f619..efd133a86 100644 --- a/ee/src/test/java/io/supertokens/ee/test/api/GetFeatureFlagAPITest.java +++ b/ee/src/test/java/io/supertokens/ee/test/api/GetFeatureFlagAPITest.java @@ -54,7 +54,7 @@ public void testRetrievingFeatureFlagInfoWhenNoLicenseKeyIsSet() throws Exceptio if (StorageLayer.getStorage(process.getProcess()).getType() == STORAGE_TYPE.SQL) { JsonArray mauArr = usageStats.get("maus").getAsJsonArray(); assertEquals(1, usageStats.entrySet().size()); - assertEquals(30, mauArr.size()); + assertEquals(31, mauArr.size()); assertEquals(0, mauArr.get(0).getAsInt()); assertEquals(0, mauArr.get(29).getAsInt()); } else { @@ -92,7 +92,7 @@ public void testRetrievingFeatureFlagInfoWhenLicenseKeyIsSet() throws Exception if (StorageLayer.getStorage(process.getProcess()).getType() == STORAGE_TYPE.SQL) { JsonArray mauArr = usageStats.get("maus").getAsJsonArray(); assertEquals(1, usageStats.entrySet().size()); - assertEquals(30, mauArr.size()); + assertEquals(31, mauArr.size()); assertEquals(0, mauArr.get(0).getAsInt()); assertEquals(0, mauArr.get(29).getAsInt()); } else { diff --git a/implementationDependencies.json b/implementationDependencies.json index e0ab94e68..ec4da266a 100644 --- a/implementationDependencies.json +++ b/implementationDependencies.json @@ -7,54 +7,54 @@ "src": "https://repo1.maven.org/maven2/com/google/code/gson/gson/2.3.1/gson-2.3.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.14.2/jackson-dataformat-yaml-2.14.2.jar", - "name": "Jackson Dataformat 2.14.2", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.14.2/jackson-dataformat-yaml-2.14.2-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.16.1/jackson-dataformat-yaml-2.16.1.jar", + "name": "Jackson Dataformat 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-yaml/2.16.1/jackson-dataformat-yaml-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar", - "name": "SnakeYAML 1.33", - "src": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/1.33/snakeyaml-1.33-sources.jar" + "jar": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/2.2/snakeyaml-2.2.jar", + "name": "SnakeYAML 2.2", + "src": "https://repo1.maven.org/maven2/org/yaml/snakeyaml/2.2/snakeyaml-2.2-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.14.2/jackson-core-2.14.2.jar", - "name": "Jackson core 2.14.2", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.14.2/jackson-core-2.14.2-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.16.1/jackson-core-2.16.1.jar", + "name": "Jackson core 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.16.1/jackson-core-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.14.2/jackson-databind-2.14.2.jar", - "name": "Jackson databind 2.14.2", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.14.2/jackson-databind-2.14.2-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.16.1/jackson-databind-2.16.1.jar", + "name": "Jackson databind 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.16.1/jackson-databind-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.14.2/jackson-annotations-2.14.2.jar", - "name": "Jackson annotation 2.14.2", - "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.14.2/jackson-annotations-2.14.2-sources.jar" + "jar": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.16.1/jackson-annotations-2.16.1.jar", + "name": "Jackson annotation 2.16.1", + "src": "https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.16.1/jackson-annotations-2.16.1-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar", - "name": "Logback classic 1.2.3", - "src": "https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3-sources.jar" + "jar": "https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.4.14/logback-classic-1.4.14.jar", + "name": "Logback classic 1.4.14", + "src": "https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.4.14/logback-classic-1.4.14-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar", - "name": "Logback core 1.2.3", - "src": "https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3-sources.jar" + "jar": "https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.4.14/logback-core-1.4.14.jar", + "name": "Logback core 1.4.14", + "src": "https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.4.14/logback-core-1.4.14-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar", - "name": "SLF4j API 1.7.25", - "src": "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25-sources.jar" + "jar": "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.jar", + "name": "SLF4j API 2.0.7", + "src": "https://repo1.maven.org/maven2/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.1/tomcat-annotations-api-10.1.1.jar", - "name": "Tomcat annotations API 10.1.1", - "src": "https://repo1.maven.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.1/tomcat-annotations-api-10.1.1-sources.jar" + "jar": "https://repo1.maven.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.18/tomcat-annotations-api-10.1.18.jar", + "name": "Tomcat annotations API 10.1.18", + "src": "https://repo1.maven.org/maven2/org/apache/tomcat/tomcat-annotations-api/10.1.18/tomcat-annotations-api-10.1.18-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.1/tomcat-embed-core-10.1.1.jar", + "jar": "https://repo1.maven.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.18/tomcat-embed-core-10.1.18.jar", "name": "Tomcat embed core API 10.1.1", - "src": "https://repo1.maven.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.1/tomcat-embed-core-10.1.1-sources.jar" + "src": "https://repo1.maven.org/maven2/org/apache/tomcat/embed/tomcat-embed-core/10.1.18/tomcat-embed-core-10.1.18-sources.jar" }, { "jar": "https://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar", @@ -67,13 +67,13 @@ "src": "https://repo1.maven.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar" }, { - "jar": "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.30.1/sqlite-jdbc-3.30.1.jar", - "name": "SQLite JDBC Driver 3.30.1", - "src": "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.30.1/sqlite-jdbc-3.30.1-sources.jar" + "jar": "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar", + "name": "SQLite JDBC Driver 3.45.1.0", + "src": "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0-sources.jar" }, { "jar": "https://repo1.maven.org/maven2/org/mindrot/jbcrypt/0.4/jbcrypt-0.4.jar", - "name": "SQLite JDBC Driver 3.30.1", + "name": "JBCrypt 0.4", "src": "https://repo1.maven.org/maven2/org/mindrot/jbcrypt/0.4/jbcrypt-0.4-sources.jar" }, { diff --git a/jar/core-7.0.14.jar b/jar/core-7.0.18.jar similarity index 84% rename from jar/core-7.0.14.jar rename to jar/core-7.0.18.jar index ee63b514bef9ed441c79984e013fb11e8d330ffd..4d06956121308ef1f7265c61fc219b87b0571773 100644 GIT binary patch delta 90865 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 wjEaI&EL!A{d$Ci_@% delta 84915 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 M3Ireaz?4Yve+-s`d;kCd diff --git a/src/main/java/io/supertokens/config/Config.java b/src/main/java/io/supertokens/config/Config.java index 042af8c9f..a51b8bd1d 100644 --- a/src/main/java/io/supertokens/config/Config.java +++ b/src/main/java/io/supertokens/config/Config.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.ProcessState; @@ -31,6 +32,7 @@ import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; +import io.supertokens.utils.ConfigMapper; import org.jetbrains.annotations.TestOnly; import java.io.File; @@ -49,16 +51,17 @@ public class Config extends ResourceDistributor.SingletonResource { private Config(Main main, String configFilePath) throws InvalidConfigException, IOException { this.main = main; final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - CoreConfig config = mapper.readValue(new File(configFilePath), CoreConfig.class); - config.normalizeAndValidate(main); + Object configObj = mapper.readValue(new File(configFilePath), Object.class); + JsonObject jsonConfig = new GsonBuilder().serializeNulls().create().toJsonTree(configObj).getAsJsonObject(); + CoreConfig config = ConfigMapper.mapConfig(jsonConfig, CoreConfig.class); + config.normalizeAndValidate(main, true); this.core = config; } private Config(Main main, JsonObject jsonConfig) throws IOException, InvalidConfigException { this.main = main; - final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - CoreConfig config = mapper.readValue(jsonConfig.toString(), CoreConfig.class); - config.normalizeAndValidate(main); + CoreConfig config = ConfigMapper.mapConfig(jsonConfig, CoreConfig.class); + config.normalizeAndValidate(main, false); this.core = config; } @@ -89,7 +92,7 @@ public static JsonObject getBaseConfigAsJsonObject(Main main) throws IOException // omit them from the output json. ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory()); Object obj = yamlReader.readValue(new File(getConfigFilePath(main)), Object.class); - return new Gson().toJsonTree(obj).getAsJsonObject(); + return new GsonBuilder().serializeNulls().create().toJsonTree(obj).getAsJsonObject(); } private static String getConfigFilePath(Main main) { diff --git a/src/main/java/io/supertokens/config/CoreConfig.java b/src/main/java/io/supertokens/config/CoreConfig.java index e02fadb4d..3de06caa7 100644 --- a/src/main/java/io/supertokens/config/CoreConfig.java +++ b/src/main/java/io/supertokens/config/CoreConfig.java @@ -30,7 +30,9 @@ import io.supertokens.pluginInterface.LOG_LEVEL; import io.supertokens.pluginInterface.exceptions.InvalidConfigException; import io.supertokens.utils.SemVer; +import io.supertokens.webserver.Utils; import io.supertokens.webserver.WebserverAPI; +import jakarta.servlet.ServletException; import org.apache.catalina.filters.RemoteAddrFilter; import org.jetbrains.annotations.TestOnly; @@ -197,6 +199,10 @@ public class CoreConfig { @JsonProperty private String supertokens_max_cdi_version = null; + @ConfigYamlOnly + @JsonProperty + private String supertokens_saas_load_only_cud = null; + @IgnoreForAnnotationCheck private Set allowedLogLevels = null; @@ -254,6 +260,10 @@ public String getBasePath() { return base_path; } + public String getSuperTokensLoadOnlyCUD() { + return supertokens_saas_load_only_cud; + } + public enum PASSWORD_HASHING_ALG { ARGON2, BCRYPT, FIREBASE_SCRYPT } @@ -394,7 +404,7 @@ private String getConfigFileLocation(Main main) { : CLIOptions.get(main).getConfigFilePath()).getAbsolutePath(); } - void normalizeAndValidate(Main main) throws InvalidConfigException { + void normalizeAndValidate(Main main, boolean includeConfigFilePath) throws InvalidConfigException { if (isNormalizedAndValid) { return; } @@ -407,8 +417,9 @@ void normalizeAndValidate(Main main) throws InvalidConfigException { } if (access_token_validity < 1 || access_token_validity > 86400000) { throw new InvalidConfigException( - "'access_token_validity' must be between 1 and 86400000 seconds inclusive. The config file can be" - + " found here: " + getConfigFileLocation(main)); + "'access_token_validity' must be between 1 and 86400000 seconds inclusive." + + (includeConfigFilePath ? " The config file can be" + + " found here: " + getConfigFileLocation(main) : "")); } Boolean validityTesting = CoreConfigTestContent.getInstance(main) .getValue(CoreConfigTestContent.VALIDITY_TESTING); @@ -417,16 +428,18 @@ void normalizeAndValidate(Main main) throws InvalidConfigException { if ((refresh_token_validity * 60) <= access_token_validity) { if (!Main.isTesting || validityTesting) { throw new InvalidConfigException( - "'refresh_token_validity' must be strictly greater than 'access_token_validity'. The config " - + "file can be found here: " + getConfigFileLocation(main)); + "'refresh_token_validity' must be strictly greater than 'access_token_validity'." + + (includeConfigFilePath ? " The config file can be" + + " found here: " + getConfigFileLocation(main) : "")); } } if (!Main.isTesting || validityTesting) { // since in testing we make this really small if (access_token_dynamic_signing_key_update_interval < 1) { throw new InvalidConfigException( - "'access_token_dynamic_signing_key_update_interval' must be greater than, equal to 1 hour. The " - + "config file can be found here: " + getConfigFileLocation(main)); + "'access_token_dynamic_signing_key_update_interval' must be greater than, equal to 1 hour." + + (includeConfigFilePath ? " The config file can be" + + " found here: " + getConfigFileLocation(main) : "")); } } @@ -456,8 +469,9 @@ void normalizeAndValidate(Main main) throws InvalidConfigException { if (max_server_pool_size <= 0) { throw new InvalidConfigException( - "'max_server_pool_size' must be >= 1. The config file can be found here: " - + getConfigFileLocation(main)); + "'max_server_pool_size' must be >= 1." + + (includeConfigFilePath ? " The config file can be" + + " found here: " + getConfigFileLocation(main) : "")); } if (api_keys != null) { @@ -663,6 +677,15 @@ void normalizeAndValidate(Main main) throws InvalidConfigException { host = cliHost; } + if (supertokens_saas_load_only_cud != null) { + try { + 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"); + } + } + access_token_validity = access_token_validity * 1000; access_token_dynamic_signing_key_update_interval = access_token_dynamic_signing_key_update_interval * 3600 * 1000; refresh_token_validity = refresh_token_validity * 60 * 1000; diff --git a/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java b/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java index 727d2f5ec..215024858 100644 --- a/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java +++ b/src/main/java/io/supertokens/cronjobs/telemetry/Telemetry.java @@ -16,20 +16,26 @@ package io.supertokens.cronjobs.telemetry; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import io.supertokens.Main; import io.supertokens.ProcessState; +import io.supertokens.authRecipe.AuthRecipe; import io.supertokens.config.Config; import io.supertokens.cronjobs.CronTask; import io.supertokens.cronjobs.CronTaskTest; +import io.supertokens.dashboard.Dashboard; import io.supertokens.httpRequest.HttpRequest; import io.supertokens.httpRequest.HttpRequestMocking; import io.supertokens.pluginInterface.ActiveUsersStorage; import io.supertokens.pluginInterface.KeyValueInfo; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.dashboard.DashboardUser; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; +import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.storageLayer.StorageLayer; @@ -90,14 +96,55 @@ protected void doTaskPerApp(AppIdentifier app) throws Exception { json.addProperty("telemetryId", telemetryId.value); json.addProperty("superTokensVersion", coreVersion); + json.addProperty("appId", app.getAppId()); + json.addProperty("connectionUriDomain", app.getConnectionUriDomain()); + if (StorageLayer.getBaseStorage(main).getType() == STORAGE_TYPE.SQL) { - ActiveUsersStorage activeUsersStorage = (ActiveUsersStorage) StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main); - json.addProperty("mau", activeUsersStorage.countUsersActiveSince(app, System.currentTimeMillis() - 30 * 24 * 3600 * 1000L)); + { // Users count across all tenants + Storage[] storages = StorageLayer.getStoragesForApp(main, app); + AppIdentifierWithStorage appIdentifierWithAllTenantStorages = new AppIdentifierWithStorage( + app.getConnectionUriDomain(), app.getAppId(), + StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main), storages + ); + + json.addProperty("usersCount", + AuthRecipe.getUsersCountAcrossAllTenants(appIdentifierWithAllTenantStorages, null)); + } + + { // Dashboard user emails + // Dashboard APIs are app specific and are always stored on the public tenant + DashboardUser[] dashboardUsers = Dashboard.getAllDashboardUsers( + app.withStorage(StorageLayer.getStorage(app.getAsPublicTenantIdentifier(), main)), main); + JsonArray dashboardUserEmails = new JsonArray(); + for (DashboardUser user : dashboardUsers) { + dashboardUserEmails.add(new JsonPrimitive(user.email)); + } + + json.add("dashboardUserEmails", dashboardUserEmails); + } + + { // MAUs + // Active users are always tracked on the public tenant, so we use the public tenant's storage + ActiveUsersStorage activeUsersStorage = (ActiveUsersStorage) StorageLayer.getStorage( + app.getAsPublicTenantIdentifier(), main); + + JsonArray mauArr = new JsonArray(); + + long now = System.currentTimeMillis(); + + for (int i = 1; i <= 31; i++) { + long timestamp = now - (i * 24 * 60 * 60 * 1000L); + int mau = activeUsersStorage.countUsersActiveSince(app, timestamp); + mauArr.add(new JsonPrimitive(mau)); + } + + json.add("maus", mauArr); + } } else { - json.addProperty("mau", -1); + json.addProperty("usersCount", -1); + json.add("dashboardUserEmails", new JsonArray()); + json.add("maus", new JsonArray()); } - json.addProperty("appId", app.getAppId()); - json.addProperty("connectionUriDomain", app.getConnectionUriDomain()); String url = "https://api.supertokens.io/0/st/telemetry"; @@ -105,7 +152,7 @@ protected void doTaskPerApp(AppIdentifier app) throws Exception { // wants // to use this) if (!Main.isTesting || HttpRequestMocking.getInstance(main).getMockURL(REQUEST_ID, url) != null) { - HttpRequest.sendJsonPOSTRequest(main, REQUEST_ID, url, json, 10000, 10000, 4); + HttpRequest.sendJsonPOSTRequest(main, REQUEST_ID, url, json, 10000, 10000, 5); ProcessState.getInstance(main).addState(ProcessState.PROCESS_STATE.SENT_TELEMETRY, null); } } diff --git a/src/main/java/io/supertokens/multitenancy/MultitenancyHelper.java b/src/main/java/io/supertokens/multitenancy/MultitenancyHelper.java index 24f1f0e7c..63a5cd7b3 100644 --- a/src/main/java/io/supertokens/multitenancy/MultitenancyHelper.java +++ b/src/main/java/io/supertokens/multitenancy/MultitenancyHelper.java @@ -51,9 +51,20 @@ public class MultitenancyHelper extends ResourceDistributor.SingletonResource { private Main main; private TenantConfig[] tenantConfigs; + // when the core has `supertokens_saas_load_only_cud` set, the tenantConfigs array will be filtered + // based on the config value. However, we need to keep all the list of CUDs from the db to be able + // to check if the CUD is present in the DB or not, while processing the requests. + private final Set dangerous_allCUDsFromDb = new HashSet<>(); + private MultitenancyHelper(Main main) throws StorageQueryException { this.main = main; - this.tenantConfigs = getAllTenantsFromDb(); + TenantConfig[] allTenantsFromDb = getAllTenantsFromDb(); + this.tenantConfigs = this.getFilteredTenantConfigs(allTenantsFromDb); + this.dangerous_allCUDsFromDb.clear(); + + for (TenantConfig config : allTenantsFromDb) { + this.dangerous_allCUDsFromDb.add(config.tenantIdentifier.getConnectionUriDomain()); + } } public static MultitenancyHelper getInstance(Main main) { @@ -109,10 +120,11 @@ public List refreshTenantsInCoreBasedOnChangesInCoreConfigOrIf return main.getResourceDistributor().withResourceDistributorLock(() -> { try { TenantConfig[] tenantsFromDb = getAllTenantsFromDb(); + TenantConfig[] filteredTenantsFromDb = this.getFilteredTenantConfigs(tenantsFromDb); Map normalizedTenantsFromDb = Config.getNormalisedConfigsForAllTenants( - tenantsFromDb, Config.getBaseConfigAsJsonObject(main)); + filteredTenantsFromDb, Config.getBaseConfigAsJsonObject(main)); Map normalizedTenantsFromMemory = Config.getNormalisedConfigsForAllTenants( @@ -130,9 +142,14 @@ public List refreshTenantsInCoreBasedOnChangesInCoreConfigOrIf } } - boolean sameNumberOfTenants = tenantsFromDb.length == this.tenantConfigs.length; + boolean sameNumberOfTenants = + filteredTenantsFromDb.length == this.tenantConfigs.length; - this.tenantConfigs = tenantsFromDb; + this.dangerous_allCUDsFromDb.clear(); + for (TenantConfig tenant : tenantsFromDb) { + this.dangerous_allCUDsFromDb.add(tenant.tenantIdentifier.getConnectionUriDomain()); + } + this.tenantConfigs = filteredTenantsFromDb; if (tenantsThatChanged.size() == 0 && sameNumberOfTenants) { return tenantsThatChanged; } @@ -191,7 +208,7 @@ public void loadStorageLayer() throws IOException, InvalidConfigException { public void loadFeatureFlag(List tenantsThatChanged) { List apps = new ArrayList<>(); Set appsSet = new HashSet<>(); - for (TenantConfig t : tenantConfigs) { + for (TenantConfig t : this.tenantConfigs) { if (appsSet.contains(t.tenantIdentifier.toAppIdentifier())) { continue; } @@ -205,7 +222,7 @@ public void loadSigningKeys(List tenantsThatChanged) throws UnsupportedJWTSigningAlgorithmException { List apps = new ArrayList<>(); Set appsSet = new HashSet<>(); - for (TenantConfig t : tenantConfigs) { + for (TenantConfig t : this.tenantConfigs) { if (appsSet.contains(t.tenantIdentifier.toAppIdentifier())) { continue; } @@ -239,4 +256,21 @@ public TenantConfig[] getAllTenants() { throw new IllegalStateException(e); } } + + private TenantConfig[] getFilteredTenantConfigs(TenantConfig[] inputTenantConfigs) { + String loadOnlyCUD = Config.getBaseConfig(main).getSuperTokensLoadOnlyCUD(); + + if (loadOnlyCUD == null) { + return inputTenantConfigs; + } + + return Arrays.stream(inputTenantConfigs) + .filter(tenantConfig -> tenantConfig.tenantIdentifier.getConnectionUriDomain().equals(loadOnlyCUD) + || tenantConfig.tenantIdentifier.getConnectionUriDomain().equals(TenantIdentifier.DEFAULT_CONNECTION_URI)) + .toArray(TenantConfig[]::new); + } + + public boolean isConnectionUriDomainPresentInDb(String cud) { + return this.dangerous_allCUDsFromDb.contains(cud); + } } diff --git a/src/main/java/io/supertokens/output/Logging.java b/src/main/java/io/supertokens/output/Logging.java index 58106b7ba..d3c89f1fb 100644 --- a/src/main/java/io/supertokens/output/Logging.java +++ b/src/main/java/io/supertokens/output/Logging.java @@ -52,11 +52,11 @@ public class Logging extends ResourceDistributor.SingletonResource { private Logging(Main main) { this.infoLogger = Config.getBaseConfig(main).getInfoLogPath(main).equals("null") - ? createLoggerForConsole(main, "io.supertokens.Info") + ? createLoggerForConsole(main, "io.supertokens.Info", LOG_LEVEL.INFO) : createLoggerForFile(main, Config.getBaseConfig(main).getInfoLogPath(main), "io.supertokens.Info"); this.errorLogger = Config.getBaseConfig(main).getErrorLogPath(main).equals("null") - ? createLoggerForConsole(main, "io.supertokens.Error") + ? createLoggerForConsole(main, "io.supertokens.Error", LOG_LEVEL.ERROR) : createLoggerForFile(main, Config.getBaseConfig(main).getErrorLogPath(main), "io.supertokens.Error"); Storage storage = StorageLayer.getBaseStorage(main); @@ -251,12 +251,13 @@ private Logger createLoggerForFile(Main main, String file, String name) { return logger; } - private Logger createLoggerForConsole(Main main, String name) { + private Logger createLoggerForConsole(Main main, String name, LOG_LEVEL logLevel) { LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); LayoutWrappingEncoder ple = new LayoutWrappingEncoder(main.getProcessId(), Version.getVersion(main).getCoreVersion()); ple.setContext(lc); ple.start(); ConsoleAppender logConsoleAppender = new ConsoleAppender<>(); + logConsoleAppender.setTarget(logLevel == LOG_LEVEL.ERROR ? "System.err" : "System.out"); logConsoleAppender.setEncoder(ple); logConsoleAppender.setContext(lc); logConsoleAppender.start(); diff --git a/src/main/java/io/supertokens/storageLayer/StorageLayer.java b/src/main/java/io/supertokens/storageLayer/StorageLayer.java index 3d4c34f83..faeaece0d 100644 --- a/src/main/java/io/supertokens/storageLayer/StorageLayer.java +++ b/src/main/java/io/supertokens/storageLayer/StorageLayer.java @@ -242,7 +242,7 @@ public static void loadAllTenantStorage(Main main, TenantConfig[] tenants) } main.getResourceDistributor().clearAllResourcesWithResourceKey(RESOURCE_KEY); - Set userPoolsInUse = new HashSet<>(); + Set uniquePoolsInUse = new HashSet<>(); for (ResourceDistributor.KeyClass key : resourceKeyToStorageMap.keySet()) { Storage currStorage = resourceKeyToStorageMap.get(key); @@ -259,11 +259,16 @@ public static void loadAllTenantStorage(Main main, TenantConfig[] tenants) main.getResourceDistributor().setResource(key.getTenantIdentifier(), RESOURCE_KEY, new StorageLayer(resourceKeyToStorageMap.get(key))); - userPoolsInUse.add(userPoolId); + uniquePoolsInUse.add(uniqueId); } for (ResourceDistributor.KeyClass key : existingStorageMap.keySet()) { - if (!userPoolsInUse.contains(((StorageLayer) existingStorageMap.get(key)).storage.getUserPoolId())) { + Storage existingStorage = ((StorageLayer) existingStorageMap.get(key)).storage; + String userPoolId = existingStorage.getUserPoolId(); + String connectionPoolId = existingStorage.getConnectionPoolId(); + String uniqueId = userPoolId + "~" + connectionPoolId; + + if (!uniquePoolsInUse.contains(uniqueId)) { ((StorageLayer) existingStorageMap.get(key)).storage.close(); ((StorageLayer) existingStorageMap.get(key)).storage.stopLogging(); } diff --git a/src/main/java/io/supertokens/utils/ConfigMapper.java b/src/main/java/io/supertokens/utils/ConfigMapper.java new file mode 100644 index 000000000..4d7484026 --- /dev/null +++ b/src/main/java/io/supertokens/utils/ConfigMapper.java @@ -0,0 +1,140 @@ +/* + * 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.utils; + +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonAlias; +import io.supertokens.pluginInterface.exceptions.InvalidConfigException; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Map; + +public class ConfigMapper { + public static T mapConfig(JsonObject config, Class clazz) throws InvalidConfigException { + try { + T result = clazz.newInstance(); + for (Map.Entry entry : config.entrySet()) { + Field field = findField(clazz, entry.getKey()); + if (field != null) { + setValue(result, field, entry.getValue()); + } + } + return result; + } catch (InstantiationException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static Field findField(Class clazz, String key) { + Field[] fields = clazz.getDeclaredFields(); + + for (Field field : fields) { + if (field.getName().equals(key)) { + return field; + } + + // Check for JsonProperty annotation + JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class); + if (jsonProperty != null && jsonProperty.value().equals(key)) { + return field; + } + + // Check for JsonAlias annotation + JsonAlias jsonAlias = field.getAnnotation(JsonAlias.class); + if (jsonAlias != null) { + for (String alias : jsonAlias.value()) { + if (alias.equals(key)) { + return field; + } + } + } + } + + return null; // Field not found + } + + private static void setValue(T object, Field field, JsonElement value) throws InvalidConfigException { + field.setAccessible(true); + Object convertedValue = convertJsonElementToTargetType(value, field.getType(), field.getName()); + if (convertedValue != null || isNullable(field.getType())) { + try { + field.set(object, convertedValue); + } catch (IllegalAccessException e) { + throw new IllegalStateException("should never happen"); + } + } + } + + private static boolean isNullable(Class type) { + return !type.isPrimitive(); + } + + private static Object convertJsonElementToTargetType(JsonElement value, Class targetType, String fieldName) + throws InvalidConfigException { + // If the value is JsonNull, return null for any type + if (value instanceof JsonNull || value == null) { + return null; + } + + try { + if (targetType == String.class) { + return value.getAsString(); + } else if (targetType == Integer.class || targetType == int.class) { + if (value.getAsDouble() == (double) value.getAsInt()) { + return value.getAsInt(); + } + } else if (targetType == Long.class || targetType == long.class) { + if (value.getAsDouble() == (double) value.getAsLong()) { + return value.getAsLong(); + } + } else if (targetType == Double.class || targetType == double.class) { + return value.getAsDouble(); + } else if (targetType == Float.class || targetType == float.class) { + return value.getAsFloat(); + } else if (targetType == Boolean.class || targetType == boolean.class) { + // Handle boolean conversion from strings like "true", "false" + return handleBooleanConversion(value, fieldName); + } + } catch (NumberFormatException e) { + // do nothing, will fall into InvalidConfigException + } + + // Throw an exception for unsupported conversions + throw new InvalidConfigException("'" + fieldName + "' must be of type " + targetType.getSimpleName()); + } + + private static Object handleBooleanConversion(JsonElement value, String fieldName) throws InvalidConfigException { + // Handle boolean conversion from strings like "true", "false" + if (value.isJsonPrimitive() && value.getAsJsonPrimitive().isString()) { + String stringValue = value.getAsString().toLowerCase(); + if (stringValue.equals("true")) { + return true; + } else if (stringValue.equals("false")) { + return false; + } + } else if (value.isJsonPrimitive() && value.getAsJsonPrimitive().isBoolean()) { + return value.getAsBoolean(); + } + + // Throw an exception for unsupported conversions + throw new InvalidConfigException("'" + fieldName + "' must be of type boolean"); + } +} diff --git a/src/main/java/io/supertokens/webserver/WebserverAPI.java b/src/main/java/io/supertokens/webserver/WebserverAPI.java index 6b9e23048..03919bc10 100644 --- a/src/main/java/io/supertokens/webserver/WebserverAPI.java +++ b/src/main/java/io/supertokens/webserver/WebserverAPI.java @@ -24,6 +24,7 @@ import io.supertokens.config.CoreConfig; import io.supertokens.exceptions.QuitProgramException; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.multitenancy.MultitenancyHelper; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.output.Logging; import io.supertokens.pluginInterface.Storage; @@ -289,15 +290,18 @@ private String getConnectionUriDomain(HttpServletRequest req) throws ServletExce String connectionUriDomain = req.getServerName(); connectionUriDomain = Utils.normalizeAndValidateConnectionUriDomain(connectionUriDomain, false); - try { - if (Config.getConfig(new TenantIdentifier(connectionUriDomain, null, null), main) == - Config.getConfig(new TenantIdentifier(null, null, null), main)) { - return null; + if (MultitenancyHelper.getInstance(main).isConnectionUriDomainPresentInDb(connectionUriDomain)) { + CoreConfig baseConfig = Config.getBaseConfig(main); + if (baseConfig.getSuperTokensLoadOnlyCUD() != null) { + if (!connectionUriDomain.equals(baseConfig.getSuperTokensLoadOnlyCUD())) { + throw new ServletException(new BadRequestException("Connection URI domain is disallowed")); + } } - } catch (TenantOrAppNotFoundException e) { - throw new IllegalStateException(e); + + return connectionUriDomain; } - return connectionUriDomain; + + return null; } @TestOnly @@ -348,7 +352,6 @@ protected AppIdentifierWithStorage getPublicTenantStorage(HttpServletRequest req Storage storage = StorageLayer.getStorage(appIdentifier.getAsPublicTenantIdentifier(), main); return appIdentifier.withStorage(storage); - } protected TenantIdentifierWithStorageAndUserIdMapping getTenantIdentifierWithStorageAndUserIdMappingFromRequest( @@ -493,10 +496,13 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws } Logging.info(main, tenantIdentifier, "API ended: " + req.getRequestURI() + ". Method: " + req.getMethod(), false); - try { - RequestStats.getInstance(main, tenantIdentifier.toAppIdentifier()).updateRequestStats(); - } catch (TenantOrAppNotFoundException e) { - // Ignore the error as we would have already sent the response for tenantNotFound + + if (tenantIdentifier != null) { + try { + RequestStats.getInstance(main, tenantIdentifier.toAppIdentifier()).updateRequestStats(); + } catch (TenantOrAppNotFoundException e) { + // Ignore the error as we would have already sent the response for tenantNotFound + } } } diff --git a/src/main/java/io/supertokens/webserver/api/multitenancy/BaseCreateOrUpdate.java b/src/main/java/io/supertokens/webserver/api/multitenancy/BaseCreateOrUpdate.java index 940968568..2fbfb5ce4 100644 --- a/src/main/java/io/supertokens/webserver/api/multitenancy/BaseCreateOrUpdate.java +++ b/src/main/java/io/supertokens/webserver/api/multitenancy/BaseCreateOrUpdate.java @@ -19,6 +19,8 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.config.Config; +import io.supertokens.config.CoreConfig; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.multitenancy.exception.BadPermissionException; @@ -59,6 +61,14 @@ protected void handle(HttpServletRequest req, TenantIdentifier sourceTenantIdent throw new ServletException(new BadRequestException("requiredSecondaryFactors cannot be empty. Set null instead to remove all required secondary factors.")); } + CoreConfig baseConfig = Config.getBaseConfig(main); + if (baseConfig.getSuperTokensLoadOnlyCUD() != null) { + if (!(targetTenantIdentifier.getConnectionUriDomain().equals(TenantIdentifier.DEFAULT_CONNECTION_URI) || targetTenantIdentifier.getConnectionUriDomain().equals(baseConfig.getSuperTokensLoadOnlyCUD()))) { + throw new ServletException(new BadRequestException("Creation of connection uri domain or app or " + + "tenant is disallowed")); + } + } + TenantConfig tenantConfig = Multitenancy.getTenantInfo(main, new TenantIdentifier(targetTenantIdentifier.getConnectionUriDomain(), targetTenantIdentifier.getAppId(), targetTenantIdentifier.getTenantId())); diff --git a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java index 983dd1624..404947121 100644 --- a/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java +++ b/src/main/java/io/supertokens/webserver/api/passwordless/ConsumeCodeAPI.java @@ -97,6 +97,10 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v4_0), createRecipeUserIfNotExists); + io.supertokens.useridmapping.UserIdMapping.populateExternalUserIdForUsers(this.getTenantIdentifierWithStorageFromRequest(req), new AuthRecipeUserInfo[]{consumeCodeResponse.user}); + + ActiveUsers.updateLastActive(this.getPublicTenantStorage(req), main, consumeCodeResponse.user.getSupertokensUserId()); + JsonObject result = new JsonObject(); result.addProperty("status", "OK"); diff --git a/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java b/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java index 3e65fc432..dfd7c78ef 100644 --- a/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java +++ b/src/test/java/io/supertokens/test/AuthRecipesParallelTest.java @@ -20,7 +20,11 @@ import io.supertokens.emailpassword.EmailPassword; import io.supertokens.emailpassword.exceptions.EmailChangeNotAllowedException; import io.supertokens.emailpassword.exceptions.WrongCredentialsException; +import io.supertokens.featureflag.EE_FEATURES; +import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; +import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager; @@ -37,8 +41,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; public class AuthRecipesParallelTest { @Rule @@ -56,50 +59,61 @@ public void beforeEach() { @Test public void timeTakenFor500SignInParallel() throws Exception { - String[] args = {"../"}; + for (int t = 0; t < 5; t++) { + String[] args = {"../"}; + + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + ExecutorService ex = Executors.newFixedThreadPool(1000); + int numberOfThreads = 500; + + EmailPassword.signUp(process.getProcess(), "test@example.com", "password"); + AtomicInteger counter = new AtomicInteger(0); + AtomicInteger retryCounter = new AtomicInteger(0); + + long st = System.currentTimeMillis(); + for (int i = 0; i < numberOfThreads; i++) { + ex.execute(() -> { + while(true) { + try { + EmailPassword.signIn(process.getProcess(), "test@example.com", "password"); + counter.incrementAndGet(); + break; + } catch (StorageQueryException e) { + retryCounter.incrementAndGet(); + // continue + } catch (WrongCredentialsException e) { + throw new RuntimeException(e); + } + } + }); + } - TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); - assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + ex.shutdown(); - if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { - return; - } - - ExecutorService ex = Executors.newFixedThreadPool(1000); - int numberOfThreads = 500; + ex.awaitTermination(2, TimeUnit.MINUTES); + System.out.println("Time taken for " + numberOfThreads + " sign in parallel: " + (System.currentTimeMillis() - st) + "ms"); + System.out.println("Retry counter: " + retryCounter.get()); + assertEquals(counter.get(), numberOfThreads); - EmailPassword.signUp(process.getProcess(), "test@example.com", "password"); - AtomicInteger counter = new AtomicInteger(0); - AtomicInteger retryCounter = new AtomicInteger(0); + if (retryCounter.get() != 0) { + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + continue; // retry + } + assertEquals(0, retryCounter.get()); - long st = System.currentTimeMillis(); - for (int i = 0; i < numberOfThreads; i++) { - ex.execute(() -> { - while(true) { - try { - EmailPassword.signIn(process.getProcess(), "test@example.com", "password"); - counter.incrementAndGet(); - break; - } catch (StorageQueryException e) { - retryCounter.incrementAndGet(); - // continue - } catch (WrongCredentialsException e) { - throw new RuntimeException(e); - } - } - }); + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + return; } - ex.shutdown(); - - ex.awaitTermination(2, TimeUnit.MINUTES); - System.out.println("Time taken for " + numberOfThreads + " sign in parallel: " + (System.currentTimeMillis() - st) + "ms"); - System.out.println("Retry counter: " + retryCounter.get()); - assertEquals(counter.get(), numberOfThreads); - assertEquals(0, retryCounter.get()); - - process.kill(); - assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + fail(); // tried 5 times } @Test diff --git a/src/test/java/io/supertokens/test/ConfigMapperTest.java b/src/test/java/io/supertokens/test/ConfigMapperTest.java new file mode 100644 index 000000000..1b048020b --- /dev/null +++ b/src/test/java/io/supertokens/test/ConfigMapperTest.java @@ -0,0 +1,296 @@ +/* + * 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.test; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.JsonObject; +import io.supertokens.pluginInterface.exceptions.InvalidConfigException; +import io.supertokens.utils.ConfigMapper; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +public class ConfigMapperTest { + + public static class DummyConfig { + @JsonProperty + int int_property = -1; + + @JsonProperty + long long_property = -1; + + @JsonProperty + float float_property = -1; + + @JsonProperty + double double_property = -1; + + @JsonProperty + String string_property = "default_string"; + + @JsonProperty + boolean bool_property; + + @JsonProperty + Long nullable_long_property = new Long(-1); + } + + @Test + public void testAllValidConversions() throws Exception { + // Test defaults + { + JsonObject config = new JsonObject(); + assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).int_property); + assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).long_property); + assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).float_property, 0.0001); + assertEquals(-1, ConfigMapper.mapConfig(config, DummyConfig.class).double_property, 0.0001); + assertEquals("default_string", ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + assertEquals(new Long(-1), ConfigMapper.mapConfig(config, DummyConfig.class).nullable_long_property); + } + + // valid for int + { + JsonObject config = new JsonObject(); + config.addProperty("int_property", "100"); + assertEquals(100, ConfigMapper.mapConfig(config, DummyConfig.class).int_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("int_property", 100); + assertEquals(100, ConfigMapper.mapConfig(config, DummyConfig.class).int_property); + } + + // valid for long + { + JsonObject config = new JsonObject(); + config.addProperty("long_property", "100"); + assertEquals(100, ConfigMapper.mapConfig(config, DummyConfig.class).long_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("long_property", 100); + assertEquals(100, ConfigMapper.mapConfig(config, DummyConfig.class).long_property); + } + + // valid for float + { + JsonObject config = new JsonObject(); + config.addProperty("float_property", 100); + System.out.println(ConfigMapper.mapConfig(config, DummyConfig.class).float_property); + assertEquals((float) 100, ConfigMapper.mapConfig(config, DummyConfig.class).float_property, 0.001); + } + { + JsonObject config = new JsonObject(); + config.addProperty("float_property", 3.14); + assertEquals((float) 3.14, ConfigMapper.mapConfig(config, DummyConfig.class).float_property, 0.001); + } + { + JsonObject config = new JsonObject(); + config.addProperty("float_property", "100"); + assertEquals((float) 100, ConfigMapper.mapConfig(config, DummyConfig.class).float_property, 0.001); + } + { + JsonObject config = new JsonObject(); + config.addProperty("float_property", "3.14"); + assertEquals((float) 3.14, ConfigMapper.mapConfig(config, DummyConfig.class).float_property, 0.001); + } + + // valid double + { + JsonObject config = new JsonObject(); + config.addProperty("double_property", 100); + assertEquals((double) 100, ConfigMapper.mapConfig(config, DummyConfig.class).double_property, 0.001); + } + { + JsonObject config = new JsonObject(); + config.addProperty("double_property", 3.14); + assertEquals((double) 3.14, ConfigMapper.mapConfig(config, DummyConfig.class).double_property, 0.001); + } + { + JsonObject config = new JsonObject(); + config.addProperty("double_property", "100"); + assertEquals((double) 100, ConfigMapper.mapConfig(config, DummyConfig.class).double_property, 0.001); + } + { + JsonObject config = new JsonObject(); + config.addProperty("double_property", "3.14"); + assertEquals((double) 3.14, ConfigMapper.mapConfig(config, DummyConfig.class).double_property, 0.001); + } + + // valid for bool + { + JsonObject config = new JsonObject(); + config.addProperty("bool_property", "true"); + assertEquals(true, ConfigMapper.mapConfig(config, DummyConfig.class).bool_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("bool_property", "TRUE"); + assertEquals(true, ConfigMapper.mapConfig(config, DummyConfig.class).bool_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("bool_property", "false"); + assertEquals(false, ConfigMapper.mapConfig(config, DummyConfig.class).bool_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("bool_property", true); + assertEquals(true, ConfigMapper.mapConfig(config, DummyConfig.class).bool_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("bool_property", false); + assertEquals(false, ConfigMapper.mapConfig(config, DummyConfig.class).bool_property); + } + + // valid for string + { + JsonObject config = new JsonObject(); + config.addProperty("string_property", "true"); + assertEquals("true", ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("string_property", true); + assertEquals("true", ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("string_property", 100); + assertEquals("100", ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("string_property", 3.14); + assertEquals("3.14", ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + } + { + JsonObject config = new JsonObject(); + config.addProperty("string_property", "hello"); + assertEquals("hello", ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + } + + { + JsonObject config = new JsonObject(); + config.add("string_property", null); + assertEquals(null, ConfigMapper.mapConfig(config, DummyConfig.class).string_property); + } + + // valid for nullable long + { + JsonObject config = new JsonObject(); + config.add("nullable_long_property", null); + assertEquals(null, ConfigMapper.mapConfig(config, DummyConfig.class).nullable_long_property); + } + + { + JsonObject config = new JsonObject(); + config.addProperty("nullable_long_property", 100); + assertEquals(new Long(100), ConfigMapper.mapConfig(config, DummyConfig.class).nullable_long_property); + } + } + + @Test + public void testInvalidConversions() throws Exception { + String[] properties = new String[]{ + "int_property", + "int_property", + "int_property", + "int_property", + "int_property", + + "long_property", + "long_property", + "long_property", + "long_property", + + "float_property", + "float_property", + "float_property", + + "double_property", + "double_property", + "double_property", + }; + Object[] values = new Object[]{ + "abcd", // int + "", // int + true, // int + new Double(4.5), // int + new Long(1234567892342l), // int + + "abcd", // long + "", // long + true, // long + new Double(4.5), // long + + "abcd", // float + "", // float + true, // float + + "abcd", // double + "", // double + true, // double + }; + + String[] expectedErrorMessages = new String[]{ + "'int_property' must be of type int", // int + "'int_property' must be of type int", // int + "'int_property' must be of type int", // int + "'int_property' must be of type int", // int + "'int_property' must be of type int", // int + + "'long_property' must be of type long", // long + "'long_property' must be of type long", // long + "'long_property' must be of type long", // long + "'long_property' must be of type long", // long + + "'float_property' must be of type float", // float + "'float_property' must be of type float", // float + "'float_property' must be of type float", // float + + "'double_property' must be of type double", // double + "'double_property' must be of type double", // double + "'double_property' must be of type double", // double + }; + + for (int i = 0; i < properties.length; i++) { + try { + System.out.println("Test case " + i); + JsonObject config = new JsonObject(); + if (values[i] == null) { + config.add(properties[i], null); + } + else if (values[i] instanceof String) { + config.addProperty(properties[i], (String) values[i]); + } else if (values[i] instanceof Boolean) { + config.addProperty(properties[i], (Boolean) values[i]); + } else if (values[i] instanceof Number) { + config.addProperty(properties[i], (Number) values[i]); + } else { + throw new RuntimeException("Invalid type"); + } + DummyConfig dc = ConfigMapper.mapConfig(config, DummyConfig.class); + fail(); + } catch (InvalidConfigException e) { + assertEquals(expectedErrorMessages[i], e.getMessage()); + } + } + } +} diff --git a/src/test/java/io/supertokens/test/ConfigTest2_21.java b/src/test/java/io/supertokens/test/ConfigTest2_21.java index 73b886f6f..a4b28c060 100644 --- a/src/test/java/io/supertokens/test/ConfigTest2_21.java +++ b/src/test/java/io/supertokens/test/ConfigTest2_21.java @@ -24,6 +24,7 @@ import org.junit.*; import org.junit.rules.TestRule; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class ConfigTest2_21 { @@ -84,4 +85,22 @@ public void testThatNewConfigWorks() throws Exception { EventAndException stopEvent = process.checkOrWaitForEvent(PROCESS_STATE.STOPPED); assertNotNull(stopEvent); } + + @Test + public void testCoreConfigTypeValidationInConfigYaml() throws Exception { + Utils.setValueInConfig("access_token_validity", "abcd"); + + String[] args = { "../" }; + + TestingProcess process = TestingProcessManager.start(args); + + EventAndException startEvent = process.checkOrWaitForEvent(PROCESS_STATE.INIT_FAILURE); + assertNotNull(startEvent); + + assertEquals("io.supertokens.pluginInterface.exceptions.InvalidConfigException: 'access_token_validity' must be of type long", startEvent.exception.getMessage()); + + process.kill(); + EventAndException stopEvent = process.checkOrWaitForEvent(PROCESS_STATE.STOPPED); + assertNotNull(stopEvent); + } } diff --git a/src/test/java/io/supertokens/test/FeatureFlagTest.java b/src/test/java/io/supertokens/test/FeatureFlagTest.java index 98a39851e..408351098 100644 --- a/src/test/java/io/supertokens/test/FeatureFlagTest.java +++ b/src/test/java/io/supertokens/test/FeatureFlagTest.java @@ -94,7 +94,7 @@ public void noLicenseKeyShouldHaveEmptyFeatureFlag() JsonObject stats = FeatureFlag.getInstance(process.getProcess()).getPaidFeatureStats(); Assert.assertEquals(stats.entrySet().size(), 1); - Assert.assertEquals(stats.get("maus").getAsJsonArray().size(), 30); + Assert.assertEquals(stats.get("maus").getAsJsonArray().size(), 31); Assert.assertEquals(stats.get("maus").getAsJsonArray().get(0).getAsInt(), 0); Assert.assertEquals(stats.get("maus").getAsJsonArray().get(29).getAsInt(), 0); @@ -189,7 +189,7 @@ public void testThatCallingGetFeatureFlagAPIReturnsMfaStats() throws Exception { assert features.size() == 2; // MFA + MULTITENANCY } assert features.contains(new JsonPrimitive("mfa")); - assert maus.size() == 30; + assert maus.size() == 31; assert maus.get(0).getAsInt() == 0; assert maus.get(29).getAsInt() == 0; @@ -197,7 +197,7 @@ public void testThatCallingGetFeatureFlagAPIReturnsMfaStats() throws Exception { int totalMfaUsers = mfaStats.get("totalUserCountWithMoreThanOneLoginMethodOrTOTPEnabled").getAsInt(); JsonArray mfaMaus = mfaStats.get("mauWithMoreThanOneLoginMethodOrTOTPEnabled").getAsJsonArray(); - assert mfaMaus.size() == 30; + assert mfaMaus.size() == 31; assert mfaMaus.get(0).getAsInt() == 0; assert mfaMaus.get(29).getAsInt() == 0; @@ -250,7 +250,7 @@ public void testThatCallingGetFeatureFlagAPIReturnsMfaStats() throws Exception { } assert features.contains(new JsonPrimitive("mfa")); - assert maus.size() == 30; + assert maus.size() == 31; assert maus.get(0).getAsInt() == 2; // 2 users have signed up assert maus.get(29).getAsInt() == 2; @@ -258,7 +258,7 @@ public void testThatCallingGetFeatureFlagAPIReturnsMfaStats() throws Exception { int totalMfaUsers = mfaStats.get("totalUserCountWithMoreThanOneLoginMethodOrTOTPEnabled").getAsInt(); JsonArray mfaMaus = mfaStats.get("mauWithMoreThanOneLoginMethodOrTOTPEnabled").getAsJsonArray(); - assert mfaMaus.size() == 30; + assert mfaMaus.size() == 31; assert mfaMaus.get(0).getAsInt() == 1; // only 1 user has TOTP enabled assert mfaMaus.get(29).getAsInt() == 1; @@ -292,7 +292,7 @@ public void testThatCallingGetFeatureFlagAPIReturnsMfaStats() throws Exception { } assert features.contains(new JsonPrimitive("mfa")); - assert maus.size() == 30; + assert maus.size() == 31; assert maus.get(0).getAsInt() == 4; // 2 users have signed up assert maus.get(29).getAsInt() == 4; diff --git a/src/test/java/io/supertokens/test/PathRouterTest.java b/src/test/java/io/supertokens/test/PathRouterTest.java index de865ed16..b58d80664 100644 --- a/src/test/java/io/supertokens/test/PathRouterTest.java +++ b/src/test/java/io/supertokens/test/PathRouterTest.java @@ -1533,7 +1533,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I public void tenantNotFoundTest3() throws InterruptedException, IOException, io.supertokens.httpRequest.HttpResponseException, InvalidConfigException, - io.supertokens.test.httpRequest.HttpResponseException, TenantOrAppNotFoundException { + io.supertokens.test.httpRequest.HttpResponseException, TenantOrAppNotFoundException, + InvalidProviderConfigException, StorageQueryException, FeatureNotEnabledException, + CannotModifyBaseConfigException, BadPermissionException { String[] args = {"../"}; Utils.setValueInConfig("host", "\"0.0.0.0\""); @@ -1556,15 +1558,26 @@ public void tenantNotFoundTest3() StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) .modifyConfigToAddANewUserPoolForTesting(tenantConfig, 2); - Config.loadAllTenantConfig(process.getProcess(), new TenantConfig[]{ - new TenantConfig(new TenantIdentifier("localhost", null, null), new EmailPasswordConfig(false), + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantConfig( + new TenantIdentifier("localhost", null, null), + new EmailPasswordConfig(false), new ThirdPartyConfig(false, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(false), null, null, tenantConfig), - new TenantConfig(new TenantIdentifier("localhost", null, "t1"), new EmailPasswordConfig(false), + false + ); + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantConfig( + new TenantIdentifier("localhost", null, "t1"), + new EmailPasswordConfig(false), new ThirdPartyConfig(false, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(false), - null, null, tenantConfig)}, new ArrayList<>()); + null, null, tenantConfig), + false + ); Webserver.getInstance(process.getProcess()).addAPI(new WebserverAPI(process.getProcess(), "") { @@ -2788,7 +2801,9 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I public void tenantNotFoundWithAppIdTest3() throws InterruptedException, IOException, io.supertokens.httpRequest.HttpResponseException, InvalidConfigException, - io.supertokens.test.httpRequest.HttpResponseException, TenantOrAppNotFoundException { + io.supertokens.test.httpRequest.HttpResponseException, TenantOrAppNotFoundException, + InvalidProviderConfigException, StorageQueryException, FeatureNotEnabledException, + CannotModifyBaseConfigException, BadPermissionException { String[] args = {"../"}; Utils.setValueInConfig("host", "\"0.0.0.0\""); @@ -2811,15 +2826,26 @@ public void tenantNotFoundWithAppIdTest3() StorageLayer.getStorage(new TenantIdentifier(null, null, null), process.getProcess()) .modifyConfigToAddANewUserPoolForTesting(tenantConfig, 2); - Config.loadAllTenantConfig(process.getProcess(), new TenantConfig[]{ - new TenantConfig(new TenantIdentifier("localhost", null, null), new EmailPasswordConfig(false), + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantConfig( + new TenantIdentifier("localhost", null, null), + new EmailPasswordConfig(false), new ThirdPartyConfig(false, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(false), null, null, tenantConfig), - new TenantConfig(new TenantIdentifier("localhost", "app1", "t1"), new EmailPasswordConfig(false), + false + ); + Multitenancy.addNewOrUpdateAppOrTenant( + process.getProcess(), + new TenantConfig( + new TenantIdentifier("localhost", "app1", "t1"), + new EmailPasswordConfig(false), new ThirdPartyConfig(false, new ThirdPartyConfig.Provider[0]), new PasswordlessConfig(false), - null, null, tenantConfig)}, new ArrayList<>()); + null, null, tenantConfig), + false + ); Webserver.getInstance(process.getProcess()).addAPI(new WebserverAPI(process.getProcess(), "") { diff --git a/src/test/java/io/supertokens/test/StorageLayerTest.java b/src/test/java/io/supertokens/test/StorageLayerTest.java index eb88558d8..d649cc7fb 100644 --- a/src/test/java/io/supertokens/test/StorageLayerTest.java +++ b/src/test/java/io/supertokens/test/StorageLayerTest.java @@ -97,7 +97,7 @@ public void totpCodeLengthTest() throws Exception { // This error will be different in Postgres and MySQL // We added (CHECK (LENGTH(code) <= 8)) to the table definition in SQLite String totpUsedCodeTable = Config.getConfig(start).getTotpUsedCodesTable(); - assert e.getMessage().contains("CHECK constraint failed: " + totpUsedCodeTable) || e.getMessage().contains("LENGTH(code) <= 8"); + assert e.getMessage().contains("CHECK constraint failed: "); } // Try code with length < 8 diff --git a/src/test/java/io/supertokens/test/TelemetryTest.java b/src/test/java/io/supertokens/test/TelemetryTest.java index 95e312ac7..968d154f4 100644 --- a/src/test/java/io/supertokens/test/TelemetryTest.java +++ b/src/test/java/io/supertokens/test/TelemetryTest.java @@ -21,7 +21,10 @@ import io.supertokens.ProcessState; import io.supertokens.ProcessState.PROCESS_STATE; import io.supertokens.cronjobs.telemetry.Telemetry; +import io.supertokens.dashboard.Dashboard; import io.supertokens.httpRequest.HttpRequestMocking; +import io.supertokens.pluginInterface.STORAGE_TYPE; +import io.supertokens.storageLayer.StorageLayer; import io.supertokens.test.TestingProcessManager.TestingProcess; import io.supertokens.version.Version; import org.junit.AfterClass; @@ -111,6 +114,16 @@ public void testThatTelemetryWorks() throws Exception { String[] args = { "../" }; TestingProcess process = TestingProcessManager.start(args, false); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + if (StorageLayer.getBaseStorage(process.getProcess()).getType() == STORAGE_TYPE.SQL) { + Dashboard.signUpDashboardUser(process.getProcess(), "test@example.com", "password123"); + } + + // Restarting the process to send telemetry again + process.kill(false); + process = TestingProcessManager.start(args, false); ByteArrayOutputStream output = new ByteArrayOutputStream(); final HttpURLConnection mockCon = mock(HttpURLConnection.class); @@ -149,13 +162,26 @@ protected URLConnection openConnection(URL u) { assertNotNull(process.checkOrWaitForEvent(PROCESS_STATE.SENT_TELEMETRY)); JsonObject telemetryData = new JsonParser().parse(output.toString()).getAsJsonObject(); + assertEquals(7, telemetryData.entrySet().size()); assertTrue(telemetryData.has("telemetryId")); assertEquals(telemetryData.get("superTokensVersion").getAsString(), Version.getVersion(process.getProcess()).getCoreVersion()); assertEquals(telemetryData.get("appId").getAsString(), "public"); assertEquals(telemetryData.get("connectionUriDomain").getAsString(), ""); - assertTrue(telemetryData.has("mau")); + assertTrue(telemetryData.has("maus")); + assertTrue(telemetryData.has("dashboardUserEmails")); + + if (StorageLayer.getBaseStorage(process.getProcess()).getType() == STORAGE_TYPE.SQL) { + assertEquals(1, telemetryData.get("dashboardUserEmails").getAsJsonArray().size()); + assertEquals("test@example.com", telemetryData.get("dashboardUserEmails").getAsJsonArray().get(0).getAsString()); + assertEquals(31, telemetryData.get("maus").getAsJsonArray().size()); + assertEquals(0, telemetryData.get("usersCount").getAsInt()); + } else { + assertEquals(0, telemetryData.get("dashboardUserEmails").getAsJsonArray().size()); + assertEquals(0, telemetryData.get("maus").getAsJsonArray().size()); + assertEquals(-1, telemetryData.get("usersCount").getAsInt()); + } process.kill(); assertNotNull(process.checkOrWaitForEvent(PROCESS_STATE.STOPPED)); diff --git a/src/test/java/io/supertokens/test/accountlinking/TestGetUserSpeed.java b/src/test/java/io/supertokens/test/accountlinking/TestGetUserSpeed.java index de6a8f890..237e26ac1 100644 --- a/src/test/java/io/supertokens/test/accountlinking/TestGetUserSpeed.java +++ b/src/test/java/io/supertokens/test/accountlinking/TestGetUserSpeed.java @@ -59,18 +59,8 @@ public void beforeEach() { Utils.reset(); } - @Test - public void testUserCreationLinkingAndGetByIdSpeeds() throws Exception { - String[] args = {"../"}; - TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); - Utils.setValueInConfig("postgresql_connection_pool_size", "100"); - Utils.setValueInConfig("mysql_connection_pool_size", "100"); - - FeatureFlagTestContent.getInstance(process.getProcess()) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ - EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY}); - process.startProcess(); - assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + public void testUserCreationLinkingAndGetByIdSpeedsCommon(TestingProcessManager.TestingProcess process, + long createTime, long linkingTime, long getTime) throws Exception { if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { return; @@ -81,6 +71,7 @@ public void testUserCreationLinkingAndGetByIdSpeeds() throws Exception { } int numberOfUsers = 10000; + List userIds = new ArrayList<>(); List userIds2 = new ArrayList<>(); Lock lock = new ReentrantLock(); @@ -108,7 +99,7 @@ public void testUserCreationLinkingAndGetByIdSpeeds() throws Exception { long end = System.currentTimeMillis(); System.out.println("Created users " + numberOfUsers + " in " + (end - start) + "ms"); - assert end - start < 25000; // 25 sec + assert end - start < createTime; // 25 sec } Thread.sleep(10000); // wait for index @@ -148,7 +139,7 @@ public void testUserCreationLinkingAndGetByIdSpeeds() throws Exception { es.awaitTermination(5, TimeUnit.MINUTES); long end = System.currentTimeMillis(); System.out.println("Accounts linked in " + (end - start) + "ms"); - assert end - start < 50000; // 50 sec + assert end - start < linkingTime; // 50 sec } Thread.sleep(10000); // wait for index @@ -169,10 +160,44 @@ public void testUserCreationLinkingAndGetByIdSpeeds() throws Exception { es.awaitTermination(5, TimeUnit.MINUTES); long end = System.currentTimeMillis(); System.out.println("Time taken for " + numberOfUsers + " users: " + (end - start) + "ms"); - assert end - start < 20000; // 20 sec + assert end - start < getTime; // 20 sec } process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } + + @Test + public void testUserCreationLinkingAndGetByIdSpeedsWithoutMinIdle() throws Exception { + String[] args = {"../"}; + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); + Utils.setValueInConfig("postgresql_connection_pool_size", "100"); + Utils.setValueInConfig("mysql_connection_pool_size", "100"); + + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ + EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + testUserCreationLinkingAndGetByIdSpeedsCommon(process, 25000, 50000, 20000); + } + + @Test + public void testUserCreationLinkingAndGetByIdSpeedsWithMinIdle() throws Exception { + String[] args = {"../"}; + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); + Utils.setValueInConfig("postgresql_connection_pool_size", "100"); + Utils.setValueInConfig("mysql_connection_pool_size", "100"); + Utils.setValueInConfig("postgresql_minimum_idle_connections", "1"); + Utils.setValueInConfig("mysql_minimum_idle_connections", "1"); + + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ + EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + testUserCreationLinkingAndGetByIdSpeedsCommon(process, 60000, 50000, 20000); + } } diff --git a/src/test/java/io/supertokens/test/accountlinking/api/UserPaginationTest.java b/src/test/java/io/supertokens/test/accountlinking/api/UserPaginationTest.java index 99cf76376..bb2bf18be 100644 --- a/src/test/java/io/supertokens/test/accountlinking/api/UserPaginationTest.java +++ b/src/test/java/io/supertokens/test/accountlinking/api/UserPaginationTest.java @@ -17,6 +17,7 @@ package io.supertokens.test.accountlinking.api; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.supertokens.Main; import io.supertokens.ProcessState; @@ -50,8 +51,8 @@ import java.security.NoSuchAlgorithmException; import java.util.*; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; public class UserPaginationTest { @Rule @@ -380,4 +381,43 @@ public void testUserPaginationWithManyUsers() throws Exception { process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } + + @Test + public void testUserPaginationFromOldVersion() throws Exception { + String[] args = {"../"}; + TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); + FeatureFlagTestContent.getInstance(process.getProcess()) + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ + EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY}); + process.startProcess(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); + + if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { + return; + } + + AuthRecipeUserInfo user1 = createEmailPasswordUser(process.getProcess(), "test@example.com", "password1"); + Thread.sleep(50); + AuthRecipeUserInfo user2 = createThirdPartyUser(process.getProcess(), "google", "userid1", "test@example.com"); + Thread.sleep(50); + AuthRecipeUserInfo user3 = createPasswordlessUserWithEmail(process.getProcess(), "test@example.com"); + Thread.sleep(50); + + AuthRecipeUserInfo primaryUser = AuthRecipe.createPrimaryUser(process.getProcess(), user2.getSupertokensUserId()).user; + AuthRecipe.linkAccounts(process.getProcess(), user1.getSupertokensUserId(), primaryUser.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), user3.getSupertokensUserId(), primaryUser.getSupertokensUserId()); + + Map params = new HashMap<>(); + JsonObject response = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", + "http://localhost:3567/users", params, 1000, 1000, null, + SemVer.v3_0.get(), ""); + + assertEquals(1, response.get("users").getAsJsonArray().size()); + JsonObject user = response.get("users").getAsJsonArray().get(0).getAsJsonObject().get("user").getAsJsonObject(); + + assertEquals(user1.getSupertokensUserId(), user.get("id").getAsString()); // oldest login method + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } } diff --git a/src/test/java/io/supertokens/test/dashboard/DashboardTest.java b/src/test/java/io/supertokens/test/dashboard/DashboardTest.java index 7bb9211a4..eeaa3b447 100644 --- a/src/test/java/io/supertokens/test/dashboard/DashboardTest.java +++ b/src/test/java/io/supertokens/test/dashboard/DashboardTest.java @@ -290,7 +290,7 @@ public void testDashboardUsageStats() throws Exception { JsonObject usageStats = response.get("usageStats").getAsJsonObject(); JsonArray mauArr = usageStats.get("maus").getAsJsonArray(); assertEquals(1, usageStats.entrySet().size()); - assertEquals(30, mauArr.size()); + assertEquals(31, mauArr.size()); assertEquals(0, mauArr.get(0).getAsInt()); assertEquals(0, mauArr.get(29).getAsInt()); } @@ -312,7 +312,7 @@ public void testDashboardUsageStats() throws Exception { JsonObject usageStats = response.get("usageStats").getAsJsonObject(); JsonArray mauArr = usageStats.get("maus").getAsJsonArray(); assertEquals(1, usageStats.entrySet().size()); - assertEquals(30, mauArr.size()); + assertEquals(31, mauArr.size()); assertEquals(0, mauArr.get(0).getAsInt()); assertEquals(0, mauArr.get(29).getAsInt()); } @@ -338,7 +338,7 @@ public void testDashboardUsageStats() throws Exception { JsonObject usageStats = response.get("usageStats").getAsJsonObject(); JsonObject dashboardLoginObject = usageStats.get("dashboard_login").getAsJsonObject(); assertEquals(2, usageStats.entrySet().size()); - assertEquals(30, usageStats.get("maus").getAsJsonArray().size()); + assertEquals(31, usageStats.get("maus").getAsJsonArray().size()); assertEquals(1, dashboardLoginObject.entrySet().size()); assertEquals(1, dashboardLoginObject.get("user_count").getAsInt()); } @@ -366,7 +366,7 @@ public void testDashboardUsageStats() throws Exception { JsonObject usageStats = response.get("usageStats").getAsJsonObject(); JsonObject dashboardLoginObject = usageStats.get("dashboard_login").getAsJsonObject(); assertEquals(2, usageStats.entrySet().size()); - assertEquals(30, usageStats.get("maus").getAsJsonArray().size()); + assertEquals(31, usageStats.get("maus").getAsJsonArray().size()); assertEquals(1, dashboardLoginObject.entrySet().size()); assertEquals(4, dashboardLoginObject.get("user_count").getAsInt()); } diff --git a/src/test/java/io/supertokens/test/multitenant/ConfigTest.java b/src/test/java/io/supertokens/test/multitenant/ConfigTest.java index 421e3b542..23675314c 100644 --- a/src/test/java/io/supertokens/test/multitenant/ConfigTest.java +++ b/src/test/java/io/supertokens/test/multitenant/ConfigTest.java @@ -1914,6 +1914,7 @@ public void testAllConflictingConfigs() throws Exception { "argon2_memory_kb", "argon2_parallelism", "bcrypt_log_rounds", + "supertokens_saas_load_only_cud" }; Object[] disallowedValues = new Object[]{ 3567, // port @@ -1930,6 +1931,7 @@ public void testAllConflictingConfigs() throws Exception { 87795, // argon2_memory_kb 2, // argon2_parallelism 11, // bcrypt_log_rounds + "mydomain.com", // supertokens_saas_load_only_cud }; process.kill(); @@ -1995,7 +1997,7 @@ public void testAllConflictingConfigs() throws Exception { new Object[]{true, false}, // disable_telemetry new Object[]{"BCRYPT", "ARGON2"}, // password_hashing_alg new Object[]{"abcd1234abcd1234abcd1234abcd1234", "qwer1234qwer1234qwer1234qwer1234"}, // firebase_password_hashing_signer_key - new Object[]{"2.21", "3.0"} // supertokens_max_cdi_version + new Object[]{"2.21", "3.0"}, // supertokens_max_cdi_version }; for (int i=0; i> uniqueUserPoolIdsTenants = StorageLayer.getTenantsWithUniqueUserPoolId(process.getProcess()); + Cronjobs.addCronjob(process.getProcess(), LoadOnlyCUDTest.PerAppCronjob.getInstance(process.getProcess(), uniqueUserPoolIdsTenants)); + + Thread.sleep(3000); + Set appIdentifiersFromCron = PerAppCronjob.getInstance(process.getProcess(), uniqueUserPoolIdsTenants).appIdentifiers; + assertEquals(2, appIdentifiersFromCron.size()); + for (AppIdentifier app : appIdentifiersFromCron) { + assertNotEquals("localhost.org", app.getConnectionUriDomain()); + } + + process.kill(); + assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); + } + + static class PerAppCronjob extends CronTask { + private static final String RESOURCE_ID = "io.supertokens.test.CronjobTest.NormalCronjob"; + + private PerAppCronjob(Main main, List> tenantsInfo) { + super("PerTenantCronjob", main, tenantsInfo, true); + } + + Set appIdentifiers = new HashSet<>(); + + public static LoadOnlyCUDTest.PerAppCronjob getInstance(Main main, List> tenantsInfo) { + try { + return (LoadOnlyCUDTest.PerAppCronjob) main.getResourceDistributor().getResource(new TenantIdentifier(null, null, null), RESOURCE_ID); + } catch (TenantOrAppNotFoundException e) { + return (LoadOnlyCUDTest.PerAppCronjob) main.getResourceDistributor() + .setResource(new TenantIdentifier(null, null, null), RESOURCE_ID, new LoadOnlyCUDTest.PerAppCronjob(main, tenantsInfo)); + } + } + + @Override + public int getIntervalTimeSeconds() { + return 1; + } + + @Override + public int getInitialWaitTimeSeconds() { + return 0; + } + + @Override + protected void doTaskPerApp(AppIdentifier app) throws Exception { + appIdentifiers.add(app); + } + } +} \ No newline at end of file