From 3d85a5cab6e38f41b66d9a6bc2475e81e9e8a434 Mon Sep 17 00:00:00 2001 From: rishabhpoddar Date: Mon, 8 Jul 2024 21:20:55 +0530 Subject: [PATCH] reformats code --- .github/PULL_REQUEST_TEMPLATE.md | 23 +- .github/helpers/package.json | 24 +- .../workflows/github-actions-changelog.yml | 12 +- .github/workflows/lint-pr-title.yml | 30 +- .github/workflows/tests-pass-check-pr.yml | 38 +- .github/workflows/tests.yml | 14 +- CHANGELOG.md | 59 +-- CONTRIBUTING.md | 54 ++- LICENSE.md | 371 +++++++++--------- README.md | 13 +- .../storage/mysql/QueryExecutorTemplate.java | 4 +- .../io/supertokens/storage/mysql/Start.java | 87 ++-- .../storage/mysql/config/Config.java | 4 +- .../storage/mysql/config/MySQLConfig.java | 13 +- .../mysql/queries/ActiveUsersQueries.java | 22 +- .../mysql/queries/DashboardQueries.java | 15 +- .../mysql/queries/EmailPasswordQueries.java | 50 ++- .../queries/EmailVerificationQueries.java | 24 +- .../storage/mysql/queries/GeneralQueries.java | 158 +++++--- .../mysql/queries/JWTSigningQueries.java | 10 +- .../mysql/queries/MultitenancyQueries.java | 47 ++- .../mysql/queries/PasswordlessQueries.java | 69 ++-- .../storage/mysql/queries/SessionQueries.java | 14 +- .../storage/mysql/queries/TOTPQueries.java | 41 +- .../mysql/queries/ThirdPartyQueries.java | 40 +- .../mysql/queries/UserIdMappingQueries.java | 44 ++- .../mysql/queries/UserMetadataQueries.java | 5 +- .../mysql/queries/UserRolesQueries.java | 22 +- .../queries/multitenancy/MfaSqlHelper.java | 21 +- .../multitenancy/TenantConfigSQLHelper.java | 30 +- .../ThirdPartyProviderClientSQLHelper.java | 35 +- .../ThirdPartyProviderSQLHelper.java | 43 +- .../storage/mysql/test/ConfigTest.java | 50 +-- .../mysql/test/DbConnectionPoolTest.java | 7 +- .../storage/mysql/test/DeadlockTest.java | 28 +- .../storage/mysql/test/InMemoryDBTest.java | 33 +- .../storage/mysql/test/LogLevelTest.java | 10 +- .../storage/mysql/test/LoggingTest.java | 33 +- .../mysql/test/OneMillionUsersTest.java | 26 +- .../storage/mysql/test/StorageLayerTest.java | 22 +- .../mysql/test/SuperTokensSaaSSecretTest.java | 15 +- .../storage/mysql/test/TableCreationTest.java | 2 +- .../storage/mysql/test/TestMainThread.java | 5 +- .../mysql/test/TestingProcessManager.java | 5 +- .../httpRequest/HttpRequestForTesting.java | 141 +++---- .../test/multitenancy/StorageLayerTest.java | 3 +- .../TestForNoCrashDuringStartup.java | 63 ++- .../TestUserPoolIdChangeBehaviour.java | 7 +- 48 files changed, 1102 insertions(+), 784 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 4de1c9d..2b22ae8 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,27 +1,38 @@ ## Summary of change + (A few sentences about this PR) ## Related issues + - Link to issue1 here - Link to issue1 here ## Test Plan -(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Bonus points for screenshots and videos!) + +(Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your +changes work. Bonus points for screenshots and videos!) ## Documentation changes -(If relevant, please create a PR in our [docs repo](https://github.com/supertokens/docs), or create a checklist here highlighting the necessary changes) + +(If relevant, please create a PR in our [docs repo](https://github.com/supertokens/docs), or create a checklist here +highlighting the necessary changes) ## Checklist for important updates + - [ ] Changelog has been updated - [ ] `pluginInterfaceSupported.json` file has been updated (if needed) - [ ] Changes to the version if needed - - In `build.gradle` + - In `build.gradle` - [ ] Had installed and ran the pre-commit hook -- [ ] If there are new dependencies that have been added in `build.gradle`, please make sure to add them in `implementationDependencies.json`. +- [ ] If there are new dependencies that have been added in `build.gradle`, please make sure to add them + in `implementationDependencies.json`. - [ ] Issue this PR against the latest non released version branch. - - To know which one it is, run find the latest released tag (`git tag`) in the format `vX.Y.Z`, and then find the latest branch (`git branch --all`) whose `X.Y` is greater than the latest released tag. - - If no such branch exists, then create one from the latest released branch. + - To know which one it is, run find the latest released tag (`git tag`) in the format `vX.Y.Z`, and then find the + latest branch (`git branch --all`) whose `X.Y` is greater than the latest released tag. + - If no such branch exists, then create one from the latest released branch. - [ ] When adding new recipes, ensure that its performance is being measured in the `OneMillionUsersTest` + ## Remaining TODOs for this PR + - [ ] Item1 - [ ] Item2 \ No newline at end of file diff --git a/.github/helpers/package.json b/.github/helpers/package.json index 80ec546..28051cd 100644 --- a/.github/helpers/package.json +++ b/.github/helpers/package.json @@ -1,14 +1,14 @@ { - "name": "helpers", - "version": "1.0.0", - "description": "", - "main": "test-pass-check-pr.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "dependencies": { - "github-workflow-helpers": "github:supertokens/github-workflow-helpers" - } + "name": "helpers", + "version": "1.0.0", + "description": "", + "main": "test-pass-check-pr.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "github-workflow-helpers": "github:supertokens/github-workflow-helpers" + } } \ No newline at end of file diff --git a/.github/workflows/github-actions-changelog.yml b/.github/workflows/github-actions-changelog.yml index 0007ca9..47aaf4a 100644 --- a/.github/workflows/github-actions-changelog.yml +++ b/.github/workflows/github-actions-changelog.yml @@ -1,15 +1,15 @@ name: "Enforcing changelog in PRs Workflow" on: pull_request: - types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ] jobs: # Enforces the update of a changelog file on every pull request changelog: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: dangoslen/changelog-enforcer@v2 - with: - changeLogPath: 'CHANGELOG.md' - skipLabels: 'Skip-Changelog' \ No newline at end of file + - uses: actions/checkout@v2 + - uses: dangoslen/changelog-enforcer@v2 + with: + changeLogPath: 'CHANGELOG.md' + skipLabels: 'Skip-Changelog' \ No newline at end of file diff --git a/.github/workflows/lint-pr-title.yml b/.github/workflows/lint-pr-title.yml index 904efde..96281a7 100644 --- a/.github/workflows/lint-pr-title.yml +++ b/.github/workflows/lint-pr-title.yml @@ -1,20 +1,20 @@ name: "Lint PR Title" on: - pull_request: - types: - - opened - - reopened - - edited - - synchronize + pull_request: + types: + - opened + - reopened + - edited + - synchronize jobs: - pr-title: - name: Lint PR title - runs-on: ubuntu-latest - steps: - - uses: amannn/action-semantic-pull-request@v3 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - validateSingleCommit: true \ No newline at end of file + pr-title: + name: Lint PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + validateSingleCommit: true \ No newline at end of file diff --git a/.github/workflows/tests-pass-check-pr.yml b/.github/workflows/tests-pass-check-pr.yml index 4f03705..07467d9 100644 --- a/.github/workflows/tests-pass-check-pr.yml +++ b/.github/workflows/tests-pass-check-pr.yml @@ -1,24 +1,24 @@ name: "Check if \"Run tests\" action succeeded" on: - pull_request: - types: - - opened - - reopened - - edited - - synchronize + pull_request: + types: + - opened + - reopened + - edited + - synchronize jobs: - pr-run-test-action: - name: Check if "Run tests" action succeeded - timeout-minutes: 60 - concurrency: - group: ${{ github.head_ref }} - cancel-in-progress: true - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: node install - run: cd ./.github/helpers && npm i - - name: Calling github API - run: cd ./.github/helpers && GITHUB_TOKEN=${{ github.token }} REPO=${{ github.repository }} RUN_ID=${{ github.run_id }} BRANCH=${{ github.head_ref }} JOB_ID=${{ github.job }} SOURCE_OWNER=${{ github.event.pull_request.head.repo.owner.login }} CURRENT_SHA=${{ github.event.pull_request.head.sha }} node node_modules/github-workflow-helpers/test-pass-check-pr.js \ No newline at end of file + pr-run-test-action: + name: Check if "Run tests" action succeeded + timeout-minutes: 60 + concurrency: + group: ${{ github.head_ref }} + cancel-in-progress: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: node install + run: cd ./.github/helpers && npm i + - name: Calling github API + run: cd ./.github/helpers && GITHUB_TOKEN=${{ github.token }} REPO=${{ github.repository }} RUN_ID=${{ github.run_id }} BRANCH=${{ github.head_ref }} JOB_ID=${{ github.job }} SOURCE_OWNER=${{ github.event.pull_request.head.repo.owner.login }} CURRENT_SHA=${{ github.event.pull_request.head.sha }} node node_modules/github-workflow-helpers/test-pass-check-pr.js \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9634417..dc2030d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,19 +4,19 @@ on: inputs: coreRepoOwnerName: description: 'supertokens-core repo owner name' - default: supertokens + default: supertokens required: true coreRepoBranch: description: 'supertokens-core repos branch name' - default: master + default: master required: true pluginRepoOwnerName: description: 'supertokens-plugin-interface repo owner name' - default: supertokens + default: supertokens required: true pluginInterfaceBranch: description: 'supertokens-plugin-interface repos branch name' - default: master + default: master required: true jobs: @@ -30,10 +30,10 @@ jobs: mysql: image: mysql:latest env: - MYSQL_DATABASE: supertokens - MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: supertokens + MYSQL_ROOT_PASSWORD: root ports: - - 3306 + - 3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=5 steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index c8b22e1..6818d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,8 +17,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - Support for MFA recipe - Adds `firstFactors` and `requiredSecondaryFactors` for tenant config. - Adds a new `useStaticKey` param to `updateSessionInfo_Transaction` - - This enables smooth switching between `useDynamicAccessTokenSigningKey` settings by allowing refresh calls to - change the signing key type of a session + - This enables smooth switching between `useDynamicAccessTokenSigningKey` settings by allowing refresh calls to + change the signing key type of a session - Fixes performance issue with user pagination ### Migration @@ -56,13 +56,13 @@ ALTER TABLE user_roles - Fixes the issue where passwords were inadvertently logged in the logs. - Adds tests to check connection pool behaviour. -- Adds `mysql_idle_connection_timeout` and `mysql_minimum_idle_connections` configs to control active connections to the database. +- Adds `mysql_idle_connection_timeout` and `mysql_minimum_idle_connections` configs to control active connections to the + database. ## [5.0.5] - 2023-12-06 - Validates db config types in `canBeUsed` function - ## [5.0.4] - 2023-11-10 - Adds index on `app_id_to_user_id` table to improve performance of get user by id queries @@ -95,15 +95,16 @@ CREATE INDEX app_id_to_user_id_user_id_index ON app_id_to_user_id (user_id); ### Changes - Support for Account Linking - - Adds columns `primary_or_recipe_user_id`, `is_linked_or_is_a_primary_user` and `primary_or_recipe_user_time_joined` to `all_auth_recipe_users` table - - Adds columns `primary_or_recipe_user_id` and `is_linked_or_is_a_primary_user` to `app_id_to_user_id` table - - Removes index `all_auth_recipe_users_pagination_index` and addes `all_auth_recipe_users_pagination_index1`, - `all_auth_recipe_users_pagination_index2`, `all_auth_recipe_users_pagination_index3` and - `all_auth_recipe_users_pagination_index4` indexes instead on `all_auth_recipe_users` table - - Adds `all_auth_recipe_users_recipe_id_index` on `all_auth_recipe_users` table - - Adds `all_auth_recipe_users_primary_user_id_index` on `all_auth_recipe_users` table - - Adds `email` column to `emailpassword_pswd_reset_tokens` table - - Changes `user_id` foreign key constraint on `emailpassword_pswd_reset_tokens` to `app_id_to_user_id` table + - Adds columns `primary_or_recipe_user_id`, `is_linked_or_is_a_primary_user` + and `primary_or_recipe_user_time_joined` to `all_auth_recipe_users` table + - Adds columns `primary_or_recipe_user_id` and `is_linked_or_is_a_primary_user` to `app_id_to_user_id` table + - Removes index `all_auth_recipe_users_pagination_index` and addes `all_auth_recipe_users_pagination_index1`, + `all_auth_recipe_users_pagination_index2`, `all_auth_recipe_users_pagination_index3` and + `all_auth_recipe_users_pagination_index4` indexes instead on `all_auth_recipe_users` table + - Adds `all_auth_recipe_users_recipe_id_index` on `all_auth_recipe_users` table + - Adds `all_auth_recipe_users_primary_user_id_index` on `all_auth_recipe_users` table + - Adds `email` column to `emailpassword_pswd_reset_tokens` table + - Changes `user_id` foreign key constraint on `emailpassword_pswd_reset_tokens` to `app_id_to_user_id` table ### Migration @@ -188,16 +189,16 @@ CREATE INDEX app_id_to_user_id_user_id_index ON app_id_to_user_id (user_id); - Fixes duplicate users in users search queries when user is associated to multiple tenants - ## [4.0.0] - 2023-06-02 ### Changes - Support for multitenancy - - New tables `apps` and `tenants` have been added. - - Schema of tables have been changed, adding `app_id` and `tenant_id` columns in tables and constraints & indexes have been modified to include this columns. - - New user tables have been added to map users to apps and tenants. - - New tables for multitenancy have been added. + - New tables `apps` and `tenants` have been added. + - Schema of tables have been changed, adding `app_id` and `tenant_id` columns in tables and constraints & indexes + have been modified to include this columns. + - New user tables have been added to map users to apps and tenants. + - New tables for multitenancy have been added. - Increased transaction retry count to 50 from 20. ### Migration @@ -925,19 +926,19 @@ CREATE INDEX app_id_to_user_id_user_id_index ON app_id_to_user_id (user_id); ### Migration - If using `access_token_signing_key_dynamic` false in the core: - - ```sql - ALTER TABLE session_info ADD COLUMN use_static_key BOOLEAN NOT NULL DEFAULT true; - ALTER TABLE session_info ALTER COLUMN use_static_key DROP DEFAULT; + - ```sql + ALTER TABLE session_info ADD COLUMN use_static_key BOOLEAN NOT NULL DEFAULT true; + ALTER TABLE session_info ALTER COLUMN use_static_key DROP DEFAULT; ``` - - ```sql + - ```sql INSERT INTO jwt_signing_keys(key_id, key_string, algorithm, created_at) select CONCAT('s-', created_at_time) as key_id, value as key_string, 'RS256' as algorithm, created_at_time as created_at from session_access_token_signing_keys; ``` - If using `access_token_signing_key_dynamic` true (or not set) in the core: - - ```sql - ALTER TABLE session_info ADD COLUMN use_static_key BOOLEAN NOT NULL DEFAULT false; - ALTER TABLE session_info ALTER COLUMN use_static_key DROP DEFAULT; + - ```sql + ALTER TABLE session_info ADD COLUMN use_static_key BOOLEAN NOT NULL DEFAULT false; + ALTER TABLE session_info ALTER COLUMN use_static_key DROP DEFAULT; ``` ## [2.4.0] - 2023-03-30 @@ -945,15 +946,17 @@ CREATE INDEX app_id_to_user_id_user_id_index ON app_id_to_user_id (user_id); - Support for Dashboard Search ## [2.3.0] - 2023-03-27 + - Support for TOTP recipe - Support for active users ### Database changes - Add new tables for TOTP recipe: - - `totp_users` that stores the users that have enabled TOTP - - `totp_user_devices` that stores devices (each device has its own secret) for each user - - `totp_used_codes` that stores used codes for each user. This is to implement rate limiting and prevent replay attacks. + - `totp_users` that stores the users that have enabled TOTP + - `totp_user_devices` that stores devices (each device has its own secret) for each user + - `totp_used_codes` that stores used codes for each user. This is to implement rate limiting and prevent replay + attacks. - Add `user_last_active` table to store the last active time of a user. ## [2.2.0] - 2023-02-21 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c03e4a0..12762f3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,30 +1,40 @@ - # Contributing -We're so excited you're interested in helping with SuperTokens! We are happy to help you get started, even if you don't have any previous open-source experience :blush: +We're so excited you're interested in helping with SuperTokens! We are happy to help you get started, even if you don't +have any previous open-source experience :blush: ## New to Open Source? -1. Take a look at [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) -2. Go thorugh the [SuperTokens Code of Conduct](https://github.com/supertokens/supertokens-mysql-plugin/blob/master/CODE_OF_CONDUCT.md) + +1. Take a look + at [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) +2. Go thorugh + the [SuperTokens Code of Conduct](https://github.com/supertokens/supertokens-mysql-plugin/blob/master/CODE_OF_CONDUCT.md) ## Where to ask Questions? -1. Check our [Github Issues](https://github.com/supertokens/supertokens-mysql-plugin/issues) to see if someone has already answered your question. -2. Join our community on [Discord](https://supertokens.io/discord) and feel free to ask us your questions +1. Check our [Github Issues](https://github.com/supertokens/supertokens-mysql-plugin/issues) to see if someone has + already answered your question. +2. Join our community on [Discord](https://supertokens.io/discord) and feel free to ask us your questions ## Development Setup + ### Prerequisites + - OS: Linux or macOS - IDE: Intellij (recommended) or equivalent IDE - MySQL ### Project Setup -1. Setup the `supertokens-core` by following [this guide](https://github.com/supertokens/supertokens-core/blob/master/CONTRIBUTING.md#development-setup). If you are not modifying the `supertokens-core` repo, then you do not need to fork that. + +1. Setup the `supertokens-core` by + following [this guide](https://github.com/supertokens/supertokens-core/blob/master/CONTRIBUTING.md#development-setup). + If you are not modifying the `supertokens-core` repo, then you do not need to fork that. 2. Start MySQL on port `3306`, listening to `locahost` or `0.0.0.0`. 3. Create a MySQL user (if not already exists) with username `root` and password `root` 4. Create a database called `supertokens`. 5. Fork the `supertokens-mysql-plugin` repository -6. Open `modules.txt` in the `supertokens-root` directory and change it so that it looks like (the last line has changed): +6. Open `modules.txt` in the `supertokens-root` directory and change it so that it looks like (the last line has + changed): ``` // put module name like module name,branch name,github username(if contributing with a forked repository) and then call ./loadModules script core,master @@ -32,20 +42,28 @@ We're so excited you're interested in helping with SuperTokens! We are happy to mysql-plugin,master, ``` 7. Run `./loadModules` in the `supertokens-root` directory. This will clone your forked `supertokens-mysql-plugin` repo. -8. Follow the [CONTRIBUTING.md](https://github.com/supertokens/supertokens-core/blob/master/CONTRIBUTING.md#modifying-code) guide from `supertokens-core` repo for modifying and testing. +8. Follow + the [CONTRIBUTING.md](https://github.com/supertokens/supertokens-core/blob/master/CONTRIBUTING.md#modifying-code) + guide from `supertokens-core` repo for modifying and testing. ## Pull Request + 1. Before submitting a pull request make sure all tests have passed -2. Reference the relevant issue or pull request and give a clear description of changes/features added when submitting a pull request +2. Reference the relevant issue or pull request and give a clear description of changes/features added when submitting a + pull request 3. Make sure the PR title follows [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) specification ## SuperTokens Community -SuperTokens is made possible by a passionate team and a strong community of developers. If you have any questions or would like to get more involved in the SuperTokens community you can check out: - - [Github Issues](https://github.com/supertokens/supertokens-mysql-plugin/issues) - - [Discord](https://supertokens.io/discord) - - [Twitter](https://twitter.com/supertokensio) - - or [email us](mailto:team@supertokens.io) - + +SuperTokens is made possible by a passionate team and a strong community of developers. If you have any questions or +would like to get more involved in the SuperTokens community you can check out: + +- [Github Issues](https://github.com/supertokens/supertokens-mysql-plugin/issues) +- [Discord](https://supertokens.io/discord) +- [Twitter](https://twitter.com/supertokensio) +- or [email us](mailto:team@supertokens.io) + Additional resources you might find useful: - - [SuperTokens Docs](https://supertokens.io/docs/community/getting-started/installation) - - [Blog Posts](https://supertokens.io/blog/) + +- [SuperTokens Docs](https://supertokens.io/docs/community/getting-started/installation) +- [Blog Posts](https://supertokens.io/blog/) diff --git a/LICENSE.md b/LICENSE.md index e105852..7a85c9c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,191 +1,192 @@ - Copyright (c) 2020, 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 software except in compliance with the License. A copy - of the License is available below the line. - - 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. +Copyright (c) 2020, 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 software except in compliance with the License. A copy +of the License is available below the line. + +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. ------------------------------------------------------------------------------- + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/README.md b/README.md index b4be068..317b931 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - ![SuperTokens banner](https://raw.githubusercontent.com/supertokens/supertokens-logo/master/images/Artboard%20%E2%80%93%2027%402x.png) # MySQL plugin for SuperTokens Community @@ -8,18 +7,26 @@ alt="chat on Discord"> ## About + This plugin is responsible for interfacing between SuperTokens Community version and an instance of MySQL. Learn more at https://supertokens.io ## Documentation + To see documentation, please click [here](https://supertokens.io/docs/community/introduction). ## Contributing -Please refer to the [CONTRIBUTING.md](https://github.com/supertokens/supertokens-mysql-plugin/blob/master/CONTRIBUTING.md) file in this repo. + +Please refer to +the [CONTRIBUTING.md](https://github.com/supertokens/supertokens-mysql-plugin/blob/master/CONTRIBUTING.md) file in this +repo. ## Contact us -For any queries, or support requests, please email us at team@supertokens.io, or join our [Discord](supertokens.io/discord) server. + +For any queries, or support requests, please email us at team@supertokens.io, or join +our [Discord](supertokens.io/discord) server. # Authors + Created with :heart: by the folks at SuperTokens.io. diff --git a/src/main/java/io/supertokens/storage/mysql/QueryExecutorTemplate.java b/src/main/java/io/supertokens/storage/mysql/QueryExecutorTemplate.java index 91d8760..50e7325 100644 --- a/src/main/java/io/supertokens/storage/mysql/QueryExecutorTemplate.java +++ b/src/main/java/io/supertokens/storage/mysql/QueryExecutorTemplate.java @@ -26,14 +26,14 @@ public interface QueryExecutorTemplate { static T execute(Start start, String QUERY, PreparedStatementValueSetter setter, - ResultSetValueExtractor mapper) throws SQLException, StorageQueryException { + ResultSetValueExtractor mapper) throws SQLException, StorageQueryException { try (Connection con = ConnectionPool.getConnection(start)) { return execute(con, QUERY, setter, mapper); } } static T execute(Connection con, String QUERY, PreparedStatementValueSetter setter, - ResultSetValueExtractor mapper) throws SQLException, StorageQueryException { + ResultSetValueExtractor mapper) throws SQLException, StorageQueryException { if (setter == null) setter = PreparedStatementValueSetter.NO_OP_SETTER; try (PreparedStatement pst = con.prepareStatement(QUERY)) { diff --git a/src/main/java/io/supertokens/storage/mysql/Start.java b/src/main/java/io/supertokens/storage/mysql/Start.java index 2ac5ff5..050a82b 100644 --- a/src/main/java/io/supertokens/storage/mysql/Start.java +++ b/src/main/java/io/supertokens/storage/mysql/Start.java @@ -45,7 +45,7 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; -import io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo; +import io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo; import io.supertokens.pluginInterface.jwt.exceptions.DuplicateKeyIdException; import io.supertokens.pluginInterface.jwt.sqlstorage.JWTRecipeSQLStorage; import io.supertokens.pluginInterface.multitenancy.*; @@ -155,7 +155,8 @@ public STORAGE_TYPE getType() { } @Override - public void loadConfig(JsonObject configJson, Set logLevels, TenantIdentifier tenantIdentifier) throws InvalidConfigException { + public void loadConfig(JsonObject configJson, Set logLevels, TenantIdentifier tenantIdentifier) + throws InvalidConfigException { Config.loadConfig(this, configJson, logLevels, tenantIdentifier); } @@ -277,7 +278,8 @@ public T startTransaction(TransactionLogic logic, TransactionIsolationLev // happen } if ((e instanceof SQLTransactionRollbackException - || (e.getMessage() != null && e.getMessage().toLowerCase().contains("deadlock"))) && tries == NUM_TRIES) { + || (e.getMessage() != null && e.getMessage().toLowerCase().contains("deadlock"))) && + tries == NUM_TRIES) { ProcessState.getInstance(this).addState(ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED, e); } if (e instanceof StorageQueryException) { @@ -749,7 +751,8 @@ public boolean isUserIdBeingUsedInNonAuthRecipe(AppIdentifier appIdentifier, Str @TestOnly @Override - public void addInfoToNonAuthRecipesBasedOnUserId(TenantIdentifier tenantIdentifier, String className, String userId) throws StorageQueryException { + public void addInfoToNonAuthRecipesBasedOnUserId(TenantIdentifier tenantIdentifier, String className, String userId) + throws StorageQueryException { if (!isTesting) { throw new UnsupportedOperationException(); } @@ -812,14 +815,15 @@ public void addInfoToNonAuthRecipesBasedOnUserId(TenantIdentifier tenantIdentifi } } else if (className.equals(TOTPStorage.class.getName())) { try { - TOTPDevice device = new TOTPDevice(userId, "testDevice", "secret", 0, 30, false, System.currentTimeMillis()); + TOTPDevice device = new TOTPDevice(userId, "testDevice", "secret", 0, 30, false, + System.currentTimeMillis()); this.startTransaction(con -> { try { long now = System.currentTimeMillis(); Connection sqlCon = (Connection) con.getConnection(); TOTPQueries.createDevice_Transaction(this, sqlCon, tenantIdentifier.toAppIdentifier(), device); TOTPQueries.insertUsedCode_Transaction(this, - sqlCon, tenantIdentifier, new TOTPUsedCode(userId, "123456", true, 1000+now, now)); + sqlCon, tenantIdentifier, new TOTPUsedCode(userId, "123456", true, 1000 + now, now)); } catch (SQLException e) { throw new StorageTransactionLogicException(e); } @@ -854,7 +858,7 @@ public String[] getProtectedConfigsFromSuperTokensSaaSUsers() { @Override public AuthRecipeUserInfo signUp(TenantIdentifier tenantIdentifier, String id, String email, String passwordHash, - long timeJoined) + long timeJoined) throws StorageQueryException, DuplicateUserIdException, DuplicateEmailException, TenantOrAppNotFoundException { try { @@ -1162,8 +1166,10 @@ public boolean isEmailVerified(AppIdentifier appIdentifier, String userId, Strin } @Override - public void updateIsEmailVerifiedToExternalUserId(AppIdentifier appIdentifier, String supertokensUserId, String externalUserId) throws StorageQueryException { - EmailVerificationQueries.updateIsEmailVerifiedToExternalUserId(this, appIdentifier, supertokensUserId, externalUserId); + public void updateIsEmailVerifiedToExternalUserId(AppIdentifier appIdentifier, String supertokensUserId, + String externalUserId) throws StorageQueryException { + EmailVerificationQueries.updateIsEmailVerifiedToExternalUserId(this, appIdentifier, supertokensUserId, + externalUserId); } @Override @@ -1301,7 +1307,7 @@ public int countUsersActiveSince(AppIdentifier appIdentifier, long time) throws } } - @Override + @Override public void deleteUserActive_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) throws StorageQueryException { try { @@ -1423,7 +1429,7 @@ private boolean isForeignKeyConstraintError(String serverMessage, String tableNa public boolean isPrimaryKeyError(String serverMessage, String tableName) { return serverMessage.endsWith("'" + tableName + ".PRIMARY'") - || serverMessage.endsWith("'PRIMARY'"); + || serverMessage.endsWith("'PRIMARY'"); } private boolean isPrimaryKeyError(String serverMessage, String tableName, String value) { @@ -1671,10 +1677,10 @@ public void createCode(TenantIdentifier tenantIdentifier, PasswordlessCode code) @Override public AuthRecipeUserInfo createUser(TenantIdentifier tenantIdentifier, - String id, - @javax.annotation.Nullable String email, - @javax.annotation.Nullable - String phoneNumber, long timeJoined) + String id, + @javax.annotation.Nullable String email, + @javax.annotation.Nullable + String phoneNumber, long timeJoined) throws StorageQueryException, DuplicateEmailException, DuplicatePhoneNumberException, DuplicateUserIdException, TenantOrAppNotFoundException { @@ -2204,7 +2210,8 @@ public void createTenant(TenantConfig tenantConfig) try { MultitenancyQueries.createTenantConfig(this, tenantConfig); } catch (StorageTransactionLogicException e) { - // We are not doing PRIMARY KEY checks here as there are multiple insert queries happening on multiple tables + // We are not doing PRIMARY KEY checks here as there are multiple insert queries happening on multiple + // tables // and it is easier to catch which PRIMARY KEY failed around the insert query itself. if (e.actualException instanceof DuplicateTenantException) { throw (DuplicateTenantException) e.actualException; @@ -2262,7 +2269,8 @@ public void overwriteTenantConfig(TenantConfig tenantConfig) try { MultitenancyQueries.overwriteTenantConfig(this, tenantConfig); } catch (StorageTransactionLogicException e) { - // We are not doing PRIMARY KEY checks here as there are multiple insert queries happening on multiple tables + // We are not doing PRIMARY KEY checks here as there are multiple insert queries happening on multiple + // tables // and it is easier to catch which PRIMARY KEY failed around the insert query itself. if (e.actualException instanceof TenantOrAppNotFoundException) { throw (TenantOrAppNotFoundException) e.actualException; @@ -2306,7 +2314,8 @@ public TenantConfig[] getAllTenants() throws StorageQueryException { } @Override - public boolean addUserIdToTenant_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con, String userId) + public boolean addUserIdToTenant_Transaction(TenantIdentifier tenantIdentifier, TransactionConnection con, + String userId) throws TenantOrAppNotFoundException, UnknownUserIdException, StorageQueryException, DuplicateEmailException, DuplicateThirdPartyUserException, DuplicatePhoneNumberException { Connection sqlCon = (Connection) con.getConnection(); @@ -2321,12 +2330,12 @@ public boolean addUserIdToTenant_Transaction(TenantIdentifier tenantIdentifier, boolean added; if (recipeId.equals("emailpassword")) { added = EmailPasswordQueries.addUserIdToTenant_Transaction(this, sqlCon, tenantIdentifier, - userId); + userId); } else if (recipeId.equals("thirdparty")) { added = ThirdPartyQueries.addUserIdToTenant_Transaction(this, sqlCon, tenantIdentifier, userId); } else if (recipeId.equals("passwordless")) { added = PasswordlessQueries.addUserIdToTenant_Transaction(this, sqlCon, tenantIdentifier, - userId); + userId); } else { throw new IllegalStateException("Should never come here!"); } @@ -2343,7 +2352,8 @@ public boolean addUserIdToTenant_Transaction(TenantIdentifier tenantIdentifier, if (isUniqueConstraintError(serverErrorMessage, config.getEmailPasswordUserToTenantTable(), "email")) { throw new DuplicateEmailException(); } - if (isUniqueConstraintError(serverErrorMessage, config.getThirdPartyUserToTenantTable(), "third_party_user_id")) { + if (isUniqueConstraintError(serverErrorMessage, config.getThirdPartyUserToTenantTable(), + "third_party_user_id")) { throw new DuplicateThirdPartyUserException(); } if (isUniqueConstraintError(serverErrorMessage, @@ -2598,7 +2608,8 @@ public void createDevice(AppIdentifier appIdentifier, TOTPDevice device) } @Override - public TOTPDevice createDevice_Transaction(TransactionConnection con, AppIdentifier appIdentifier, TOTPDevice device) + public TOTPDevice createDevice_Transaction(TransactionConnection con, AppIdentifier appIdentifier, + TOTPDevice device) throws DeviceAlreadyExistsException, TenantOrAppNotFoundException, StorageQueryException { Connection sqlCon = (Connection) con.getConnection(); try { @@ -2620,7 +2631,8 @@ public TOTPDevice createDevice_Transaction(TransactionConnection con, AppIdentif } @Override - public TOTPDevice getDeviceByName_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, String deviceName) throws StorageQueryException { + public TOTPDevice getDeviceByName_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, + String deviceName) throws StorageQueryException { Connection sqlCon = (Connection) con.getConnection(); try { return TOTPQueries.getDeviceByName_Transaction(this, sqlCon, appIdentifier, userId, deviceName); @@ -2693,7 +2705,7 @@ public void updateDeviceName(AppIdentifier appIdentifier, String userId, String throw new DeviceAlreadyExistsException(); } } - throw new StorageQueryException(e); + throw new StorageQueryException(e); } } @@ -2732,7 +2744,8 @@ public void insertUsedCode_Transaction(TransactionConnection con, TenantIdentifi } else if (isForeignKeyConstraintError(e.getMessage(), Config.getConfig(this).getTotpUsedCodesTable(), "user_id")) { throw new UnknownTotpUserIdException(); - } else if (isForeignKeyConstraintError(e.getMessage(), Config.getConfig(this).getTotpUsedCodesTable(), "tenant_id")) { + } else if (isForeignKeyConstraintError(e.getMessage(), Config.getConfig(this).getTotpUsedCodesTable(), + "tenant_id")) { throw new TenantOrAppNotFoundException(tenantIdentifier); } @@ -2893,7 +2906,8 @@ public void linkAccounts_Transaction(AppIdentifier appIdentifier, TransactionCon } @Override - public void unlinkAccounts_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String primaryUserId, String recipeUserId) + public void unlinkAccounts_Transaction(AppIdentifier appIdentifier, TransactionConnection con, String primaryUserId, + String recipeUserId) throws StorageQueryException { try { Connection sqlCon = (Connection) con.getConnection(); @@ -2926,7 +2940,8 @@ public boolean checkIfUsesAccountLinking(AppIdentifier appIdentifier) throws Sto } @Override - public int countUsersThatHaveMoreThanOneLoginMethodAndActiveSince(AppIdentifier appIdentifier, long sinceTime) throws StorageQueryException { + public int countUsersThatHaveMoreThanOneLoginMethodAndActiveSince(AppIdentifier appIdentifier, long sinceTime) + throws StorageQueryException { try { return ActiveUsersQueries.countUsersActiveSinceAndHasMoreThanOneLoginMethod(this, appIdentifier, sinceTime); } catch (SQLException e) { @@ -2955,11 +2970,13 @@ public UserIdMapping getUserIdMapping_Transaction(TransactionConnection con, App try { Connection sqlCon = (Connection) con.getConnection(); if (isSuperTokensUserId) { - return UserIdMappingQueries.getuseraIdMappingWithSuperTokensUserId_Transaction(this, sqlCon, appIdentifier, + return UserIdMappingQueries.getuseraIdMappingWithSuperTokensUserId_Transaction(this, sqlCon, + appIdentifier, userId); } - return UserIdMappingQueries.getUserIdMappingWithExternalUserId_Transaction(this, sqlCon, appIdentifier, userId); + return UserIdMappingQueries.getUserIdMappingWithExternalUserId_Transaction(this, sqlCon, appIdentifier, + userId); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -2980,7 +2997,8 @@ public UserIdMapping[] getUserIdMapping_Transaction(TransactionConnection con, A } @Override - public int getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(AppIdentifier appIdentifier) throws StorageQueryException { + public int getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(AppIdentifier appIdentifier) + throws StorageQueryException { try { return GeneralQueries.getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(this, appIdentifier); } catch (SQLException e) { @@ -2989,9 +3007,12 @@ public int getUsersCountWithMoreThanOneLoginMethodOrTOTPEnabled(AppIdentifier ap } @Override - public int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(AppIdentifier appIdentifier, long sinceTime) throws StorageQueryException { + public int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(AppIdentifier appIdentifier, + long sinceTime) + throws StorageQueryException { try { - return ActiveUsersQueries.countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(this, appIdentifier, sinceTime); + return ActiveUsersQueries.countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(this, + appIdentifier, sinceTime); } catch (SQLException e) { throw new StorageQueryException(e); } @@ -3003,7 +3024,7 @@ public static boolean isEnabledForDeadlockTesting() { @TestOnly public static void setEnableForDeadlockTesting(boolean value) { - assert(isTesting); + assert (isTesting); enableForDeadlockTesting = value; } diff --git a/src/main/java/io/supertokens/storage/mysql/config/Config.java b/src/main/java/io/supertokens/storage/mysql/config/Config.java index 41cef1f..a45a912 100644 --- a/src/main/java/io/supertokens/storage/mysql/config/Config.java +++ b/src/main/java/io/supertokens/storage/mysql/config/Config.java @@ -53,7 +53,8 @@ private static Config getInstance(Start start) { return (Config) start.getResourceDistributor().getResource(RESOURCE_KEY); } - public static void loadConfig(Start start, JsonObject configJson, Set logLevels, TenantIdentifier tenantIdentifier) + public static void loadConfig(Start start, JsonObject configJson, Set logLevels, + TenantIdentifier tenantIdentifier) throws InvalidConfigException { if (getInstance(start) != null) { return; @@ -93,6 +94,7 @@ public static MySQLConfig getConfig(Start start) { public static Set getLogLevels(Start start) { return getInstance(start).logLevels; } + public static void setLogLevels(Start start, Set logLevels) { getInstance(start).logLevels = logLevels; } diff --git a/src/main/java/io/supertokens/storage/mysql/config/MySQLConfig.java b/src/main/java/io/supertokens/storage/mysql/config/MySQLConfig.java index 52bc3fe..1ff78b8 100644 --- a/src/main/java/io/supertokens/storage/mysql/config/MySQLConfig.java +++ b/src/main/java/io/supertokens/storage/mysql/config/MySQLConfig.java @@ -352,7 +352,7 @@ void validateAndNormalise() throws InvalidConfigException { throw new InvalidConfigException( "'mysql_minimum_idle_connections' must be a >= 0"); } - + if (mysql_minimum_idle_connections > mysql_connection_pool_size) { throw new InvalidConfigException( "'mysql_minimum_idle_connections' must be less than or equal to " @@ -499,7 +499,8 @@ void validateAndNormalise() throws InvalidConfigException { } if (mysql_emailverification_verified_emails_table_name == null) { - mysql_emailverification_verified_emails_table_name = addPrefixToTableName("emailverification_verified_emails"); + mysql_emailverification_verified_emails_table_name = addPrefixToTableName( + "emailverification_verified_emails"); } if (mysql_thirdparty_users_table_name == null) { @@ -509,7 +510,8 @@ void validateAndNormalise() throws InvalidConfigException { isValidAndNormalised = true; } - public void assertThatConfigFromSameUserPoolIsNotConflicting(MySQLConfig otherConfig) throws InvalidConfigException { + public void assertThatConfigFromSameUserPoolIsNotConflicting(MySQLConfig otherConfig) + throws InvalidConfigException { for (Field field : MySQLConfig.class.getDeclaredFields()) { if (field.isAnnotationPresent(NotConflictingWithinUserPool.class)) { try { @@ -549,10 +551,11 @@ public String getConnectionPoolId() { try { String fieldName = field.getName(); String fieldValue = field.get(this) != null ? field.get(this).toString() : null; - if(fieldValue == null) { + if (fieldValue == null) { continue; } - // To ensure a unique connectionPoolId we include the database password and use the "|db_pass|" identifier. + // To ensure a unique connectionPoolId we include the database password and use the "|db_pass|" + // identifier. // This facilitates easy removal of the password from logs when necessary. if (fieldName.equals("mysql_password")) { connectionPoolId.append("|db_pass|" + fieldValue + "|db_pass"); diff --git a/src/main/java/io/supertokens/storage/mysql/queries/ActiveUsersQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/ActiveUsersQueries.java index 1905ec2..3e51e81 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/ActiveUsersQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/ActiveUsersQueries.java @@ -23,7 +23,8 @@ static String getQueryToCreateUserLastActiveTable(Start start) { + " );"; } - public static int countUsersActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) throws SQLException, StorageQueryException { + public static int countUsersActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) + throws SQLException, StorageQueryException { String QUERY = "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getUserLastActiveTable() + " WHERE app_id = ? AND last_active_time >= ?"; @@ -38,7 +39,8 @@ public static int countUsersActiveSince(Start start, AppIdentifier appIdentifier }); } - public static int countUsersActiveSinceAndHasMoreThanOneLoginMethod(Start start, AppIdentifier appIdentifier, long sinceTime) + public static int countUsersActiveSinceAndHasMoreThanOneLoginMethod(Start start, AppIdentifier appIdentifier, + long sinceTime) throws SQLException, StorageQueryException { String QUERY = "SELECT count(1) as c FROM (" + " SELECT count(user_id) as num_login_methods, app_id, primary_or_recipe_user_id" @@ -77,10 +79,11 @@ public static int countUsersEnabledTotp(Start start, AppIdentifier appIdentifier public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) throws SQLException, StorageQueryException { - String QUERY = "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable() + " AS totp_users " - + "INNER JOIN " + Config.getConfig(start).getUserLastActiveTable() + " AS user_last_active " - + "ON totp_users.user_id = user_last_active.user_id " - + "WHERE user_last_active.app_id = ? AND user_last_active.last_active_time >= ?"; + String QUERY = + "SELECT COUNT(*) as total FROM " + Config.getConfig(start).getTotpUsersTable() + " AS totp_users " + + "INNER JOIN " + Config.getConfig(start).getUserLastActiveTable() + " AS user_last_active " + + "ON totp_users.user_id = user_last_active.user_id " + + "WHERE user_last_active.app_id = ? AND user_last_active.last_active_time >= ?"; return execute(start, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -93,7 +96,8 @@ public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier }); } - public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId) + throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getUserLastActiveTable() + "(app_id, user_id, last_active_time) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE last_active_time = ?"; @@ -138,7 +142,9 @@ public static void deleteUserActive_Transaction(Connection con, Start start, App }); } - public static int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) + public static int countUsersThatHaveMoreThanOneLoginMethodOrTOTPEnabledAndActiveSince(Start start, + AppIdentifier appIdentifier, + long sinceTime) throws SQLException, StorageQueryException { // TODO: Active users are present only on public tenant and MFA users may be present on different storages String QUERY = diff --git a/src/main/java/io/supertokens/storage/mysql/queries/DashboardQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/DashboardQueries.java index 3978be7..7e623b4 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/DashboardQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/DashboardQueries.java @@ -100,7 +100,8 @@ public static boolean deleteDashboardUserWithUserId(Start start, AppIdentifier a } - public static DashboardUser[] getAllDashBoardUsers(Start start, AppIdentifier appIdentifier) throws SQLException, StorageQueryException { + public static DashboardUser[] getAllDashBoardUsers(Start start, AppIdentifier appIdentifier) + throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getDashboardUsersTable() + " WHERE app_id = ? ORDER BY time_joined ASC"; return QueryExecutorTemplate.execute(start, QUERY, @@ -153,7 +154,8 @@ public static boolean updateDashboardUsersPasswordWithUserId_Transaction(Start s return rowsUpdated > 0; } - public static void createDashboardSession(Start start, AppIdentifier appIdentifier, String userId, String sessionId, long timeCreated, + public static void createDashboardSession(Start start, AppIdentifier appIdentifier, String userId, String sessionId, + long timeCreated, long expiry) throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getDashboardSessionsTable() + "(app_id, user_id, session_id, time_created, expiry)" + " VALUES(?, ?, ?, ?, ?)"; @@ -166,7 +168,8 @@ public static void createDashboardSession(Start start, AppIdentifier appIdentifi }); } - public static DashboardSessionInfo getSessionInfoWithSessionId(Start start, AppIdentifier appIdentifier, String sessionId) + public static DashboardSessionInfo getSessionInfoWithSessionId(Start start, AppIdentifier appIdentifier, + String sessionId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getDashboardSessionsTable() + " WHERE app_id = ? AND session_id = ?"; @@ -181,7 +184,8 @@ public static DashboardSessionInfo getSessionInfoWithSessionId(Start start, AppI }); } - public static DashboardSessionInfo[] getAllSessionsForUserId(Start start, AppIdentifier appIdentifier, String userId) + public static DashboardSessionInfo[] getAllSessionsForUserId(Start start, AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getDashboardSessionsTable() + " WHERE app_id = ? AND user_id = ?"; @@ -215,7 +219,8 @@ public static DashboardUser getDashboardUserByEmail(Start start, AppIdentifier a }); } - public static boolean deleteDashboardUserSessionWithSessionId(Start start, AppIdentifier appIdentifier, String sessionId) + public static boolean deleteDashboardUserSessionWithSessionId(Start start, AppIdentifier appIdentifier, + String sessionId) throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + Config.getConfig(start).getDashboardSessionsTable() + " WHERE app_id = ? AND session_id = ?"; diff --git a/src/main/java/io/supertokens/storage/mysql/queries/EmailPasswordQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/EmailPasswordQueries.java index 3fc0db3..1380efd 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/EmailPasswordQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/EmailPasswordQueries.java @@ -51,7 +51,8 @@ static String getQueryToCreateUsersTable(Start start) { + "time_joined BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, user_id)," + "FOREIGN KEY(app_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + " (app_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + + " (app_id, user_id) ON DELETE CASCADE" + ");"; } @@ -66,7 +67,8 @@ static String getQueryToCreateEmailPasswordUserToTenantTable(Start start) { + "CONSTRAINT email UNIQUE (app_id, tenant_id, email)," + "PRIMARY KEY (app_id, tenant_id, user_id)," + "FOREIGN KEY (app_id, tenant_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getUsersTable() + "(app_id, tenant_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getUsersTable() + + "(app_id, tenant_id, user_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -151,7 +153,7 @@ public static PasswordResetTokenInfo[] getAllPasswordResetTokenInfoForUser(Start throws StorageQueryException, SQLException { String QUERY = "SELECT user_id, token, token_expiry, email FROM " + getConfig(start).getPasswordResetTokensTable() - + " WHERE app_id = ? AND user_id = ?"; + + " WHERE app_id = ? AND user_id = ?"; return execute(start, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -176,7 +178,7 @@ public static PasswordResetTokenInfo[] getAllPasswordResetTokenInfoForUser_Trans String QUERY = "SELECT user_id, token, token_expiry, email FROM " + getConfig(start).getPasswordResetTokensTable() - + " WHERE app_id = ? AND user_id = ? FOR UPDATE"; + + " WHERE app_id = ? AND user_id = ? FOR UPDATE"; return execute(con, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -199,7 +201,7 @@ public static PasswordResetTokenInfo getPasswordResetTokenInfo(Start start, AppI throws SQLException, StorageQueryException { String QUERY = "SELECT user_id, token, token_expiry, email FROM " + getConfig(start).getPasswordResetTokensTable() - + " WHERE app_id = ? AND token = ?"; + + " WHERE app_id = ? AND token = ?"; return execute(start, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); pst.setString(2, token); @@ -257,7 +259,9 @@ public static AuthRecipeUserInfo signUp(Start start, TenantIdentifier tenantIden { // all_auth_recipe_users String QUERY = "INSERT INTO " + getConfig(start).getUsersTable() - + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, " + + "primary_or_recipe_user_time_joined)" + " VALUES(?, ?, ?, ?, ?, ?, ?)"; update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); @@ -313,10 +317,10 @@ public static void deleteUser_Transaction(Connection sqlCon, Start start, AppIde String QUERY = "DELETE FROM " + getConfig(start).getAppIdToUserIdTable() + " WHERE app_id = ? AND user_id = ?"; - update(sqlCon, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, userId); - }); + update(sqlCon, QUERY, pst -> { + pst.setString(1, appIdentifier.getAppId()); + pst.setString(2, userId); + }); } else { { String QUERY = "DELETE FROM " + getConfig(start).getUsersTable() @@ -347,8 +351,10 @@ public static void deleteUser_Transaction(Connection sqlCon, Start start, AppIde } } - private static UserInfoPartial getUserInfoUsingId_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, - String id) throws SQLException, StorageQueryException { + private static UserInfoPartial getUserInfoUsingId_Transaction(Start start, Connection sqlCon, + AppIdentifier appIdentifier, + String id) + throws SQLException, StorageQueryException { // we don't need a FOR UPDATE here because this is already part of a transaction, and locked on // app_id_to_user_id table String QUERY = "SELECT user_id, email, password_hash, time_joined FROM " @@ -398,7 +404,7 @@ public static List getUsersInfoUsingIdList(Start start, Set } public static List getUsersInfoUsingIdList_Transaction(Start start, Connection con, Set ids, - AppIdentifier appIdentifier) + AppIdentifier appIdentifier) throws SQLException, StorageQueryException { if (ids.size() > 0) { // No need to filter based on tenantId because the id list is already filtered for a tenant @@ -428,6 +434,7 @@ public static List getUsersInfoUsingIdList_Transaction(Start start, } return Collections.emptyList(); } + public static String lockEmail_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String email) @@ -447,7 +454,7 @@ public static String lockEmail_Transaction(Start start, Connection con, } public static String getPrimaryUserIdUsingEmail(Start start, TenantIdentifier tenantIdentifier, - String email) + String email) throws StorageQueryException, SQLException { String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + "FROM " + getConfig(start).getEmailPasswordUserToTenantTable() + " AS ep" + @@ -467,8 +474,9 @@ public static String getPrimaryUserIdUsingEmail(Start start, TenantIdentifier te }); } - public static List getPrimaryUserIdsUsingEmail_Transaction(Start start, Connection con, AppIdentifier appIdentifier, - String email) + public static List getPrimaryUserIdsUsingEmail_Transaction(Start start, Connection con, + AppIdentifier appIdentifier, + String email) throws StorageQueryException, SQLException { String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + "FROM " + getConfig(start).getEmailPasswordUsersTable() + " AS ep" + @@ -498,12 +506,15 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC throw new UnknownUserIdException(); } - GeneralQueries.AccountLinkingInfo accountLinkingInfo = GeneralQueries.getAccountLinkingInfo_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), userId); + GeneralQueries.AccountLinkingInfo accountLinkingInfo = GeneralQueries.getAccountLinkingInfo_Transaction(start, + sqlCon, tenantIdentifier.toAppIdentifier(), userId); { // all_auth_recipe_users // ON CONFLICT DO NOTHING String QUERY = "INSERT INTO " + getConfig(start).getUsersTable() - + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, is_linked_or_is_a_primary_user, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, is_linked_or_is_a_primary_user, " + + "recipe_id, time_joined, primary_or_recipe_user_time_joined)" + " SELECT ?, ?, ?, ?, ?, ?, ?, ? WHERE NOT EXISTS (" + " SELECT app_id, tenant_id, user_id FROM " + getConfig(start).getUsersTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?" @@ -524,7 +535,8 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC pst.setString(11, userId); }); - GeneralQueries.updateTimeJoinedForPrimaryUser_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), finalAccountLinkingInfo.primaryUserId); + GeneralQueries.updateTimeJoinedForPrimaryUser_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), + finalAccountLinkingInfo.primaryUserId); } { // emailpassword_user_to_tenant diff --git a/src/main/java/io/supertokens/storage/mysql/queries/EmailVerificationQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/EmailVerificationQueries.java index 5941063..b612b00 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/EmailVerificationQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/EmailVerificationQueries.java @@ -46,7 +46,7 @@ static String getQueryToCreateEmailVerificationTable(Start start) { + "email VARCHAR(256) NOT NULL," + "PRIMARY KEY (app_id, user_id, email)," + "FOREIGN KEY(app_id)" - + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + ");"; } @@ -60,7 +60,7 @@ static String getQueryToCreateEmailVerificationTokensTable(Start start) { + "token_expiry BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, tenant_id, user_id, email, token)," + "FOREIGN KEY(app_id, tenant_id)" - + " REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE" + ")"; } @@ -221,7 +221,8 @@ public static boolean isEmailVerified(Start start, AppIdentifier appIdentifier, }, result -> result.next()); } - public static void updateIsEmailVerifiedToExternalUserId(Start start, AppIdentifier appIdentifier, String supertokensUserId, String externalUserId) + public static void updateIsEmailVerifiedToExternalUserId(Start start, AppIdentifier appIdentifier, + String supertokensUserId, String externalUserId) throws StorageQueryException { try { start.startTransaction((TransactionConnection con) -> { @@ -283,8 +284,10 @@ public static List isEmailVerified_transaction(Start start, Connection s // We have external user id stored in the email verification table, so we need to fetch the mapped userids for // calculating the verified emails - HashMap supertokensUserIdToExternalUserIdMap = UserIdMappingQueries.getUserIdMappingWithUserIds_Transaction(start, - sqlCon, appIdentifier, supertokensUserIds); + HashMap supertokensUserIdToExternalUserIdMap = + UserIdMappingQueries.getUserIdMappingWithUserIds_Transaction( + start, + sqlCon, appIdentifier, supertokensUserIds); HashMap externalUserIdToSupertokensUserIdMap = new HashMap<>(); List supertokensOrExternalUserIdsToQuery = new ArrayList<>(); @@ -311,7 +314,8 @@ public static List isEmailVerified_transaction(Start start, Connection s } String QUERY = "SELECT * FROM " + getConfig(start).getEmailVerificationTable() - + " WHERE app_id = ? AND user_id IN (" + Utils.generateCommaSeperatedQuestionMarks(supertokensOrExternalUserIdsToQuery.size()) + + + " WHERE app_id = ? AND user_id IN (" + + Utils.generateCommaSeperatedQuestionMarks(supertokensOrExternalUserIdsToQuery.size()) + ") AND email IN (" + Utils.generateCommaSeperatedQuestionMarks(emails.size()) + ")"; return execute(sqlCon, QUERY, pst -> { @@ -337,7 +341,7 @@ public static List isEmailVerified_transaction(Start start, Connection s } public static List isEmailVerified(Start start, AppIdentifier appIdentifier, - List userIdAndEmail) + List userIdAndEmail) throws SQLException, StorageQueryException { if (userIdAndEmail.isEmpty()) { return new ArrayList<>(); @@ -351,7 +355,8 @@ public static List isEmailVerified(Start start, AppIdentifier appIdentif } // We have external user id stored in the email verification table, so we need to fetch the mapped userids for // calculating the verified emails - HashMap supertokensUserIdToExternalUserIdMap = UserIdMappingQueries.getUserIdMappingWithUserIds(start, + HashMap supertokensUserIdToExternalUserIdMap = UserIdMappingQueries.getUserIdMappingWithUserIds( + start, appIdentifier, supertokensUserIds); HashMap externalUserIdToSupertokensUserIdMap = new HashMap<>(); List supertokensOrExternalUserIdsToQuery = new ArrayList<>(); @@ -377,7 +382,8 @@ public static List isEmailVerified(Start start, AppIdentifier appIdentif supertokensOrExternalUserIdToEmailMap.put(supertokensOrExternalUserId, ue.email); } String QUERY = "SELECT * FROM " + getConfig(start).getEmailVerificationTable() - + " WHERE app_id = ? AND user_id IN (" + Utils.generateCommaSeperatedQuestionMarks(supertokensOrExternalUserIdsToQuery.size()) + + + " WHERE app_id = ? AND user_id IN (" + + Utils.generateCommaSeperatedQuestionMarks(supertokensOrExternalUserIdsToQuery.size()) + ") AND email IN (" + Utils.generateCommaSeperatedQuestionMarks(emails.size()) + ")"; return execute(start, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); diff --git a/src/main/java/io/supertokens/storage/mysql/queries/GeneralQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/GeneralQueries.java index 8df206c..05d5a9d 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/GeneralQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/GeneralQueries.java @@ -90,9 +90,11 @@ static String getQueryToCreateUsersTable(Start start) { + "FOREIGN KEY(app_id, tenant_id)" + " REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE," + "FOREIGN KEY(app_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + " (app_id, user_id) ON DELETE CASCADE," + + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + + " (app_id, user_id) ON DELETE CASCADE," + "FOREIGN KEY(app_id, primary_or_recipe_user_id)" - + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + " (app_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + + " (app_id, user_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -108,7 +110,9 @@ static String getQueryToCreateUserPaginationIndex1(Start start) { static String getQueryToCreateUserPaginationIndex3(Start start) { return "CREATE INDEX all_auth_recipe_users_pagination_index3 ON " + Config.getConfig(start).getUsersTable() - + "(recipe_id, app_id, tenant_id, primary_or_recipe_user_time_joined DESC, primary_or_recipe_user_id DESC);"; + + + "(recipe_id, app_id, tenant_id, primary_or_recipe_user_time_joined DESC, primary_or_recipe_user_id " + + "DESC);"; } static String getQueryToCreatePrimaryUserId(Start start) { @@ -184,7 +188,8 @@ private static String getQueryToCreateAppIdToUserIdTable(Start start) { + "FOREIGN KEY (app_id)" + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE," + "FOREIGN KEY(app_id, primary_or_recipe_user_id)" - + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + " (app_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + + " (app_id, user_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -505,7 +510,7 @@ public static long getUsersCount(Start start, AppIdentifier appIdentifier, RECIP throws SQLException, StorageQueryException { StringBuilder QUERY = new StringBuilder( "SELECT COUNT(DISTINCT primary_or_recipe_user_id) AS total FROM " + - Config.getConfig(start).getUsersTable()); + Config.getConfig(start).getUsersTable()); QUERY.append(" WHERE app_id = ?"); if (includeRecipeIds != null && includeRecipeIds.length > 0) { QUERY.append(" AND recipe_id IN ("); @@ -538,7 +543,8 @@ public static long getUsersCount(Start start, AppIdentifier appIdentifier, RECIP public static long getUsersCount(Start start, TenantIdentifier tenantIdentifier, RECIPE_ID[] includeRecipeIds) throws SQLException, StorageQueryException { StringBuilder QUERY = new StringBuilder( - "SELECT COUNT(DISTINCT primary_or_recipe_user_id) AS total FROM " + Config.getConfig(start).getUsersTable()); + "SELECT COUNT(DISTINCT primary_or_recipe_user_id) AS total FROM " + + Config.getConfig(start).getUsersTable()); QUERY.append(" WHERE app_id = ? AND tenant_id = ?"); if (includeRecipeIds != null && includeRecipeIds.length > 0) { QUERY.append(" AND recipe_id IN ("); @@ -581,7 +587,8 @@ public static boolean doesUserIdExist(Start start, AppIdentifier appIdentifier, }, ResultSet::next); } - public static boolean doesUserIdExist_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + public static boolean doesUserIdExist_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { // We query both tables cause there is a case where a primary user ID exists, but its associated // recipe user ID has been deleted AND there are other recipe user IDs linked to this primary user ID already. @@ -629,12 +636,15 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant { // check if we should search through the emailpassword table if (dashboardSearchTags.shouldEmailPasswordTableBeSearched()) { - String QUERY = "SELECT allAuthUsersTable.*" + " FROM " + Config.getConfig(start).getUsersTable() - + " AS allAuthUsersTable" + - " JOIN " + Config.getConfig(start).getEmailPasswordUserToTenantTable() - + " AS emailpasswordTable ON allAuthUsersTable.app_id = emailpasswordTable.app_id AND " - + "allAuthUsersTable.tenant_id = emailpasswordTable.tenant_id AND " - + "allAuthUsersTable.user_id = emailpasswordTable.user_id"; + String QUERY = + "SELECT allAuthUsersTable.*" + " FROM " + Config.getConfig(start).getUsersTable() + + " AS allAuthUsersTable" + + " JOIN " + Config.getConfig(start).getEmailPasswordUserToTenantTable() + + + " AS emailpasswordTable ON allAuthUsersTable.app_id = emailpasswordTable" + + ".app_id AND " + + "allAuthUsersTable.tenant_id = emailpasswordTable.tenant_id AND " + + "allAuthUsersTable.user_id = emailpasswordTable.user_id"; // attach email tags to queries QUERY = QUERY + @@ -658,15 +668,20 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant { // check if we should search through the thirdparty table if (dashboardSearchTags.shouldThirdPartyTableBeSearched()) { - String QUERY = "SELECT allAuthUsersTable.*" + " FROM " + Config.getConfig(start).getUsersTable() - + " AS allAuthUsersTable" - + " JOIN " + Config.getConfig(start).getThirdPartyUserToTenantTable() - + " AS thirdPartyToTenantTable ON allAuthUsersTable.app_id = thirdPartyToTenantTable.app_id AND" - + " allAuthUsersTable.tenant_id = thirdPartyToTenantTable.tenant_id AND" - + " allAuthUsersTable.user_id = thirdPartyToTenantTable.user_id" - + " JOIN " + Config.getConfig(start).getThirdPartyUsersTable() - + " AS thirdPartyTable ON thirdPartyToTenantTable.app_id = thirdPartyTable.app_id AND" - + " thirdPartyToTenantTable.user_id = thirdPartyTable.user_id"; + String QUERY = + "SELECT allAuthUsersTable.*" + " FROM " + Config.getConfig(start).getUsersTable() + + " AS allAuthUsersTable" + + " JOIN " + Config.getConfig(start).getThirdPartyUserToTenantTable() + + + " AS thirdPartyToTenantTable ON allAuthUsersTable.app_id = " + + "thirdPartyToTenantTable.app_id AND" + + " allAuthUsersTable.tenant_id = thirdPartyToTenantTable.tenant_id AND" + + " allAuthUsersTable.user_id = thirdPartyToTenantTable.user_id" + + " JOIN " + Config.getConfig(start).getThirdPartyUsersTable() + + + " AS thirdPartyTable ON thirdPartyToTenantTable.app_id = thirdPartyTable" + + ".app_id AND" + + " thirdPartyToTenantTable.user_id = thirdPartyTable.user_id"; // check if email tag is present if (dashboardSearchTags.emails != null) { @@ -727,12 +742,15 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant { // check if we should search through the passwordless table if (dashboardSearchTags.shouldPasswordlessTableBeSearched()) { - String QUERY = "SELECT allAuthUsersTable.*" + " FROM " + Config.getConfig(start).getUsersTable() - + " AS allAuthUsersTable" + - " JOIN " + Config.getConfig(start).getPasswordlessUserToTenantTable() - + " AS passwordlessTable ON allAuthUsersTable.app_id = passwordlessTable.app_id AND" - + " allAuthUsersTable.tenant_id = passwordlessTable.tenant_id AND" - + " allAuthUsersTable.user_id = passwordlessTable.user_id"; + String QUERY = + "SELECT allAuthUsersTable.*" + " FROM " + Config.getConfig(start).getUsersTable() + + " AS allAuthUsersTable" + + " JOIN " + Config.getConfig(start).getPasswordlessUserToTenantTable() + + + " AS passwordlessTable ON allAuthUsersTable.app_id = passwordlessTable.app_id" + + " AND" + + " allAuthUsersTable.tenant_id = passwordlessTable.tenant_id AND" + + " allAuthUsersTable.user_id = passwordlessTable.user_id"; // check if email tag is present if (dashboardSearchTags.emails != null) { @@ -791,8 +809,11 @@ public static AuthRecipeUserInfo[] getUsers(Start start, TenantIdentifier tenant usersFromQuery = new ArrayList<>(); } else { - String finalQuery = "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM ( " + USER_SEARCH_TAG_CONDITION.toString() + " )" - + " AS finalResultTable ORDER BY primary_or_recipe_user_time_joined " + timeJoinedOrder + ", primary_or_recipe_user_id " + timeJoinedOrder; + String finalQuery = + "SELECT DISTINCT primary_or_recipe_user_id, primary_or_recipe_user_time_joined FROM ( " + + USER_SEARCH_TAG_CONDITION.toString() + " )" + + " AS finalResultTable ORDER BY primary_or_recipe_user_time_joined " + + timeJoinedOrder + ", primary_or_recipe_user_id " + timeJoinedOrder; usersFromQuery = execute(start, finalQuery, pst -> { for (int i = 1; i <= queryList.size(); i++) { pst.setString(i, queryList.get(i - 1)); @@ -1052,7 +1073,8 @@ public static AuthRecipeUserInfo[] listPrimaryUsersByThirdPartyInfo_Transaction( // now that we have locks on all the relevant tables, we can read from them safely List userIds = ThirdPartyQueries.listUserIdsByThirdPartyInfo_Transaction(start, sqlCon, appIdentifier, thirdPartyId, thirdPartyUserId); - List result = getPrimaryUserInfoForUserIds_Transaction(start, sqlCon, appIdentifier, userIds); + List result = getPrimaryUserInfoForUserIds_Transaction(start, sqlCon, appIdentifier, + userIds); // this is going to order them based on oldest that joined to newest that joined. result.sort(Comparator.comparingLong(o -> o.timeJoined)); @@ -1150,9 +1172,9 @@ public static AuthRecipeUserInfo[] listPrimaryUsersByPhoneNumber(Start start, } public static AuthRecipeUserInfo getPrimaryUserByThirdPartyInfo(Start start, - TenantIdentifier tenantIdentifier, - String thirdPartyId, - String thirdPartyUserId) + TenantIdentifier tenantIdentifier, + String thirdPartyId, + String thirdPartyUserId) throws StorageQueryException, SQLException { String userId = ThirdPartyQueries.getUserIdByThirdPartyInfo(start, tenantIdentifier, thirdPartyId, thirdPartyUserId); @@ -1186,7 +1208,7 @@ public static AuthRecipeUserInfo getPrimaryUserInfoForUserId(Start start, AppIde } public static AuthRecipeUserInfo getPrimaryUserInfoForUserId_Transaction(Start start, Connection con, - AppIdentifier appIdentifier, String id) + AppIdentifier appIdentifier, String id) throws SQLException, StorageQueryException { List ids = new ArrayList<>(); ids.add(id); @@ -1209,14 +1231,18 @@ private static List getPrimaryUserInfoForUserIds(Start start // which is linked to a primary user ID in which case it won't be in the primary_or_recipe_user_id column, // or the input may have a primary user ID whose recipe user ID was removed, so it won't be in the user_id // column - String QUERY = "SELECT au.user_id, au.primary_or_recipe_user_id, au.is_linked_or_is_a_primary_user, au.recipe_id, aaru.tenant_id, aaru.time_joined FROM " + Config.getConfig(start).getAppIdToUserIdTable() + " as au " + - "LEFT JOIN " + Config.getConfig(start).getUsersTable() + " as aaru ON au.app_id = aaru.app_id AND au.user_id = aaru.user_id" + - " WHERE au.primary_or_recipe_user_id IN (SELECT primary_or_recipe_user_id FROM " + - Config.getConfig(start).getAppIdToUserIdTable() + " WHERE (user_id IN (" - + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + - ") OR primary_or_recipe_user_id IN (" + - Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + - ")) AND app_id = ?) AND au.app_id = ?"; + String QUERY = + "SELECT au.user_id, au.primary_or_recipe_user_id, au.is_linked_or_is_a_primary_user, au.recipe_id, " + + "aaru.tenant_id, aaru.time_joined FROM " + + Config.getConfig(start).getAppIdToUserIdTable() + " as au " + + "LEFT JOIN " + Config.getConfig(start).getUsersTable() + + " as aaru ON au.app_id = aaru.app_id AND au.user_id = aaru.user_id" + + " WHERE au.primary_or_recipe_user_id IN (SELECT primary_or_recipe_user_id FROM " + + Config.getConfig(start).getAppIdToUserIdTable() + " WHERE (user_id IN (" + + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + + ") OR primary_or_recipe_user_id IN (" + + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + + ")) AND app_id = ?) AND au.app_id = ?"; List allAuthUsersResult = execute(start, QUERY, pst -> { // IN user_id @@ -1290,8 +1316,8 @@ private static List getPrimaryUserInfoForUserIds(Start start } private static List getPrimaryUserInfoForUserIds_Transaction(Start start, Connection sqlCon, - AppIdentifier appIdentifier, - List userIds) + AppIdentifier appIdentifier, + List userIds) throws StorageQueryException, SQLException { if (userIds.size() == 0) { return new ArrayList<>(); @@ -1301,14 +1327,18 @@ private static List getPrimaryUserInfoForUserIds_Transaction // which is linked to a primary user ID in which case it won't be in the primary_or_recipe_user_id column, // or the input may have a primary user ID whose recipe user ID was removed, so it won't be in the user_id // column - String QUERY = "SELECT au.user_id, au.primary_or_recipe_user_id, au.is_linked_or_is_a_primary_user, au.recipe_id, aaru.tenant_id, aaru.time_joined FROM " + Config.getConfig(start).getAppIdToUserIdTable() + " as au" + - " LEFT JOIN " + Config.getConfig(start).getUsersTable() + " as aaru ON au.app_id = aaru.app_id AND au.user_id = aaru.user_id" + - " WHERE au.primary_or_recipe_user_id IN (SELECT primary_or_recipe_user_id FROM " + - Config.getConfig(start).getAppIdToUserIdTable() + " WHERE (user_id IN (" - + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + - ") OR primary_or_recipe_user_id IN (" + - Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + - ")) AND app_id = ?) AND au.app_id = ?"; + String QUERY = + "SELECT au.user_id, au.primary_or_recipe_user_id, au.is_linked_or_is_a_primary_user, au.recipe_id, " + + "aaru.tenant_id, aaru.time_joined FROM " + + Config.getConfig(start).getAppIdToUserIdTable() + " as au" + + " LEFT JOIN " + Config.getConfig(start).getUsersTable() + + " as aaru ON au.app_id = aaru.app_id AND au.user_id = aaru.user_id" + + " WHERE au.primary_or_recipe_user_id IN (SELECT primary_or_recipe_user_id FROM " + + Config.getConfig(start).getAppIdToUserIdTable() + " WHERE (user_id IN (" + + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + + ") OR primary_or_recipe_user_id IN (" + + Utils.generateCommaSeperatedQuestionMarks(userIds.size()) + + ")) AND app_id = ?) AND au.app_id = ?"; List allAuthUsersResult = execute(sqlCon, QUERY, pst -> { // IN user_id @@ -1345,10 +1375,13 @@ private static List getPrimaryUserInfoForUserIds_Transaction List loginMethods = new ArrayList<>(); loginMethods.addAll( - EmailPasswordQueries.getUsersInfoUsingIdList_Transaction(start, sqlCon, recipeUserIdsToFetch, appIdentifier)); - loginMethods.addAll(ThirdPartyQueries.getUsersInfoUsingIdList_Transaction(start, sqlCon, recipeUserIdsToFetch, appIdentifier)); + EmailPasswordQueries.getUsersInfoUsingIdList_Transaction(start, sqlCon, recipeUserIdsToFetch, + appIdentifier)); + loginMethods.addAll(ThirdPartyQueries.getUsersInfoUsingIdList_Transaction(start, sqlCon, recipeUserIdsToFetch, + appIdentifier)); loginMethods.addAll( - PasswordlessQueries.getUsersInfoUsingIdList_Transaction(start, sqlCon, recipeUserIdsToFetch, appIdentifier)); + PasswordlessQueries.getUsersInfoUsingIdList_Transaction(start, sqlCon, recipeUserIdsToFetch, + appIdentifier)); Map recipeUserIdToLoginMethodMap = new HashMap<>(); for (LoginMethod loginMethod : loginMethods) { @@ -1526,7 +1559,7 @@ public static String[] getAllTablesInTheDatabase(Start start) throws SQLExceptio List tableNames = new ArrayList<>(); try (Connection con = ConnectionPool.getConnection(start)) { DatabaseMetaData metadata = con.getMetaData(); - ResultSet resultSet = metadata.getTables(null, null, null, new String[] { "TABLE" }); + ResultSet resultSet = metadata.getTables(null, null, null, new String[]{"TABLE"}); while (resultSet.next()) { String tableName = resultSet.getString("TABLE_NAME"); tableNames.add(tableName); @@ -1538,7 +1571,7 @@ public static String[] getAllTablesInTheDatabase(Start start) throws SQLExceptio @TestOnly public static String[] getAllTablesInTheDatabaseThatHasDataForAppId(Start start, String appId) - throws StorageQueryException, SQLException { + throws StorageQueryException, SQLException { if (!Start.isTesting) { throw new UnsupportedOperationException(); } @@ -1616,7 +1649,8 @@ public static boolean checkIfUsesAccountLinking(Start start, AppIdentifier appId }); } - public static AccountLinkingInfo getAccountLinkingInfo_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + public static AccountLinkingInfo getAccountLinkingInfo_Transaction(Start start, Connection sqlCon, + AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { GeneralQueries.AccountLinkingInfo accountLinkingInfo = new GeneralQueries.AccountLinkingInfo(userId, false); { @@ -1638,9 +1672,11 @@ public static AccountLinkingInfo getAccountLinkingInfo_Transaction(Start start, return accountLinkingInfo; } - public static void updateTimeJoinedForPrimaryUser_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String primaryUserId) + public static void updateTimeJoinedForPrimaryUser_Transaction(Start start, Connection sqlCon, + AppIdentifier appIdentifier, String primaryUserId) throws SQLException, StorageQueryException { - // Query like postgres causes issue in mysql, so we have to fetch min time joined first on a separate query and then update it + // Query like postgres causes issue in mysql, so we have to fetch min time joined first on a separate query + // and then update it String QUERY1 = "SELECT MIN(time_joined) AS min_time_joined FROM " + Config.getConfig(start).getUsersTable() + " WHERE app_id = ? AND primary_or_recipe_user_id = ?"; long minTimeJoined = execute(sqlCon, QUERY1, pst -> { diff --git a/src/main/java/io/supertokens/storage/mysql/queries/JWTSigningQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/JWTSigningQueries.java index 3e8537c..a3b820d 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/JWTSigningQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/JWTSigningQueries.java @@ -45,13 +45,13 @@ static String getQueryToCreateJWTSigningTable(Start start) { */ return "CREATE TABLE IF NOT EXISTS " + Config.getConfig(start).getJWTSigningKeysTable() + " (" + "app_id VARCHAR(64) DEFAULT 'public'," - + "key_id VARCHAR(255) NOT NULL," - + "key_string TEXT NOT NULL," - + "algorithm VARCHAR(10) NOT NULL," + + "key_id VARCHAR(255) NOT NULL," + + "key_string TEXT NOT NULL," + + "algorithm VARCHAR(10) NOT NULL," + "created_at BIGINT UNSIGNED," + "PRIMARY KEY(app_id, key_id)," + "FOREIGN KEY(app_id)" - + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + ");"; } @@ -61,7 +61,7 @@ public static List getJWTSigningKeys_Transaction(Start start, String QUERY = "SELECT * FROM " + Config.getConfig(start).getJWTSigningKeysTable() + " WHERE app_id = ? ORDER BY created_at DESC FOR UPDATE"; - return execute(con, QUERY, pst -> pst.setString(1, appIdentifier.getAppId()),result -> { + return execute(con, QUERY, pst -> pst.setString(1, appIdentifier.getAppId()), result -> { List keys = new ArrayList<>(); while (result.next()) { diff --git a/src/main/java/io/supertokens/storage/mysql/queries/MultitenancyQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/MultitenancyQueries.java index 179e587..dcfb395 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/MultitenancyQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/MultitenancyQueries.java @@ -87,7 +87,8 @@ static String getQueryToCreateTenantThirdPartyProvidersTable(Start start) { + "user_info_map_from_user_info_endpoint_email_verified VARCHAR(64)," + "PRIMARY KEY (connection_uri_domain, app_id, tenant_id, third_party_id)," + "FOREIGN KEY(connection_uri_domain, app_id, tenant_id)" - + " REFERENCES " + Config.getConfig(start).getTenantConfigsTable() + " (connection_uri_domain, app_id, tenant_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getTenantConfigsTable() + + " (connection_uri_domain, app_id, tenant_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -107,7 +108,8 @@ static String getQueryToCreateTenantThirdPartyProviderClientsTable(Start start) + "additional_config TEXT," + " PRIMARY KEY (connection_uri_domain, app_id, tenant_id, third_party_id, client_type)," + "FOREIGN KEY(connection_uri_domain, app_id, tenant_id, third_party_id)" - + " REFERENCES " + Config.getConfig(start).getTenantThirdPartyProvidersTable() + " (connection_uri_domain, app_id, tenant_id, third_party_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getTenantThirdPartyProvidersTable() + + " (connection_uri_domain, app_id, tenant_id, third_party_id) ON DELETE CASCADE" + ");"; } @@ -121,7 +123,8 @@ public static String getQueryToCreateFirstFactorsTable(Start start) { + "factor_id VARCHAR(128)," + "PRIMARY KEY (connection_uri_domain, app_id, tenant_id, factor_id)," + "FOREIGN KEY (connection_uri_domain, app_id, tenant_id)" - + " REFERENCES " + Config.getConfig(start).getTenantConfigsTable() + " (connection_uri_domain, app_id, tenant_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getTenantConfigsTable() + + " (connection_uri_domain, app_id, tenant_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -158,7 +161,8 @@ private static void executeCreateTenantQueries(Start start, Connection sqlCon, T try { ThirdPartyProviderSQLHelper.create(start, sqlCon, tenantConfig, provider); } catch (SQLIntegrityConstraintViolationException e) { - if (start.isPrimaryKeyError(e.getMessage(), Config.getConfig(start).getTenantThirdPartyProvidersTable())) { + if (start.isPrimaryKeyError(e.getMessage(), + Config.getConfig(start).getTenantThirdPartyProvidersTable())) { throw new StorageTransactionLogicException(new DuplicateThirdPartyIdException()); } else { throw e; @@ -169,7 +173,8 @@ private static void executeCreateTenantQueries(Start start, Connection sqlCon, T try { ThirdPartyProviderClientSQLHelper.create(start, sqlCon, tenantConfig, provider, providerClient); } catch (SQLIntegrityConstraintViolationException e) { - if (start.isPrimaryKeyError(e.getMessage(), Config.getConfig(start).getTenantThirdPartyProviderClientsTable())) { + if (start.isPrimaryKeyError(e.getMessage(), + Config.getConfig(start).getTenantThirdPartyProviderClientsTable())) { throw new StorageTransactionLogicException(new DuplicateClientTypeException()); } else { throw e; @@ -179,10 +184,12 @@ private static void executeCreateTenantQueries(Start start, Connection sqlCon, T } MfaSqlHelper.createFirstFactors(start, sqlCon, tenantConfig.tenantIdentifier, tenantConfig.firstFactors); - MfaSqlHelper.createRequiredSecondaryFactors(start, sqlCon, tenantConfig.tenantIdentifier, tenantConfig.requiredSecondaryFactors); + MfaSqlHelper.createRequiredSecondaryFactors(start, sqlCon, tenantConfig.tenantIdentifier, + tenantConfig.requiredSecondaryFactors); } - public static void createTenantConfig(Start start, TenantConfig tenantConfig) throws StorageQueryException, StorageTransactionLogicException { + public static void createTenantConfig(Start start, TenantConfig tenantConfig) + throws StorageQueryException, StorageTransactionLogicException { start.startTransaction(con -> { Connection sqlCon = (Connection) con.getConnection(); { @@ -198,7 +205,8 @@ public static void createTenantConfig(Start start, TenantConfig tenantConfig) th }); } - public static boolean deleteTenantConfig(Start start, TenantIdentifier tenantIdentifier) throws StorageQueryException { + public static boolean deleteTenantConfig(Start start, TenantIdentifier tenantIdentifier) + throws StorageQueryException { try { String QUERY = "DELETE FROM " + getConfig(start).getTenantConfigsTable() + " WHERE connection_uri_domain = ? AND app_id = ? AND tenant_id = ?"; @@ -216,7 +224,8 @@ public static boolean deleteTenantConfig(Start start, TenantIdentifier tenantIde } } - public static void overwriteTenantConfig(Start start, TenantConfig tenantConfig) throws StorageQueryException, StorageTransactionLogicException { + public static void overwriteTenantConfig(Start start, TenantConfig tenantConfig) + throws StorageQueryException, StorageTransactionLogicException { start.startTransaction(con -> { Connection sqlCon = (Connection) con.getConnection(); { @@ -230,7 +239,8 @@ public static void overwriteTenantConfig(Start start, TenantConfig tenantConfig) pst.setString(3, tenantConfig.tenantIdentifier.getTenantId()); }); if (rowsAffected == 0) { - throw new StorageTransactionLogicException(new TenantOrAppNotFoundException(tenantConfig.tenantIdentifier)); + throw new StorageTransactionLogicException( + new TenantOrAppNotFoundException(tenantConfig.tenantIdentifier)); } } @@ -253,16 +263,21 @@ public static TenantConfig[] getAllTenants(Start start) throws StorageQueryExcep try { // Map TenantIdentifier -> thirdPartyId -> clientType - HashMap>> providerClientsMap = ThirdPartyProviderClientSQLHelper.selectAll(start); + HashMap>> providerClientsMap = ThirdPartyProviderClientSQLHelper.selectAll( + start); // Map (tenantIdentifier) -> thirdPartyId -> provider - HashMap> providerMap = ThirdPartyProviderSQLHelper.selectAll(start, providerClientsMap); + HashMap> providerMap = + ThirdPartyProviderSQLHelper.selectAll( + start, providerClientsMap); // Map (tenantIdentifier) -> firstFactors HashMap firstFactorsMap = MfaSqlHelper.selectAllFirstFactors(start); // Map (tenantIdentifier) -> requiredSecondaryFactors - HashMap requiredSecondaryFactorsMap = MfaSqlHelper.selectAllRequiredSecondaryFactors(start); + HashMap requiredSecondaryFactorsMap = + MfaSqlHelper.selectAllRequiredSecondaryFactors( + start); return TenantConfigSQLHelper.selectAll(start, providerMap, firstFactorsMap, requiredSecondaryFactorsMap); } catch (SQLException throwables) { @@ -316,7 +331,7 @@ public static void addTenantIdInTargetStorage_Transaction(Start start, Connectio + ")"; update(con, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); - pst.setLong(2, currentTime); + pst.setLong(2, currentTime); pst.setString(3, tenantIdentifier.getAppId()); }); } @@ -333,7 +348,7 @@ public static void addTenantIdInTargetStorage_Transaction(Start start, Connectio update(con, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); pst.setString(2, tenantIdentifier.getTenantId()); - pst.setLong(3, currentTime); + pst.setLong(3, currentTime); pst.setString(4, tenantIdentifier.getAppId()); pst.setString(5, tenantIdentifier.getTenantId()); }); @@ -341,7 +356,7 @@ public static void addTenantIdInTargetStorage_Transaction(Start start, Connectio } public static void deleteTenantIdInTargetStorage(Start start, TenantIdentifier tenantIdentifier) - throws StorageQueryException { + throws StorageQueryException { try { if (tenantIdentifier.getTenantId().equals(TenantIdentifier.DEFAULT_TENANT_ID)) { // Delete the app diff --git a/src/main/java/io/supertokens/storage/mysql/queries/PasswordlessQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/PasswordlessQueries.java index 7518f34..ae6b4be 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/PasswordlessQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/PasswordlessQueries.java @@ -55,7 +55,8 @@ public static String getQueryToCreateUsersTable(Start start) { + "time_joined BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, user_id)," + " FOREIGN KEY(app_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + " (app_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + + " (app_id, user_id) ON DELETE CASCADE" + ");"; } @@ -72,7 +73,8 @@ static String getQueryToCreatePasswordlessUserToTenantTable(Start start) { + "CONSTRAINT phone_number UNIQUE (app_id, tenant_id, phone_number)," + "PRIMARY KEY (app_id, tenant_id, user_id)," + "FOREIGN KEY (app_id, tenant_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getUsersTable() + "(app_id, tenant_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getUsersTable() + + "(app_id, tenant_id, user_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -81,14 +83,14 @@ public static String getQueryToCreateDevicesTable(Start start) { return "CREATE TABLE IF NOT EXISTS " + getConfig(start).getPasswordlessDevicesTable() + " (" + "app_id VARCHAR(64) DEFAULT 'public'," + "tenant_id VARCHAR(64) DEFAULT 'public'," - + "device_id_hash CHAR(44) NOT NULL," - + "email VARCHAR(256)," - + "phone_number VARCHAR(256)," - + "link_code_salt CHAR(44) NOT NULL," - + "failed_attempts INT UNSIGNED NOT NULL," + + "device_id_hash CHAR(44) NOT NULL," + + "email VARCHAR(256)," + + "phone_number VARCHAR(256)," + + "link_code_salt CHAR(44) NOT NULL," + + "failed_attempts INT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, tenant_id, device_id_hash)," + "FOREIGN KEY(app_id, tenant_id)" - + " REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE" + ");"; } @@ -96,14 +98,15 @@ public static String getQueryToCreateCodesTable(Start start) { return "CREATE TABLE IF NOT EXISTS " + getConfig(start).getPasswordlessCodesTable() + " (" + "app_id VARCHAR(64) DEFAULT 'public'," + "tenant_id VARCHAR(64) DEFAULT 'public'," - + "code_id CHAR(36) NOT NULL," - + "device_id_hash CHAR(44) NOT NULL," + + "code_id CHAR(36) NOT NULL," + + "device_id_hash CHAR(44) NOT NULL," + "link_code_hash CHAR(44) NOT NULL," - + "created_at BIGINT UNSIGNED NOT NULL," + + "created_at BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, tenant_id, code_id)," + "CONSTRAINT link_code_hash UNIQUE (app_id, tenant_id, link_code_hash)," + "FOREIGN KEY (app_id, tenant_id, device_id_hash)" - + " REFERENCES " + getConfig(start).getPasswordlessDevicesTable() + "(app_id, tenant_id, device_id_hash) ON DELETE CASCADE ON UPDATE CASCADE" + + " REFERENCES " + getConfig(start).getPasswordlessDevicesTable() + + "(app_id, tenant_id, device_id_hash) ON DELETE CASCADE ON UPDATE CASCADE" + ");"; } @@ -113,7 +116,8 @@ public static String getQueryToCreateDeviceEmailIndex(Start start) { } public static String getQueryToCreateDevicePhoneNumberIndex(Start start) { - return "CREATE INDEX passwordless_devices_phone_number_index ON " + getConfig(start).getPasswordlessDevicesTable() + return "CREATE INDEX passwordless_devices_phone_number_index ON " + + getConfig(start).getPasswordlessDevicesTable() + " (app_id, tenant_id, phone_number);"; // USING hash } @@ -352,7 +356,8 @@ public static void deleteCode_Transaction(Start start, Connection con, TenantIde }); } - public static AuthRecipeUserInfo createUser(Start start, TenantIdentifier tenantIdentifier, String id, @Nullable String email, + public static AuthRecipeUserInfo createUser(Start start, TenantIdentifier tenantIdentifier, String id, + @Nullable String email, @Nullable String phoneNumber, long timeJoined) throws StorageTransactionLogicException, StorageQueryException { return start.startTransaction(con -> { @@ -371,7 +376,9 @@ public static AuthRecipeUserInfo createUser(Start start, TenantIdentifier tenant { // all_auth_recipe_users String QUERY = "INSERT INTO " + getConfig(start).getUsersTable() - + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, " + + "primary_or_recipe_user_time_joined)" + " VALUES(?, ?, ?, ?, ?, ?, ?)"; update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); @@ -421,7 +428,7 @@ public static AuthRecipeUserInfo createUser(Start start, TenantIdentifier tenant } private static UserInfoWithTenantId[] getUserInfosWithTenant_Transaction(Start start, Connection con, - AppIdentifier appIdentifier, String userId) + AppIdentifier appIdentifier, String userId) throws StorageQueryException, SQLException { String QUERY = "SELECT pl_users.user_id as user_id, pl_users.email as email, " + "pl_users.phone_number as phone_number, pl_users_to_tenant.tenant_id as tenant_id " @@ -733,7 +740,7 @@ public static List getUsersInfoUsingIdList(Start start, Set } public static List getUsersInfoUsingIdList_Transaction(Start start, Connection con, Set ids, - AppIdentifier appIdentifier) + AppIdentifier appIdentifier) throws SQLException, StorageQueryException { if (ids.size() > 0) { // No need to filter based on tenantId because the id list is already filtered for a tenant @@ -763,7 +770,7 @@ public static List getUsersInfoUsingIdList_Transaction(Start start, } private static UserInfoPartial getUserById_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, - String userId) + String userId) throws StorageQueryException, SQLException { // we don't need a LOCK here because this is already part of a transaction, and locked on app_id_to_user_id // table @@ -801,8 +808,8 @@ public static List lockEmail_Transaction(Start start, Connection con, Ap } public static List lockPhoneAndTenant_Transaction(Start start, Connection con, - AppIdentifier appIdentifier, - String phoneNumber) + AppIdentifier appIdentifier, + String phoneNumber) throws SQLException, StorageQueryException { String QUERY = "SELECT user_id FROM " + getConfig(start).getPasswordlessUsersTable() + @@ -820,7 +827,7 @@ public static List lockPhoneAndTenant_Transaction(Start start, Connectio } public static String getPrimaryUserIdUsingEmail(Start start, TenantIdentifier tenantIdentifier, - String email) + String email) throws StorageQueryException, SQLException { String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + "FROM " + getConfig(start).getPasswordlessUserToTenantTable() + " AS pless" + @@ -840,8 +847,9 @@ public static String getPrimaryUserIdUsingEmail(Start start, TenantIdentifier te }); } - public static List getPrimaryUserIdsUsingEmail_Transaction(Start start, Connection con, AppIdentifier appIdentifier, - String email) + public static List getPrimaryUserIdsUsingEmail_Transaction(Start start, Connection con, + AppIdentifier appIdentifier, + String email) throws StorageQueryException, SQLException { String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + "FROM " + getConfig(start).getPasswordlessUsersTable() + " AS pless" + @@ -882,8 +890,9 @@ public static String getPrimaryUserByPhoneNumber(Start start, TenantIdentifier t }); } - public static List listUserIdsByPhoneNumber_Transaction(Start start, Connection con, AppIdentifier appIdentifier, - @Nonnull String phoneNumber) + public static List listUserIdsByPhoneNumber_Transaction(Start start, Connection con, + AppIdentifier appIdentifier, + @Nonnull String phoneNumber) throws StorageQueryException, SQLException { String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " + "FROM " + getConfig(start).getPasswordlessUsersTable() + " AS pless" + @@ -913,12 +922,15 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC throw new UnknownUserIdException(); } - GeneralQueries.AccountLinkingInfo accountLinkingInfo = GeneralQueries.getAccountLinkingInfo_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), userId); + GeneralQueries.AccountLinkingInfo accountLinkingInfo = GeneralQueries.getAccountLinkingInfo_Transaction(start, + sqlCon, tenantIdentifier.toAppIdentifier(), userId); { // all_auth_recipe_users // ON CONFLICT DO NOTHING String QUERY = "INSERT INTO " + getConfig(start).getUsersTable() - + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, is_linked_or_is_a_primary_user, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, is_linked_or_is_a_primary_user, " + + "recipe_id, time_joined, primary_or_recipe_user_time_joined)" + "SELECT ?, ?, ?, ?, ?, ?, ?, ? WHERE NOT EXISTS (" + " SELECT app_id, tenant_id, user_id FROM " + getConfig(start).getUsersTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?" @@ -937,7 +949,8 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC pst.setString(11, userInfo.id); }); - GeneralQueries.updateTimeJoinedForPrimaryUser_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), accountLinkingInfo.primaryUserId); + GeneralQueries.updateTimeJoinedForPrimaryUser_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), + accountLinkingInfo.primaryUserId); } { // passwordless_user_to_tenant diff --git a/src/main/java/io/supertokens/storage/mysql/queries/SessionQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/SessionQueries.java index 12e3cca..93fef07 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/SessionQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/SessionQueries.java @@ -106,7 +106,7 @@ public static SessionInfo getSessionInfo_Transaction(Start start, Connection con "SELECT session_handle, user_id, refresh_token_hash_2, session_data, " + "expires_at, created_at_time, jwt_user_payload, use_static_key FROM " + Config.getConfig(start).getSessionInfoTable() - + " WHERE app_id = ? AND tenant_id = ? AND session_handle = ? FOR UPDATE"; + + " WHERE app_id = ? AND tenant_id = ? AND session_handle = ? FOR UPDATE"; SessionInfo sessionInfo = execute(con, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); pst.setString(2, tenantIdentifier.getTenantId()); @@ -327,11 +327,11 @@ public static SessionInfo getSession(Start start, TenantIdentifier tenantIdentif String QUERY = "SELECT sess.session_handle, sess.user_id, sess.refresh_token_hash_2, sess.session_data, sess" + ".expires_at, " - + + + "sess.created_at_time, sess.jwt_user_payload, sess.use_static_key, users" + ".primary_or_recipe_user_id FROM " + Config.getConfig(start).getSessionInfoTable() - + " AS sess LEFT JOIN " + Config.getConfig(start).getUsersTable() + + + " AS sess LEFT JOIN " + Config.getConfig(start).getUsersTable() + " as users ON sess.app_id = users.app_id AND sess.user_id = users.user_id WHERE sess.app_id =" + " ? AND " + "sess.tenant_id = ? AND sess.session_handle = ?"; @@ -412,11 +412,11 @@ public SessionInfo mapOrThrow(ResultSet result, boolean hasPrimaryOrRecipeUserId hasPrimaryOrRecipeUserId ? result.getString("primary_or_recipe_user_id") : result.getString("user_id"), result.getString("user_id"), - result.getString("refresh_token_hash_2"), - jp.parse(result.getString("session_data")).getAsJsonObject(), + result.getString("refresh_token_hash_2"), + jp.parse(result.getString("session_data")).getAsJsonObject(), result.getLong("expires_at"), - jp.parse(result.getString("jwt_user_payload")).getAsJsonObject(), - result.getLong("created_at_time"), result.getBoolean("use_static_key")); + jp.parse(result.getString("jwt_user_payload")).getAsJsonObject(), + result.getLong("created_at_time"), result.getBoolean("use_static_key")); } catch (Exception e) { throw new StorageQueryException(e); } diff --git a/src/main/java/io/supertokens/storage/mysql/queries/TOTPQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/TOTPQueries.java index b3536dd..33b08e2 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/TOTPQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/TOTPQueries.java @@ -26,19 +26,19 @@ public static String getQueryToCreateUsersTable(Start start) { + "user_id VARCHAR(128) NOT NULL," + "PRIMARY KEY (app_id, user_id)," + "FOREIGN KEY(app_id)" - + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + ")"; } public static String getQueryToCreateUserDevicesTable(Start start) { return "CREATE TABLE IF NOT EXISTS " + Config.getConfig(start).getTotpUserDevicesTable() + " (" + "app_id VARCHAR(64) DEFAULT 'public'," - + "user_id VARCHAR(128) NOT NULL," - + "device_name VARCHAR(256) NOT NULL," + + "user_id VARCHAR(128) NOT NULL," + + "device_name VARCHAR(256) NOT NULL," + "secret_key VARCHAR(256) NOT NULL," - + "period INTEGER NOT NULL," - + "skew INTEGER NOT NULL," - + "verified BOOLEAN NOT NULL," + + "period INTEGER NOT NULL," + + "skew INTEGER NOT NULL," + + "verified BOOLEAN NOT NULL," + "created_at BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, user_id, device_name)," + "FOREIGN KEY (app_id, user_id)" @@ -86,10 +86,13 @@ private static int insertUser_Transaction(Start start, Connection con, AppIdenti }); } - private static int insertDevice_Transaction(Start start, Connection con, AppIdentifier appIdentifier, TOTPDevice device) + private static int insertDevice_Transaction(Start start, Connection con, AppIdentifier appIdentifier, + TOTPDevice device) throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getTotpUserDevicesTable() - + " (app_id, user_id, device_name, secret_key, period, skew, verified, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + + + " (app_id, user_id, device_name, secret_key, period, skew, verified, created_at) VALUES (?, ?, ?, ?, " + + "?, ?, ?, ?)"; return update(con, QUERY, pst -> { pst.setString(1, appIdentifier.getAppId()); @@ -103,13 +106,15 @@ private static int insertDevice_Transaction(Start start, Connection con, AppIden }); } - public static void createDevice_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, TOTPDevice device) + public static void createDevice_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, + TOTPDevice device) throws SQLException, StorageQueryException { insertUser_Transaction(start, sqlCon, appIdentifier, device.userId); insertDevice_Transaction(start, sqlCon, appIdentifier, device); } - public static TOTPDevice getDeviceByName_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId, String deviceName) + public static TOTPDevice getDeviceByName_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, + String userId, String deviceName) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getTotpUserDevicesTable() + " WHERE app_id = ? AND user_id = ? AND device_name = ? FOR UPDATE;"; @@ -137,7 +142,8 @@ public static int markDeviceAsVerified(Start start, AppIdentifier appIdentifier, }); } - public static int deleteDevice_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String userId, String deviceName) + public static int deleteDevice_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String userId, + String deviceName) throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + Config.getConfig(start).getTotpUserDevicesTable() + " WHERE app_id = ? AND user_id = ? AND device_name = ?;"; @@ -174,7 +180,8 @@ public static boolean removeUser(Start start, TenantIdentifier tenantIdentifier, return removedUsersCount > 0; } - public static int updateDeviceName(Start start, AppIdentifier appIdentifier, String userId, String oldDeviceName, String newDeviceName) + public static int updateDeviceName(Start start, AppIdentifier appIdentifier, String userId, String oldDeviceName, + String newDeviceName) throws StorageQueryException, SQLException { String QUERY = "UPDATE " + Config.getConfig(start).getTotpUserDevicesTable() + " SET device_name = ? WHERE app_id = ? AND user_id = ? AND device_name = ?;"; @@ -205,7 +212,8 @@ public static TOTPDevice[] getDevices(Start start, AppIdentifier appIdentifier, }); } - public static TOTPDevice[] getDevices_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String userId) + public static TOTPDevice[] getDevices_Transaction(Start start, Connection con, AppIdentifier appIdentifier, + String userId) throws StorageQueryException, SQLException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getTotpUserDevicesTable() + " WHERE app_id = ? AND user_id = ? FOR UPDATE;"; @@ -224,10 +232,13 @@ public static TOTPDevice[] getDevices_Transaction(Start start, Connection con, A } - public static int insertUsedCode_Transaction(Start start, Connection con, TenantIdentifier tenantIdentifier, TOTPUsedCode code) + public static int insertUsedCode_Transaction(Start start, Connection con, TenantIdentifier tenantIdentifier, + TOTPUsedCode code) throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getTotpUsedCodesTable() - + " (app_id, tenant_id, user_id, code, is_valid, expiry_time_ms, created_time_ms) VALUES (?, ?, ?, ?, ?, ?, ?);"; + + + " (app_id, tenant_id, user_id, code, is_valid, expiry_time_ms, created_time_ms) VALUES (?, ?, ?, ?, " + + "?, ?, ?);"; return update(con, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); diff --git a/src/main/java/io/supertokens/storage/mysql/queries/ThirdPartyQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/ThirdPartyQueries.java index ac1b4c4..304c4ad 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/ThirdPartyQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/ThirdPartyQueries.java @@ -46,13 +46,14 @@ static String getQueryToCreateUsersTable(Start start) { return "CREATE TABLE IF NOT EXISTS " + Config.getConfig(start).getThirdPartyUsersTable() + " (" + "app_id VARCHAR(64) DEFAULT 'public'," + "third_party_id VARCHAR(28) NOT NULL," - + "third_party_user_id VARCHAR(256) NOT NULL," - + "user_id CHAR(36) NOT NULL," - + "email VARCHAR(256) NOT NULL," + + "third_party_user_id VARCHAR(256) NOT NULL," + + "user_id CHAR(36) NOT NULL," + + "email VARCHAR(256) NOT NULL," + "time_joined BIGINT UNSIGNED NOT NULL," + "PRIMARY KEY (app_id, user_id)," + "FOREIGN KEY(app_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + " (app_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getAppIdToUserIdTable() + + " (app_id, user_id) ON DELETE CASCADE" + ");"; } @@ -78,7 +79,8 @@ static String getQueryToCreateThirdPartyUserToTenantTable(Start start) { + "CONSTRAINT third_party_user_id UNIQUE (app_id, tenant_id, third_party_id, third_party_user_id)," + "PRIMARY KEY (app_id, tenant_id, user_id)," + "FOREIGN KEY (app_id, tenant_id, user_id)" - + " REFERENCES " + Config.getConfig(start).getUsersTable() + "(app_id, tenant_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + Config.getConfig(start).getUsersTable() + + "(app_id, tenant_id, user_id) ON DELETE CASCADE" + ");"; // @formatter:on } @@ -102,7 +104,9 @@ public static AuthRecipeUserInfo signUp(Start start, TenantIdentifier tenantIden { // all_auth_recipe_users String QUERY = "INSERT INTO " + Config.getConfig(start).getUsersTable() - + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, recipe_id, time_joined, " + + "primary_or_recipe_user_time_joined)" + " VALUES(?, ?, ?, ?, ?, ?, ?)"; update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getAppId()); @@ -259,7 +263,7 @@ public static List getUsersInfoUsingIdList(Start start, Set } public static List getUsersInfoUsingIdList_Transaction(Start start, Connection con, Set ids, - AppIdentifier appIdentifier) + AppIdentifier appIdentifier) throws SQLException, StorageQueryException { if (ids.size() > 0) { String QUERY = "SELECT user_id, third_party_id, third_party_user_id, email, time_joined " @@ -290,7 +294,7 @@ public static List getUsersInfoUsingIdList_Transaction(Start start, public static List listUserIdsByThirdPartyInfo(Start start, AppIdentifier appIdentifier, - String thirdPartyId, String thirdPartyUserId) + String thirdPartyId, String thirdPartyUserId) throws SQLException, StorageQueryException { String QUERY = "SELECT DISTINCT all_users.primary_or_recipe_user_id AS user_id " @@ -312,7 +316,8 @@ public static List listUserIdsByThirdPartyInfo(Start start, AppIdentifie }); } - public static List listUserIdsByThirdPartyInfo_Transaction(Start start, Connection con, AppIdentifier appIdentifier, + public static List listUserIdsByThirdPartyInfo_Transaction(Start start, Connection con, + AppIdentifier appIdentifier, String thirdPartyId, String thirdPartyUserId) throws SQLException, StorageQueryException { @@ -373,7 +378,7 @@ public static void updateUserEmail_Transaction(Start start, Connection con, AppI } private static UserInfoPartial getUserInfoUsingUserId_Transaction(Start start, Connection con, - AppIdentifier appIdentifier, String userId) + AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { // we don't need a LOCK here because this is already part of a transaction, and locked on app_id_to_user_id @@ -447,12 +452,15 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC throw new UnknownUserIdException(); } - GeneralQueries.AccountLinkingInfo accountLinkingInfo = GeneralQueries.getAccountLinkingInfo_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), userId); + GeneralQueries.AccountLinkingInfo accountLinkingInfo = GeneralQueries.getAccountLinkingInfo_Transaction(start, + sqlCon, tenantIdentifier.toAppIdentifier(), userId); { // all_auth_recipe_users // ON CONFLICT DO NOTHING String QUERY = "INSERT INTO " + Config.getConfig(start).getUsersTable() - + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, is_linked_or_is_a_primary_user, recipe_id, time_joined, primary_or_recipe_user_time_joined)" + + + "(app_id, tenant_id, user_id, primary_or_recipe_user_id, is_linked_or_is_a_primary_user, " + + "recipe_id, time_joined, primary_or_recipe_user_time_joined)" + "SELECT ?, ?, ?, ?, ?, ?, ?, ? WHERE NOT EXISTS (" + " SELECT app_id, tenant_id, user_id FROM " + Config.getConfig(start).getUsersTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?" @@ -471,7 +479,8 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC pst.setString(11, userInfo.id); }); - GeneralQueries.updateTimeJoinedForPrimaryUser_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), accountLinkingInfo.primaryUserId); + GeneralQueries.updateTimeJoinedForPrimaryUser_Transaction(start, sqlCon, tenantIdentifier.toAppIdentifier(), + accountLinkingInfo.primaryUserId); } { // thirdparty_user_to_tenant @@ -479,7 +488,8 @@ public static boolean addUserIdToTenant_Transaction(Start start, Connection sqlC String QUERY = "INSERT INTO " + Config.getConfig(start).getThirdPartyUserToTenantTable() + "(app_id, tenant_id, user_id, third_party_id, third_party_user_id) " + "SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (" - + " SELECT app_id, tenant_id, user_id FROM " + Config.getConfig(start).getThirdPartyUserToTenantTable() + + " SELECT app_id, tenant_id, user_id FROM " + + Config.getConfig(start).getThirdPartyUserToTenantTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?" + ")"; int numRows = update(sqlCon, QUERY, pst -> { @@ -566,7 +576,7 @@ private static List fillUserInfoWithTenantIds_transaction(Start Map> tenantIdsForUserIds = GeneralQueries.getTenantIdsForUserIds_transaction(start, sqlCon, appIdentifier, userIds); - for (UserInfoPartial userInfo : userInfos) { + for (UserInfoPartial userInfo : userInfos) { userInfo.tenantIds = tenantIdsForUserIds.get(userInfo.id).toArray(new String[0]); } return userInfos; diff --git a/src/main/java/io/supertokens/storage/mysql/queries/UserIdMappingQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/UserIdMappingQueries.java index 355d29e..7effa7a 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/UserIdMappingQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/UserIdMappingQueries.java @@ -49,12 +49,13 @@ public static String getQueryToCreateUserIdMappingTable(Start start) { + "CONSTRAINT external_user_id UNIQUE (app_id, external_user_id)," + "PRIMARY KEY (app_id, supertokens_user_id, external_user_id), " + "FOREIGN KEY (app_id, supertokens_user_id)" - + " REFERENCES " + getConfig(start).getAppIdToUserIdTable()+ "(app_id, user_id) ON DELETE CASCADE" + + " REFERENCES " + getConfig(start).getAppIdToUserIdTable() + "(app_id, user_id) ON DELETE CASCADE" + ")"; // @formatter:on } - public static void createUserIdMapping(Start start, AppIdentifier appIdentifier, String superTokensUserId, String externalUserId, + public static void createUserIdMapping(Start start, AppIdentifier appIdentifier, String superTokensUserId, + String externalUserId, String externalUserIdInfo) throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getUserIdMappingTable() + " (app_id, supertokens_user_id, external_user_id, external_user_id_info)" + " VALUES(?, ?, ?, ?)"; @@ -67,7 +68,8 @@ public static void createUserIdMapping(Start start, AppIdentifier appIdentifier, }); } - public static UserIdMapping getuseraIdMappingWithSuperTokensUserId(Start start, AppIdentifier appIdentifier, String userId) + public static UserIdMapping getuseraIdMappingWithSuperTokensUserId(Start start, AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND supertokens_user_id = ?"; @@ -82,7 +84,8 @@ public static UserIdMapping getuseraIdMappingWithSuperTokensUserId(Start start, }); } - public static UserIdMapping getUserIdMappingWithExternalUserId(Start start, AppIdentifier appIdentifier, String userId) + public static UserIdMapping getUserIdMappingWithExternalUserId(Start start, AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND external_user_id = ?"; @@ -99,7 +102,9 @@ public static UserIdMapping getUserIdMappingWithExternalUserId(Start start, AppI } public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExternalUserId(Start start, - AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { + AppIdentifier appIdentifier, + String userId) + throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND (supertokens_user_id = ? OR external_user_id = ?)"; @@ -190,7 +195,8 @@ public static HashMap getUserIdMappingWithUserIds_Transaction(St }); } - public static boolean deleteUserIdMappingWithSuperTokensUserId(Start start, AppIdentifier appIdentifier, String userId) + public static boolean deleteUserIdMappingWithSuperTokensUserId(Start start, AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "DELETE FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND supertokens_user_id = ?"; @@ -206,7 +212,8 @@ public static boolean deleteUserIdMappingWithSuperTokensUserId(Start start, AppI public static boolean deleteUserIdMappingWithExternalUserId(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException { - String QUERY = "DELETE FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND external_user_id = ?"; + String QUERY = "DELETE FROM " + Config.getConfig(start).getUserIdMappingTable() + + " WHERE app_id = ? AND external_user_id = ?"; // store the number of rows updated int rowUpdatedCount = update(start, QUERY, pst -> { @@ -218,8 +225,10 @@ public static boolean deleteUserIdMappingWithExternalUserId(Start start, AppIden } public static boolean updateOrDeleteExternalUserIdInfoWithSuperTokensUserId(Start start, - AppIdentifier appIdentifier, String userId, - @Nullable String externalUserIdInfo) throws SQLException, StorageQueryException { + AppIdentifier appIdentifier, + String userId, + @Nullable String externalUserIdInfo) + throws SQLException, StorageQueryException { String QUERY = "UPDATE " + Config.getConfig(start).getUserIdMappingTable() + " SET external_user_id_info = ? WHERE app_id = ? AND supertokens_user_id = ?"; @@ -234,7 +243,8 @@ public static boolean updateOrDeleteExternalUserIdInfoWithSuperTokensUserId(Star public static boolean updateOrDeleteExternalUserIdInfoWithExternalUserId(Start start, AppIdentifier appIdentifier, String userId, - @Nullable String externalUserIdInfo) throws SQLException, StorageQueryException { + @Nullable String externalUserIdInfo) + throws SQLException, StorageQueryException { String QUERY = "UPDATE " + Config.getConfig(start).getUserIdMappingTable() + " SET external_user_id_info = ? WHERE app_id = ? AND external_user_id = ?"; @@ -247,7 +257,9 @@ public static boolean updateOrDeleteExternalUserIdInfoWithExternalUserId(Start s return rowUpdated > 0; } - public static UserIdMapping getuseraIdMappingWithSuperTokensUserId_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + public static UserIdMapping getuseraIdMappingWithSuperTokensUserId_Transaction(Start start, Connection sqlCon, + AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND supertokens_user_id = ?"; @@ -262,7 +274,9 @@ public static UserIdMapping getuseraIdMappingWithSuperTokensUserId_Transaction(S }); } - public static UserIdMapping getUserIdMappingWithExternalUserId_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) + public static UserIdMapping getUserIdMappingWithExternalUserId_Transaction(Start start, Connection sqlCon, + AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND external_user_id = ?"; @@ -278,8 +292,10 @@ public static UserIdMapping getUserIdMappingWithExternalUserId_Transaction(Start }); } - public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExternalUserId_Transaction(Start start, Connection sqlCon, - AppIdentifier appIdentifier, String userId) + public static UserIdMapping[] getUserIdMappingWithEitherSuperTokensUserIdOrExternalUserId_Transaction(Start start, + Connection sqlCon, + AppIdentifier appIdentifier, + String userId) throws SQLException, StorageQueryException { String QUERY = "SELECT * FROM " + Config.getConfig(start).getUserIdMappingTable() + " WHERE app_id = ? AND (supertokens_user_id = ? OR external_user_id = ?)"; diff --git a/src/main/java/io/supertokens/storage/mysql/queries/UserMetadataQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/UserMetadataQueries.java index a3d7d3a..5fa72d9 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/UserMetadataQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/UserMetadataQueries.java @@ -39,9 +39,10 @@ public static String getQueryToCreateUserMetadataTable(Start start) { return "CREATE TABLE IF NOT EXISTS " + tableName + " (" + "app_id VARCHAR(64) DEFAULT 'public'," + "user_id VARCHAR(128) NOT NULL," - + "user_metadata TEXT NOT NULL," + + "user_metadata TEXT NOT NULL," + "PRIMARY KEY(app_id, user_id)," - + "FOREIGN KEY (app_id) REFERENCES " + Config.getConfig(start).getAppsTable() + "(app_id) ON DELETE CASCADE" + + "FOREIGN KEY (app_id) REFERENCES " + Config.getConfig(start).getAppsTable() + + "(app_id) ON DELETE CASCADE" + " );"; // @formatter:on diff --git a/src/main/java/io/supertokens/storage/mysql/queries/UserRolesQueries.java b/src/main/java/io/supertokens/storage/mysql/queries/UserRolesQueries.java index 303bebb..834a443 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/UserRolesQueries.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/UserRolesQueries.java @@ -33,13 +33,13 @@ public class UserRolesQueries { public static String getQueryToCreateRolesTable(Start start) { String tableName = Config.getConfig(start).getRolesTable(); // @formatter:off - return "CREATE TABLE IF NOT EXISTS " + tableName + " ( " - + "app_id VARCHAR(64) DEFAULT 'public'," - + "role VARCHAR(255) NOT NULL," - + "PRIMARY KEY(app_id, role)," - + "FOREIGN KEY(app_id)" - + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" - + ")"; + return "CREATE TABLE IF NOT EXISTS " + tableName + " ( " + + "app_id VARCHAR(64) DEFAULT 'public'," + + "role VARCHAR(255) NOT NULL," + + "PRIMARY KEY(app_id, role)," + + "FOREIGN KEY(app_id)" + + " REFERENCES " + Config.getConfig(start).getAppsTable() + " (app_id) ON DELETE CASCADE" + + ")"; // @formatter:on } @@ -52,7 +52,7 @@ public static String getQueryToCreateRolePermissionsTable(Start start) { + "permission VARCHAR(255) NOT NULL, " + "PRIMARY KEY (app_id, role, permission), " + "FOREIGN KEY (app_id, role)" - + " REFERENCES " + Config.getConfig(start).getRolesTable()+ "(app_id, role) ON DELETE CASCADE )"; + + " REFERENCES " + Config.getConfig(start).getRolesTable() + "(app_id, role) ON DELETE CASCADE )"; // @formatter:on } @@ -75,7 +75,8 @@ public static String getQueryToCreateUserRolesTable(Start start) { } public static String getQueryToCreateUserRolesRoleIndex(Start start) { - return "CREATE INDEX user_roles_role_index ON " + Config.getConfig(start).getUserRolesTable() + "(app_id, tenant_id, role)"; + return "CREATE INDEX user_roles_role_index ON " + Config.getConfig(start).getUserRolesTable() + + "(app_id, tenant_id, role)"; } public static boolean createNewRoleOrDoNothingIfExists_Transaction(Start start, Connection con, @@ -99,7 +100,8 @@ public static boolean createNewRoleOrDoNothingIfExists_Transaction(Start start, public static void addPermissionToRoleOrDoNothingIfExists_Transaction(Start start, Connection con, AppIdentifier appIdentifier, String role, - String permission) throws SQLException, StorageQueryException { + String permission) + throws SQLException, StorageQueryException { // ON CONFLICT DO NOTHING String QUERY = "INSERT INTO " + Config.getConfig(start).getUserRolesPermissionsTable() + "(app_id, role, permission) " diff --git a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/MfaSqlHelper.java b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/MfaSqlHelper.java index 9da3eb5..7c16117 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/MfaSqlHelper.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/MfaSqlHelper.java @@ -33,11 +33,13 @@ public static HashMap selectAllFirstFactors(Start st throws SQLException, StorageQueryException { String QUERY = "SELECT connection_uri_domain, app_id, tenant_id, factor_id FROM " + getConfig(start).getTenantFirstFactorsTable() + ";"; - return execute(start, QUERY, pst -> {}, result -> { + return execute(start, QUERY, pst -> { + }, result -> { HashMap> firstFactors = new HashMap<>(); while (result.next()) { - TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), result.getString("app_id"), result.getString("tenant_id")); + TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), + result.getString("app_id"), result.getString("tenant_id")); if (!firstFactors.containsKey(tenantIdentifier)) { firstFactors.put(tenantIdentifier, new ArrayList<>()); } @@ -58,7 +60,8 @@ public static HashMap selectAllRequiredSecondaryFact throws SQLException, StorageQueryException { String QUERY = "SELECT connection_uri_domain, app_id, tenant_id, factor_id FROM " + getConfig(start).getTenantRequiredSecondaryFactorsTable() + ";"; - return execute(start, QUERY, pst -> {}, result -> { + return execute(start, QUERY, pst -> { + }, result -> { HashMap> defaultRequiredFactors = new HashMap<>(); while (result.next()) { @@ -80,13 +83,15 @@ public static HashMap selectAllRequiredSecondaryFact }); } - public static void createFirstFactors(Start start, Connection sqlCon, TenantIdentifier tenantIdentifier, String[] firstFactors) + public static void createFirstFactors(Start start, Connection sqlCon, TenantIdentifier tenantIdentifier, + String[] firstFactors) throws SQLException, StorageQueryException { if (firstFactors == null || firstFactors.length == 0) { return; } - String QUERY = "INSERT INTO " + getConfig(start).getTenantFirstFactorsTable() + "(connection_uri_domain, app_id, tenant_id, factor_id) VALUES (?, ?, ?, ?);"; + String QUERY = "INSERT INTO " + getConfig(start).getTenantFirstFactorsTable() + + "(connection_uri_domain, app_id, tenant_id, factor_id) VALUES (?, ?, ?, ?);"; for (String factorId : new HashSet<>(Arrays.asList(firstFactors))) { update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getConnectionUriDomain()); @@ -97,13 +102,15 @@ public static void createFirstFactors(Start start, Connection sqlCon, TenantIden } } - public static void createRequiredSecondaryFactors(Start start, Connection sqlCon, TenantIdentifier tenantIdentifier, String[] requiredSecondaryFactors) + public static void createRequiredSecondaryFactors(Start start, Connection sqlCon, TenantIdentifier tenantIdentifier, + String[] requiredSecondaryFactors) throws SQLException, StorageQueryException { if (requiredSecondaryFactors == null || requiredSecondaryFactors.length == 0) { return; } - String QUERY = "INSERT INTO " + getConfig(start).getTenantRequiredSecondaryFactorsTable() + "(connection_uri_domain, app_id, tenant_id, factor_id) VALUES (?, ?, ?, ?);"; + String QUERY = "INSERT INTO " + getConfig(start).getTenantRequiredSecondaryFactorsTable() + + "(connection_uri_domain, app_id, tenant_id, factor_id) VALUES (?, ?, ?, ?);"; for (String factorId : requiredSecondaryFactors) { update(sqlCon, QUERY, pst -> { pst.setString(1, tenantIdentifier.getConnectionUriDomain()); diff --git a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/TenantConfigSQLHelper.java b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/TenantConfigSQLHelper.java index af3931c..22450b2 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/TenantConfigSQLHelper.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/TenantConfigSQLHelper.java @@ -40,13 +40,15 @@ public static class TenantConfigRowMapper implements RowMapper> providerMap, HashMap firstFactorsMap, HashMap requiredSecondaryFactorsMap) + public static TenantConfig[] selectAll(Start start, + HashMap> providerMap, + HashMap firstFactorsMap, + HashMap requiredSecondaryFactorsMap) throws SQLException, StorageQueryException { String QUERY = "SELECT connection_uri_domain, app_id, tenant_id, core_config," + " email_password_enabled, passwordless_enabled, third_party_enabled FROM " + getConfig(start).getTenantConfigsTable() + ";"; - TenantConfig[] tenantConfigs = execute(start, QUERY, pst -> {}, result -> { + TenantConfig[] tenantConfigs = execute(start, QUERY, pst -> { + }, result -> { List temp = new ArrayList<>(); while (result.next()) { - TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), result.getString("app_id"), result.getString("tenant_id")); + TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), + result.getString("app_id"), result.getString("tenant_id")); ThirdPartyConfig.Provider[] providers = null; if (providerMap.containsKey(tenantIdentifier)) { providers = providerMap.get(tenantIdentifier).values().toArray(new ThirdPartyConfig.Provider[0]); } - String[] firstFactors = firstFactorsMap.containsKey(tenantIdentifier) ? firstFactorsMap.get(tenantIdentifier) : new String[0]; + String[] firstFactors = + firstFactorsMap.containsKey(tenantIdentifier) ? firstFactorsMap.get(tenantIdentifier) : + new String[0]; - String[] requiredSecondaryFactors = requiredSecondaryFactorsMap.containsKey(tenantIdentifier) ? requiredSecondaryFactorsMap.get(tenantIdentifier) : new String[0]; + String[] requiredSecondaryFactors = requiredSecondaryFactorsMap.containsKey(tenantIdentifier) ? + requiredSecondaryFactorsMap.get(tenantIdentifier) : new String[0]; - temp.add(TenantConfigSQLHelper.TenantConfigRowMapper.getInstance(providers, firstFactors, requiredSecondaryFactors).mapOrThrow(result)); + temp.add(TenantConfigSQLHelper.TenantConfigRowMapper.getInstance(providers, firstFactors, + requiredSecondaryFactors).mapOrThrow(result)); } TenantConfig[] finalResult = new TenantConfig[temp.size()]; for (int i = 0; i < temp.size(); i++) { diff --git a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderClientSQLHelper.java b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderClientSQLHelper.java index 44d8049..da09245 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderClientSQLHelper.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderClientSQLHelper.java @@ -40,7 +40,8 @@ public class ThirdPartyProviderClientSQLHelper { public static class TenantThirdPartyProviderClientRowMapper implements RowMapper { - public static final TenantThirdPartyProviderClientRowMapper INSTANCE = new TenantThirdPartyProviderClientRowMapper(); + public static final TenantThirdPartyProviderClientRowMapper INSTANCE = + new TenantThirdPartyProviderClientRowMapper(); private TenantThirdPartyProviderClientRowMapper() { } @@ -59,7 +60,7 @@ public ThirdPartyConfig.ProviderClient map(ResultSet result) throws StorageQuery } else { JsonArray scopeArray = new Gson().fromJson(scopeArrayStr, JsonArray.class); scopeStringArray = new String[scopeArray.size()]; - for (int i=0; i < scopeArray.size(); i++) { + for (int i = 0; i < scopeArray.size(); i++) { scopeStringArray[i] = scopeArray.get(i).getAsString(); } } @@ -85,37 +86,47 @@ public ThirdPartyConfig.ProviderClient map(ResultSet result) throws StorageQuery } } - public static HashMap>> selectAll(Start start) + public static HashMap>> selectAll( + Start start) throws SQLException, StorageQueryException { HashMap>> providerClientsMap = new HashMap<>(); - String QUERY = "SELECT connection_uri_domain, app_id, tenant_id, third_party_id, client_type, client_id, client_secret, scope, force_pkce, additional_config FROM " - + getConfig(start).getTenantThirdPartyProviderClientsTable() + ";"; + String QUERY = + "SELECT connection_uri_domain, app_id, tenant_id, third_party_id, client_type, client_id, " + + "client_secret, scope, force_pkce, additional_config FROM " + + getConfig(start).getTenantThirdPartyProviderClientsTable() + ";"; - execute(start, QUERY, pst -> {}, result -> { + execute(start, QUERY, pst -> { + }, result -> { while (result.next()) { - TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), result.getString("app_id"), result.getString("tenant_id")); - ThirdPartyConfig.ProviderClient providerClient = TenantThirdPartyProviderClientRowMapper.getInstance().mapOrThrow(result); + TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), + result.getString("app_id"), result.getString("tenant_id")); + ThirdPartyConfig.ProviderClient providerClient = TenantThirdPartyProviderClientRowMapper.getInstance() + .mapOrThrow(result); if (!providerClientsMap.containsKey(tenantIdentifier)) { providerClientsMap.put(tenantIdentifier, new HashMap<>()); } - if(!providerClientsMap.get(tenantIdentifier).containsKey(result.getString("third_party_id"))) { + if (!providerClientsMap.get(tenantIdentifier).containsKey(result.getString("third_party_id"))) { providerClientsMap.get(tenantIdentifier).put(result.getString("third_party_id"), new HashMap<>()); } - providerClientsMap.get(tenantIdentifier).get(result.getString("third_party_id")).put(providerClient.clientType, providerClient); + providerClientsMap.get(tenantIdentifier).get(result.getString("third_party_id")) + .put(providerClient.clientType, providerClient); } return null; }); return providerClientsMap; } - public static void create(Start start, Connection sqlCon, TenantConfig tenantConfig, ThirdPartyConfig.Provider provider, ThirdPartyConfig.ProviderClient providerClient) + public static void create(Start start, Connection sqlCon, TenantConfig tenantConfig, + ThirdPartyConfig.Provider provider, ThirdPartyConfig.ProviderClient providerClient) throws SQLException, StorageTransactionLogicException { String QUERY = "INSERT INTO " + getConfig(start).getTenantThirdPartyProviderClientsTable() - + "(connection_uri_domain, app_id, tenant_id, third_party_id, client_type, client_id, client_secret, scope, force_pkce, additional_config)" + + + "(connection_uri_domain, app_id, tenant_id, third_party_id, client_type, client_id, client_secret, " + + "scope, force_pkce, additional_config)" + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; String scopeArrayStr; diff --git a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderSQLHelper.java b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderSQLHelper.java index ebe7dc9..b4b3b88 100644 --- a/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderSQLHelper.java +++ b/src/main/java/io/supertokens/storage/mysql/queries/multitenancy/ThirdPartyProviderSQLHelper.java @@ -86,21 +86,35 @@ public ThirdPartyConfig.Provider map(ResultSet result) throws StorageQueryExcept } } - public static HashMap> selectAll(Start start, HashMap>> providerClientsMap) + public static HashMap> selectAll(Start start, + HashMap>> providerClientsMap) throws SQLException, StorageQueryException { HashMap> providerMap = new HashMap<>(); - String QUERY = "SELECT connection_uri_domain, app_id, tenant_id, third_party_id, name, authorization_endpoint, authorization_endpoint_query_params, token_endpoint, token_endpoint_body_params, user_info_endpoint, user_info_endpoint_query_params, user_info_endpoint_headers, jwks_uri, oidc_discovery_endpoint, require_email, user_info_map_from_id_token_payload_user_id, user_info_map_from_id_token_payload_email, user_info_map_from_id_token_payload_email_verified, user_info_map_from_user_info_endpoint_user_id, user_info_map_from_user_info_endpoint_email, user_info_map_from_user_info_endpoint_email_verified FROM " - + getConfig(start).getTenantThirdPartyProvidersTable() + ";"; + String QUERY = + "SELECT connection_uri_domain, app_id, tenant_id, third_party_id, name, authorization_endpoint, " + + "authorization_endpoint_query_params, token_endpoint, token_endpoint_body_params, " + + "user_info_endpoint, user_info_endpoint_query_params, user_info_endpoint_headers, jwks_uri, " + + "oidc_discovery_endpoint, require_email, user_info_map_from_id_token_payload_user_id, " + + "user_info_map_from_id_token_payload_email, " + + "user_info_map_from_id_token_payload_email_verified, " + + "user_info_map_from_user_info_endpoint_user_id, user_info_map_from_user_info_endpoint_email, " + + "user_info_map_from_user_info_endpoint_email_verified FROM " + + getConfig(start).getTenantThirdPartyProvidersTable() + ";"; - execute(start, QUERY, pst -> {}, result -> { + execute(start, QUERY, pst -> { + }, result -> { while (result.next()) { - TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), result.getString("app_id"), result.getString("tenant_id")); + TenantIdentifier tenantIdentifier = new TenantIdentifier(result.getString("connection_uri_domain"), + result.getString("app_id"), result.getString("tenant_id")); ThirdPartyConfig.ProviderClient[] clients = null; - if (providerClientsMap.containsKey(tenantIdentifier) && providerClientsMap.get(tenantIdentifier).containsKey(result.getString("third_party_id"))) { - clients = providerClientsMap.get(tenantIdentifier).get(result.getString("third_party_id")).values().toArray(new ThirdPartyConfig.ProviderClient[0]); + if (providerClientsMap.containsKey(tenantIdentifier) && + providerClientsMap.get(tenantIdentifier).containsKey(result.getString("third_party_id"))) { + clients = providerClientsMap.get(tenantIdentifier).get(result.getString("third_party_id")).values() + .toArray(new ThirdPartyConfig.ProviderClient[0]); } - ThirdPartyConfig.Provider provider = TenantThirdPartyProviderRowMapper.getInstance(clients).mapOrThrow(result); + ThirdPartyConfig.Provider provider = TenantThirdPartyProviderRowMapper.getInstance(clients) + .mapOrThrow(result); if (!providerMap.containsKey(tenantIdentifier)) { providerMap.put(tenantIdentifier, new HashMap<>()); @@ -112,10 +126,19 @@ public static HashMap { diff --git a/src/test/java/io/supertokens/storage/mysql/test/ConfigTest.java b/src/test/java/io/supertokens/storage/mysql/test/ConfigTest.java index 8c930fe..479ba1f 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/ConfigTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/ConfigTest.java @@ -59,7 +59,7 @@ public void beforeEach() { @Test public void testThatDefaultConfigLoadsCorrectly() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -75,7 +75,7 @@ public void testThatDefaultConfigLoadsCorrectly() throws Exception { @Test public void testThatCustomConfigLoadsCorrectly() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_pool_size", "5"); @@ -91,7 +91,7 @@ public void testThatCustomConfigLoadsCorrectly() throws Exception { @Test public void testThatInvalidConfigThrowsRightError() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; // mysql_connection_pool_size is not set properly in the config file @@ -111,7 +111,7 @@ public void testThatInvalidConfigThrowsRightError() throws Exception { @Test public void testThatMissingConfigFileThrowsError() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; ProcessBuilder pb = new ProcessBuilder("rm", "-r", "config.yaml"); pb.directory(new File(args[0])); @@ -132,7 +132,7 @@ public void testThatMissingConfigFileThrowsError() throws Exception { @Test public void testCustomLocationForConfigLoadsCorrectly() throws Exception { - String[] args = { "../", "configFile=../temp/config.yaml" }; + String[] args = {"../", "configFile=../temp/config.yaml"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); ProcessState.EventAndException e = process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.INIT_FAILURE); @@ -144,7 +144,7 @@ public void testCustomLocationForConfigLoadsCorrectly() throws Exception { // absolute path File f = new File("../temp/config.yaml"); - args = new String[] { "../", "configFile=" + f.getAbsolutePath() }; + args = new String[]{"../", "configFile=" + f.getAbsolutePath()}; process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -158,7 +158,7 @@ public void testCustomLocationForConfigLoadsCorrectly() throws Exception { @Test public void testBadPortInput() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_port", "8989"); TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); @@ -185,7 +185,7 @@ public void testBadPortInput() throws Exception { @Test public void storageDisabledAndThenEnabled() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); process.getProcess().waitToInitStorageModule(); @@ -210,7 +210,7 @@ public void storageDisabledAndThenEnabled() throws Exception { @Test public void testBadHostInput() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_host", "random"); @@ -219,7 +219,8 @@ public void testBadHostInput() throws Exception { assertNotNull(e); assertEquals("Failed to initialize pool: Could not connect to address=(host=random)(port=3306)(type=master) : " - + "Socket fail to connect to host:random, port:3306. random", e.exception.getCause().getCause().getCause().getMessage()); + + "Socket fail to connect to host:random, port:3306. random", + e.exception.getCause().getCause().getCause().getMessage()); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -228,7 +229,7 @@ public void testBadHostInput() throws Exception { @Test public void testThatChangeInTableNameIsCorrect() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_key_value_table_name", "key_value_table"); Utils.setValueInConfig("mysql_session_info_table_name", "session_info_table"); @@ -251,7 +252,7 @@ public void testThatChangeInTableNameIsCorrect() throws Exception { @Test public void testAddingTableNamePrefixWorks() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_key_value_table_name", "key_value_table"); Utils.setValueInConfig("mysql_table_names_prefix", "some_prefix"); @@ -278,7 +279,7 @@ public void testValidConnectionURI() throws Exception { MySQLConfig userConfig = mapper.readValue(new File("../config.yaml"), MySQLConfig.class); String hostname = userConfig.getHostName(); { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root:root@" + hostname + ":3306/supertokens"); Utils.commentConfigValue("mysql_password"); @@ -298,7 +299,7 @@ public void testValidConnectionURI() throws Exception { { Utils.reset(); - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root:root@" + hostname + "/supertokens"); Utils.commentConfigValue("mysql_password"); @@ -318,7 +319,7 @@ public void testValidConnectionURI() throws Exception { { Utils.reset(); - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://" + hostname + ":3306/supertokens"); Utils.commentConfigValue("mysql_port"); @@ -336,7 +337,7 @@ public void testValidConnectionURI() throws Exception { { Utils.reset(); - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root@" + hostname + ":3306/supertokens"); Utils.commentConfigValue("mysql_user"); @@ -355,7 +356,7 @@ public void testValidConnectionURI() throws Exception { { Utils.reset(); - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root:root@" + hostname + ":3306"); Utils.commentConfigValue("mysql_password"); @@ -380,7 +381,7 @@ public void testInvalidConnectionURI() throws Exception { MySQLConfig userConfig = mapper.readValue(new File("../config.yaml"), MySQLConfig.class); String hostname = userConfig.getHostName(); { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", ":/" + hostname + ":3306/supertokens"); @@ -399,7 +400,7 @@ public void testInvalidConnectionURI() throws Exception { { Utils.reset(); - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root:wrongPassword@" + hostname + ":3306/supertokens"); @@ -426,7 +427,7 @@ public void testValidConnectionURIAttributes() throws Exception { MySQLConfig userConfig = mapper.readValue(new File("../config.yaml"), MySQLConfig.class); String hostname = userConfig.getHostName(); { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root:root@" + hostname + ":3306/supertokens?key1=value1"); @@ -442,7 +443,7 @@ public void testValidConnectionURIAttributes() throws Exception { { Utils.reset(); - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("mysql_connection_uri", "mysql://root:root@" + hostname + ":3306/supertokens?key1=value1&allowPublicKeyRetrieval=false&key2" + "=value2"); @@ -485,9 +486,12 @@ public void testAllConfigsHaveAnAnnotation() throws Exception { continue; } - if (!(field.isAnnotationPresent(UserPoolProperty.class) || field.isAnnotationPresent(ConnectionPoolProperty.class) || field.isAnnotationPresent( + if (!(field.isAnnotationPresent(UserPoolProperty.class) || + field.isAnnotationPresent(ConnectionPoolProperty.class) || field.isAnnotationPresent( NotConflictingWithinUserPool.class))) { - fail(field.getName() + " does not have UserPoolProperty, ConnectionPoolProperty or NotConflictingWithinUserPool annotation"); + fail(field.getName() + + " does not have UserPoolProperty, ConnectionPoolProperty or NotConflictingWithinUserPool " + + "annotation"); } } } diff --git a/src/test/java/io/supertokens/storage/mysql/test/DbConnectionPoolTest.java b/src/test/java/io/supertokens/storage/mysql/test/DbConnectionPoolTest.java index ccfeb27..42bfc17 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/DbConnectionPoolTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/DbConnectionPoolTest.java @@ -152,14 +152,15 @@ public void testDownTimeWhenChangingConnectionPoolSize() throws Exception { try { TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); - ThirdParty.signInUp(t1, t1Storage, process.getProcess(), "google", "googleid"+ finalI, "user" + + ThirdParty.signInUp(t1, t1Storage, process.getProcess(), "google", "googleid" + finalI, "user" + finalI + "@example.com"); if (firstErrorTime.get() != -1 && successAfterErrorTime.get() == -1) { successAfterErrorTime.set(System.currentTimeMillis()); } } catch (StorageQueryException e) { - if (e.getMessage().contains("called on closed connection") || e.getMessage().contains("Connection is closed")) { + if (e.getMessage().contains("called on closed connection") || + e.getMessage().contains("Connection is closed")) { if (firstErrorTime.get() == -1) { firstErrorTime.set(System.currentTimeMillis()); } @@ -354,7 +355,7 @@ public void testIdleConnectionTimeout() throws Exception { try { TenantIdentifier t1 = new TenantIdentifier(null, null, "t1"); Storage t1Storage = (StorageLayer.getStorage(t1, process.getProcess())); - ThirdParty.signInUp(t1, t1Storage, process.getProcess(), "google", "googleid"+ finalI, "user" + + ThirdParty.signInUp(t1, t1Storage, process.getProcess(), "google", "googleid" + finalI, "user" + finalI + "@example.com"); } catch (StorageQueryException e) { diff --git a/src/test/java/io/supertokens/storage/mysql/test/DeadlockTest.java b/src/test/java/io/supertokens/storage/mysql/test/DeadlockTest.java index db3633d..4ce2ec0 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/DeadlockTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/DeadlockTest.java @@ -75,7 +75,7 @@ public void beforeEach() { @Test public void transactionDeadlockTesting() throws InterruptedException, StorageQueryException, StorageTransactionLogicException { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -84,7 +84,8 @@ public void transactionDeadlockTesting() sqlStorage.startTransaction(con -> { try { sqlStorage.setKeyValue_Transaction(TenantIdentifier.BASE_TENANT, con, "Key", new KeyValueInfo("Value")); - sqlStorage.setKeyValue_Transaction(TenantIdentifier.BASE_TENANT, con, "Key1", new KeyValueInfo("Value1")); + sqlStorage.setKeyValue_Transaction(TenantIdentifier.BASE_TENANT, con, "Key1", + new KeyValueInfo("Value1")); sqlStorage.commitTransaction(con); } catch (TenantOrAppNotFoundException e) { throw new StorageTransactionLogicException(e); @@ -175,7 +176,7 @@ public void transactionDeadlockTesting() @Test public void testCodeCreationRapidly() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -211,7 +212,7 @@ public void testCodeCreationRapidly() throws Exception { @Test public void testCodeCreationRapidlyWithDifferentEmails() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -260,7 +261,8 @@ public void testCodeCreationRapidlyWithDifferentEmails() throws Exception { System.out.println("Durations: " + durations.toString()); assertNull(process - .checkOrWaitForEventInPlugin(io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED)); + .checkOrWaitForEventInPlugin( + io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED)); assertNotNull(process .checkOrWaitForEventInPlugin(io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_FOUND)); assert (pass.get()); @@ -271,7 +273,7 @@ public void testCodeCreationRapidlyWithDifferentEmails() throws Exception { @Test public void testConcurrentDeleteAndInsert() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -392,7 +394,8 @@ public void testConcurrentDeleteAndInsert() throws Exception { TOTPUsedCode code2 = new TOTPUsedCode("user", "1234", false, nextDay, now + 1); try { totpStorage.insertUsedCode_Transaction(con, TenantIdentifier.BASE_TENANT, code2); - } catch (UnknownTotpUserIdException | UsedCodeAlreadyExistsException | TenantOrAppNotFoundException e) { + } catch (UnknownTotpUserIdException | UsedCodeAlreadyExistsException | + TenantOrAppNotFoundException e) { // This should not happen throw new StorageTransactionLogicException(e); } @@ -436,7 +439,7 @@ public void testConcurrentDeleteAndInsert() throws Exception { @Test public void testConcurrentDeleteAndUpdate() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -623,7 +626,8 @@ public void testLinkAccountsInParallel() throws Exception { for (int i = 0; i < 3000; i++) { es.execute(() -> { try { - AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), user1.getSupertokensUserId()); + AuthRecipe.linkAccounts(process.getProcess(), user2.getSupertokensUserId(), + user1.getSupertokensUserId()); AuthRecipe.unlinkAccounts(process.getProcess(), user2.getSupertokensUserId()); } catch (Exception e) { if (e.getMessage().toLowerCase().contains("the transaction might succeed if retried")) { @@ -638,7 +642,8 @@ public void testLinkAccountsInParallel() throws Exception { assert (pass.get()); assertNull(process - .checkOrWaitForEventInPlugin(io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED)); + .checkOrWaitForEventInPlugin( + io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED)); assertNotNull(process .checkOrWaitForEventInPlugin(io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_FOUND)); @@ -681,7 +686,8 @@ public void testCreatePrimaryInParallel() throws Exception { assert (pass.get()); assertNull(process - .checkOrWaitForEventInPlugin(io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED)); + .checkOrWaitForEventInPlugin( + io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_NOT_RESOLVED)); assertNotNull(process .checkOrWaitForEventInPlugin(io.supertokens.storage.mysql.ProcessState.PROCESS_STATE.DEADLOCK_FOUND)); diff --git a/src/test/java/io/supertokens/storage/mysql/test/InMemoryDBTest.java b/src/test/java/io/supertokens/storage/mysql/test/InMemoryDBTest.java index c6494f2..cbaf5ed 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/InMemoryDBTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/InMemoryDBTest.java @@ -56,7 +56,7 @@ public void checkThatInMemDVWorksEvenIfWrongConfig() throws Exception { Utils.commentConfigValue("mysql_user"); Utils.commentConfigValue("mysql_password"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -72,7 +72,7 @@ public void checkThatInMemDVWorksEvenIfWrongConfig() throws Exception { assert sessionInfo.accessToken != null; assert sessionInfo.refreshToken != null; - assertEquals(((SessionStorage)StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( + assertEquals(((SessionStorage) StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( TenantIdentifier.BASE_TENANT), 1); process.kill(); @@ -80,12 +80,13 @@ public void checkThatInMemDVWorksEvenIfWrongConfig() throws Exception { } { - String[] args = { "../" }; + String[] args = {"../"}; StorageLayer.close(); TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); - assertEquals(((SessionStorage)StorageLayer.getStorage(process.getProcess())).getNumberOfSessions(TenantIdentifier.BASE_TENANT), 0); + assertEquals(((SessionStorage) StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( + TenantIdentifier.BASE_TENANT), 0); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -95,7 +96,7 @@ public void checkThatInMemDVWorksEvenIfWrongConfig() throws Exception { @Test public void checkThatActualDBWorksIfCorrectConfigDev() throws Exception { { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -111,17 +112,19 @@ public void checkThatActualDBWorksIfCorrectConfigDev() throws Exception { assert sessionInfo.accessToken != null; assert sessionInfo.refreshToken != null; - assertEquals(((SessionStorage)StorageLayer.getStorage(process.getProcess())).getNumberOfSessions(TenantIdentifier.BASE_TENANT), 1); + assertEquals(((SessionStorage) StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( + TenantIdentifier.BASE_TENANT), 1); process.kill(false); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); - assertEquals(((SessionStorage)StorageLayer.getStorage(process.getProcess())).getNumberOfSessions(TenantIdentifier.BASE_TENANT), 1); + assertEquals(((SessionStorage) StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( + TenantIdentifier.BASE_TENANT), 1); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -131,7 +134,7 @@ public void checkThatActualDBWorksIfCorrectConfigDev() throws Exception { @Test public void checkThatActualDBWorksIfCorrectConfigProduction() throws Exception { { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -147,17 +150,19 @@ public void checkThatActualDBWorksIfCorrectConfigProduction() throws Exception { assert sessionInfo.accessToken != null; assert sessionInfo.refreshToken != null; - assertEquals(((SessionStorage)StorageLayer.getStorage(process.getProcess())).getNumberOfSessions(TenantIdentifier.BASE_TENANT), 1); + assertEquals(((SessionStorage) StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( + TenantIdentifier.BASE_TENANT), 1); process.kill(false); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); - assertEquals(((SessionStorage)StorageLayer.getStorage(process.getProcess())).getNumberOfSessions(TenantIdentifier.BASE_TENANT), 1); + assertEquals(((SessionStorage) StorageLayer.getStorage(process.getProcess())).getNumberOfSessions( + TenantIdentifier.BASE_TENANT), 1); process.kill(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -166,7 +171,7 @@ public void checkThatActualDBWorksIfCorrectConfigProduction() throws Exception { @Test public void checkThatErrorIsThrownIfIncorrectConfigInProduction() throws IOException, InterruptedException { - String[] args = { "../" }; + String[] args = {"../"}; Utils.commentConfigValue("mysql_user"); @@ -184,7 +189,7 @@ public void checkThatErrorIsThrownIfIncorrectConfigInProduction() throws IOExcep @Test public void ifForceNoInMemoryThenDevShouldThrowError() throws IOException, InterruptedException { - String[] args = { "../", "forceNoInMemDB=true" }; + String[] args = {"../", "forceNoInMemDB=true"}; Utils.commentConfigValue("mysql_user"); diff --git a/src/test/java/io/supertokens/storage/mysql/test/LogLevelTest.java b/src/test/java/io/supertokens/storage/mysql/test/LogLevelTest.java index b26df66..b776d3c 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/LogLevelTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/LogLevelTest.java @@ -52,7 +52,7 @@ public void beforeEach() { public void testLogLevelNoneOutput() throws Exception { { Utils.setValueInConfig("log_level", "NONE"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -96,7 +96,7 @@ public void testLogLevelNoneOutput() throws Exception { public void testLogLevelErrorOutput() throws Exception { { Utils.setValueInConfig("log_level", "ERROR"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -150,7 +150,7 @@ public void testLogLevelErrorOutput() throws Exception { public void testLogLevelWarnOutput() throws Exception { { Utils.setValueInConfig("log_level", "WARN"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -204,7 +204,7 @@ public void testLogLevelWarnOutput() throws Exception { public void testLogLevelInfoOutput() throws Exception { { Utils.setValueInConfig("log_level", "INFO"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -258,7 +258,7 @@ public void testLogLevelInfoOutput() throws Exception { public void testLogLevelDebugOutput() throws Exception { { Utils.setValueInConfig("log_level", "DEBUG"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); diff --git a/src/test/java/io/supertokens/storage/mysql/test/LoggingTest.java b/src/test/java/io/supertokens/storage/mysql/test/LoggingTest.java index 96dbf2a..606058c 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/LoggingTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/LoggingTest.java @@ -66,7 +66,7 @@ public void beforeEach() { @Test public void defaultLogging() throws Exception { StorageLayer.close(); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -109,7 +109,7 @@ public void defaultLogging() throws Exception { @Test public void customLogging() throws Exception { try { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("info_log_path", "\"tempLogging/info.log\""); Utils.setValueInConfig("error_log_path", "\"tempLogging/error.log\""); @@ -160,7 +160,7 @@ public void customLogging() throws Exception { @Test public void testStandardOutLoggingWithNullStr() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; ByteArrayOutputStream stdOutput = new ByteArrayOutputStream(); ByteArrayOutputStream errorOutput = new ByteArrayOutputStream(); @@ -197,7 +197,7 @@ public void testStandardOutLoggingWithNullStr() throws Exception { @Test public void confirmLoggerClosed() throws Exception { StorageLayer.close(); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -223,7 +223,7 @@ public void confirmLoggerClosed() throws Exception { @Test public void testStandardOutLoggingWithNull() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; ByteArrayOutputStream stdOutput = new ByteArrayOutputStream(); ByteArrayOutputStream errorOutput = new ByteArrayOutputStream(); @@ -260,7 +260,7 @@ public void testStandardOutLoggingWithNull() throws Exception { @Test public void confirmHikariLoggerClosedOnlyWhenProcessEnds() throws Exception { StorageLayer.close(); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); FeatureFlagTestContent.getInstance(process.getProcess()) .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY}); @@ -314,7 +314,7 @@ public void confirmHikariLoggerClosedOnlyWhenProcessEnds() throws Exception { @Test public void testDBPasswordMaskingOnDBConnectionFailUsingConnectionUri() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; String dbUser = "db_user"; String dbPassword = "db_password"; @@ -348,7 +348,7 @@ public void testDBPasswordMaskingOnDBConnectionFailUsingConnectionUri() throws E @Test public void testDBPasswordMaskingOnDBConnectionFailUsingCredentials() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; String dbUser = "db_user"; String dbPassword = "db_password"; @@ -382,7 +382,7 @@ public void testDBPasswordMaskingOnDBConnectionFailUsingCredentials() throws Exc @Test public void testDBPasswordMasking() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; ByteArrayOutputStream stdOutput = new ByteArrayOutputStream(); ByteArrayOutputStream errorOutput = new ByteArrayOutputStream(); @@ -417,7 +417,7 @@ public void testDBPasswordMasking() throws Exception { @Test public void testDBPasswordIsNotLoggedWhenProcessStartsEnds() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("error_log_path", "null"); Utils.setValueInConfig("info_log_path", "null"); @@ -481,7 +481,7 @@ public void testDBPasswordIsNotLoggedWhenProcessStartsEnds() throws Exception { @Test public void testDBPasswordIsNotLoggedWhenTenantIsCreated() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; Utils.setValueInConfig("error_log_path", "null"); Utils.setValueInConfig("info_log_path", "null"); @@ -501,14 +501,15 @@ public void testDBPasswordIsNotLoggedWhenTenantIsCreated() throws Exception { assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); Start start = (Start) StorageLayer.getStorage(process.getProcess()); - MySQLConfig userConfig = io.supertokens.storage.mysql.config.Config.getConfig(start);; + MySQLConfig userConfig = io.supertokens.storage.mysql.config.Config.getConfig(start); + ; String dbPasswordFromConfig = userConfig.getPassword(); Main main = process.getProcess(); FeatureFlagTestContent.getInstance(main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { - EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY }); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ + EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY}); JsonObject config = new JsonObject(); TenantIdentifier tenantIdentifier = new TenantIdentifier(null, "a1", null); @@ -549,8 +550,8 @@ public void testDBPasswordIsNotLoggedWhenTenantIsCreated() throws Exception { Main main = process.getProcess(); FeatureFlagTestContent.getInstance(main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { - EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY }); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ + EE_FEATURES.ACCOUNT_LINKING, EE_FEATURES.MULTI_TENANCY}); TenantIdentifier tenantIdentifier = new TenantIdentifier(null, "a1", null); JsonObject config = new JsonObject(); diff --git a/src/test/java/io/supertokens/storage/mysql/test/OneMillionUsersTest.java b/src/test/java/io/supertokens/storage/mysql/test/OneMillionUsersTest.java index 893fc2c..165139b 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/OneMillionUsersTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/OneMillionUsersTest.java @@ -110,7 +110,8 @@ private void createEmailPasswordUsers(Main main) throws Exception { String userId = io.supertokens.utils.Utils.getUUID(); long timeJoined = System.currentTimeMillis(); - storage.signUp(TenantIdentifier.BASE_TENANT, userId, "eptest" + finalI + "@example.com", combinedPasswordHash, + storage.signUp(TenantIdentifier.BASE_TENANT, userId, "eptest" + finalI + "@example.com", + combinedPasswordHash, timeJoined); synchronized (lock) { allUserIds.add(userId); @@ -119,7 +120,7 @@ private void createEmailPasswordUsers(Main main) throws Exception { throw new RuntimeException(e); } if (finalI % 10000 == 9999) { - System.out.println("Created " + ((finalI +1)) + " users"); + System.out.println("Created " + ((finalI + 1)) + " users"); } }); } @@ -140,7 +141,8 @@ private void createPasswordlessUsersWithEmail(Main main) throws Exception { String userId = io.supertokens.utils.Utils.getUUID(); long timeJoined = System.currentTimeMillis(); try { - storage.createUser(TenantIdentifier.BASE_TENANT, userId, "pltest" + finalI + "@example.com", null, timeJoined); + storage.createUser(TenantIdentifier.BASE_TENANT, userId, "pltest" + finalI + "@example.com", null, + timeJoined); synchronized (lock) { allUserIds.add(userId); } @@ -149,7 +151,7 @@ private void createPasswordlessUsersWithEmail(Main main) throws Exception { } if (finalI % 10000 == 9999) { - System.out.println("Created " + ((finalI +1)) + " users"); + System.out.println("Created " + ((finalI + 1)) + " users"); } }); } @@ -179,7 +181,7 @@ private void createPasswordlessUsersWithPhone(Main main) throws Exception { } if (finalI % 10000 == 9999) { - System.out.println("Created " + ((finalI +1)) + " users"); + System.out.println("Created " + ((finalI + 1)) + " users"); } }); } @@ -201,7 +203,8 @@ private void createThirdpartyUsers(Main main) throws Exception { long timeJoined = System.currentTimeMillis(); try { - storage.signUp(TenantIdentifier.BASE_TENANT, userId, "tptest" + finalI + "@example.com", new LoginMethod.ThirdParty("google", "googleid" + finalI), timeJoined ); + storage.signUp(TenantIdentifier.BASE_TENANT, userId, "tptest" + finalI + "@example.com", + new LoginMethod.ThirdParty("google", "googleid" + finalI), timeJoined); synchronized (lock) { allUserIds.add(userId); } @@ -210,7 +213,7 @@ private void createThirdpartyUsers(Main main) throws Exception { } if (finalI % 10000 == 9999) { - System.out.println("Created " + (finalI +1) + " users"); + System.out.println("Created " + (finalI + 1) + " users"); } }); } @@ -655,7 +658,8 @@ private void sanityCheckAPIs(Main main) throws Exception { JsonArray userRolesArr = response.getAsJsonArray("roles"); assertEquals(1, userRolesArr.size()); assertTrue( - userRolesArr.get(0).getAsString().equals("admin") || userRolesArr.get(0).getAsString().equals("user") + userRolesArr.get(0).getAsString().equals("admin") || + userRolesArr.get(0).getAsString().equals("user") ); } @@ -800,7 +804,8 @@ private void measureOperations(Main main) throws Exception { int finalI = i; es.execute(() -> { try { - ThirdParty.signInUp(main, "twitter", "twitterid" + finalI, "twitter" + finalI + "@example.com"); + ThirdParty.signInUp(main, "twitter", "twitterid" + finalI, + "twitter" + finalI + "@example.com"); } catch (Exception e) { errorCount.incrementAndGet(); throw new RuntimeException(e); @@ -826,7 +831,8 @@ private void measureOperations(Main main) throws Exception { int finalI = i; es.execute(() -> { try { - ThirdParty.signInUp(main, "twitter", "twitterid" + finalI, "twitter" + finalI + "@example.com"); + ThirdParty.signInUp(main, "twitter", "twitterid" + finalI, + "twitter" + finalI + "@example.com"); } catch (Exception e) { errorCount.incrementAndGet(); throw new RuntimeException(e); diff --git a/src/test/java/io/supertokens/storage/mysql/test/StorageLayerTest.java b/src/test/java/io/supertokens/storage/mysql/test/StorageLayerTest.java index 02d6a74..1a3e761 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/StorageLayerTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/StorageLayerTest.java @@ -70,7 +70,7 @@ public static void insertUsedCodeUtil(TOTPSQLStorage storage, TOTPUsedCode usedC @Test public void totpCodeLengthTest() throws Exception { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -112,13 +112,18 @@ public void testLinkedAccountUser() throws Exception { AuthRecipeUserInfo user1 = EmailPassword.signUp(process.getProcess(), "test1@example.com", "password"); Thread.sleep(50); - AuthRecipeUserInfo user2 = ThirdParty.signInUp(process.getProcess(), "google", "googleid", "test2@example.com").user; + AuthRecipeUserInfo user2 = ThirdParty.signInUp(process.getProcess(), "google", "googleid", + "test2@example.com").user; Thread.sleep(50); - Passwordless.CreateCodeResponse code1 = Passwordless.createCode(process.getProcess(), "test3@example.com", null, null, null); - AuthRecipeUserInfo user3 = Passwordless.consumeCode(process.getProcess(), code1.deviceId, code1.deviceIdHash, code1.userInputCode, null).user; + Passwordless.CreateCodeResponse code1 = Passwordless.createCode(process.getProcess(), "test3@example.com", null, + null, null); + AuthRecipeUserInfo user3 = Passwordless.consumeCode(process.getProcess(), code1.deviceId, code1.deviceIdHash, + code1.userInputCode, null).user; Thread.sleep(50); - Passwordless.CreateCodeResponse code2 = Passwordless.createCode(process.getProcess(), null, "+919876543210", null, null); - AuthRecipeUserInfo user4 = Passwordless.consumeCode(process.getProcess(), code2.deviceId, code2.deviceIdHash, code2.userInputCode, null).user; + Passwordless.CreateCodeResponse code2 = Passwordless.createCode(process.getProcess(), null, "+919876543210", + null, null); + AuthRecipeUserInfo user4 = Passwordless.consumeCode(process.getProcess(), code2.deviceId, code2.deviceIdHash, + code2.userInputCode, null).user; AuthRecipe.createPrimaryUser(process.getProcess(), user3.getSupertokensUserId()); AuthRecipe.linkAccounts(process.getProcess(), user1.getSupertokensUserId(), user3.getSupertokensUserId()); @@ -132,8 +137,9 @@ public void testLinkedAccountUser() throws Exception { user4.getSupertokensUserId() }; - for (String userId : userIds){ - AuthRecipeUserInfo primaryUser = ((AuthRecipeStorage) StorageLayer.getStorage(process.getProcess())).getPrimaryUserById( + for (String userId : userIds) { + AuthRecipeUserInfo primaryUser = ((AuthRecipeStorage) StorageLayer.getStorage( + process.getProcess())).getPrimaryUserById( new AppIdentifier(null, null), userId); assertEquals(user3.getSupertokensUserId(), primaryUser.getSupertokensUserId()); assertEquals(4, primaryUser.loginMethods.length); diff --git a/src/test/java/io/supertokens/storage/mysql/test/SuperTokensSaaSSecretTest.java b/src/test/java/io/supertokens/storage/mysql/test/SuperTokensSaaSSecretTest.java index b551c44..208a812 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/SuperTokensSaaSSecretTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/SuperTokensSaaSSecretTest.java @@ -102,10 +102,11 @@ public void testThatTenantCannotSetProtectedConfigIfSuperTokensSaaSSecretIsSet() try { JsonObject j = new JsonObject(); j.addProperty(PROTECTED_CORE_CONFIG[i], ""); - Multitenancy.addNewOrUpdateAppOrTenant(process.main, new TenantConfig(new TenantIdentifier(null, null, "t1"), new EmailPasswordConfig(false), - new ThirdPartyConfig(false, new ThirdPartyConfig.Provider[0]), - new PasswordlessConfig(false), - null, null, j), true); + Multitenancy.addNewOrUpdateAppOrTenant(process.main, + new TenantConfig(new TenantIdentifier(null, null, "t1"), new EmailPasswordConfig(false), + new ThirdPartyConfig(false, new ThirdPartyConfig.Provider[0]), + new PasswordlessConfig(false), + null, null, j), true); fail(); } catch (BadPermissionException e) { assertEquals(e.getMessage(), "Not allowed to modify DB related configs."); @@ -195,7 +196,8 @@ public void testThatTenantCannotGetProtectedConfigIfSuperTokensSaaSSecretIsSet() { JsonObject response = HttpRequestForTesting.sendJsonRequest(process.getProcess(), "", - HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, "/recipe/multitenancy/tenant/list"), + HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, + "/recipe/multitenancy/tenant/list"), null, 1000, 1000, null, SemVer.v3_0.get(), "GET", apiKey, "multitenancy"); @@ -216,7 +218,8 @@ public void testThatTenantCannotGetProtectedConfigIfSuperTokensSaaSSecretIsSet() { JsonObject response = HttpRequestForTesting.sendJsonRequest(process.getProcess(), "", - HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, "/recipe/multitenancy/tenant/list"), + HttpRequestForTesting.getMultitenantUrl(TenantIdentifier.BASE_TENANT, + "/recipe/multitenancy/tenant/list"), null, 1000, 1000, null, SemVer.v3_0.get(), "GET", saasSecret, "multitenancy"); diff --git a/src/test/java/io/supertokens/storage/mysql/test/TableCreationTest.java b/src/test/java/io/supertokens/storage/mysql/test/TableCreationTest.java index ac57459..3d9399e 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/TableCreationTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/TableCreationTest.java @@ -45,7 +45,7 @@ public void beforeEach() { @Test public void checkingCreationOfNewTable() throws InterruptedException { - String[] args = { "../" }; + String[] args = {"../"}; TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); diff --git a/src/test/java/io/supertokens/storage/mysql/test/TestMainThread.java b/src/test/java/io/supertokens/storage/mysql/test/TestMainThread.java index 02607bc..afa7aec 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/TestMainThread.java +++ b/src/test/java/io/supertokens/storage/mysql/test/TestMainThread.java @@ -75,8 +75,9 @@ public void testThatMainThreadIsSameThroughout() throws Exception { JsonObject requestBody = new JsonObject(); requestBody.addProperty("appId", "a1"); requestBody.add("coreConfig", config); - HttpRequestForTesting.sendJsonPUTRequest(process.getProcess(), "", "http://localhost:3567/recipe/multitenancy/app", - requestBody, 1000, 2500, null, "3.0", "multitenancy"); + HttpRequestForTesting.sendJsonPUTRequest(process.getProcess(), "", + "http://localhost:3567/recipe/multitenancy/app", + requestBody, 1000, 2500, null, "3.0", "multitenancy"); Storage storage2 = StorageLayer.getStorage(new TenantIdentifier(null, "a1", null), process.getProcess()); diff --git a/src/test/java/io/supertokens/storage/mysql/test/TestingProcessManager.java b/src/test/java/io/supertokens/storage/mysql/test/TestingProcessManager.java index 2fb5d9a..a9776f9 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/TestingProcessManager.java +++ b/src/test/java/io/supertokens/storage/mysql/test/TestingProcessManager.java @@ -32,7 +32,7 @@ public class TestingProcessManager { static void deleteAllInformation() throws Exception { System.out.println("----------DELETE ALL INFORMATION----------"); - String[] args = { "../" }; + String[] args = {"../"}; TestingProcess process = TestingProcessManager.start(args); process.checkOrWaitForEvent(PROCESS_STATE.STARTED); process.main.deleteAllInformationForTesting(); @@ -148,7 +148,8 @@ public EventAndException checkOrWaitForEvent(PROCESS_STATE state) throws Interru return checkOrWaitForEvent(state, 15000); } - public EventAndException checkOrWaitForEvent(PROCESS_STATE state, long timeToWaitMS) throws InterruptedException { + public EventAndException checkOrWaitForEvent(PROCESS_STATE state, long timeToWaitMS) + throws InterruptedException { EventAndException e = ProcessState.getInstance(main).getLastEventByName(state); if (e == null) { // we shall now wait until some time as passed. diff --git a/src/test/java/io/supertokens/storage/mysql/test/httpRequest/HttpRequestForTesting.java b/src/test/java/io/supertokens/storage/mysql/test/httpRequest/HttpRequestForTesting.java index 1ad2a9e..1a119fa 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/httpRequest/HttpRequestForTesting.java +++ b/src/test/java/io/supertokens/storage/mysql/test/httpRequest/HttpRequestForTesting.java @@ -62,7 +62,8 @@ private static boolean isJsonValid(String jsonInString) { @SuppressWarnings("unchecked") public static T sendGETRequest(Main main, String requestID, String url, Map params, - int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, String rid) + int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, + String rid) throws IOException, HttpResponseException { StringBuilder paramBuilder = new StringBuilder(); @@ -198,101 +199,107 @@ public static T sendJsonRequest(Main main, String requestID, String url, Jso } public static T sendJsonPOSTRequest(Main main, String requestID, String url, JsonElement requestBody, - int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, String rid) + int connectionTimeoutMS, int readTimeoutMS, Integer version, + String cdiVersion, String rid) throws IOException, HttpResponseException { return sendJsonRequest(main, requestID, url, requestBody, connectionTimeoutMS, readTimeoutMS, version, cdiVersion, "POST", null, rid); } public static T sendJsonPOSTRequest(Main main, String requestID, String url, JsonElement requestBody, - int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, String apiKey, String rid) + int connectionTimeoutMS, int readTimeoutMS, Integer version, + String cdiVersion, String apiKey, String rid) throws IOException, HttpResponseException { return sendJsonRequest(main, requestID, url, requestBody, connectionTimeoutMS, readTimeoutMS, version, cdiVersion, "POST", apiKey, rid); } public static T sendJsonPUTRequest(Main main, String requestID, String url, JsonElement requestBody, - int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, String rid) + int connectionTimeoutMS, int readTimeoutMS, Integer version, + String cdiVersion, String rid) throws IOException, HttpResponseException { return sendJsonRequest(main, requestID, url, requestBody, connectionTimeoutMS, readTimeoutMS, version, cdiVersion, "PUT", null, rid); } public static T sendJsonDELETERequest(Main main, String requestID, String url, JsonElement requestBody, - int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, String rid) + int connectionTimeoutMS, int readTimeoutMS, Integer version, + String cdiVersion, String rid) throws IOException, HttpResponseException { return sendJsonRequest(main, requestID, url, requestBody, connectionTimeoutMS, readTimeoutMS, version, cdiVersion, "DELETE", null, rid); } @SuppressWarnings("unchecked") - public static T sendJsonDELETERequestWithQueryParams(Main main, String requestID, String url, Map params, - int connectionTimeoutMS, int readTimeoutMS, Integer version, String cdiVersion, String rid) + public static T sendJsonDELETERequestWithQueryParams(Main main, String requestID, String url, + Map params, + int connectionTimeoutMS, int readTimeoutMS, + Integer version, String cdiVersion, String rid) throws IOException, HttpResponseException { - StringBuilder paramBuilder = new StringBuilder(); + StringBuilder paramBuilder = new StringBuilder(); - if (params != null) { - for (Map.Entry entry : params.entrySet()) { - paramBuilder.append(entry.getKey()).append("=") - .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)).append("&"); - } - } - String paramsStr = paramBuilder.toString(); - if (!paramsStr.equals("")) { - paramsStr = paramsStr.substring(0, paramsStr.length() - 1); - url = url + "?" + paramsStr; + if (params != null) { + for (Map.Entry entry : params.entrySet()) { + paramBuilder.append(entry.getKey()).append("=") + .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)).append("&"); + } + } + String paramsStr = paramBuilder.toString(); + if (!paramsStr.equals("")) { + paramsStr = paramsStr.substring(0, paramsStr.length() - 1); + url = url + "?" + paramsStr; + } + URL obj = getURL(main, requestID, url); + InputStream inputStream = null; + HttpURLConnection con = null; + + try { + con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("DELETE"); + con.setConnectTimeout(connectionTimeoutMS); + con.setReadTimeout(readTimeoutMS + 1000); + if (version != null) { + con.setRequestProperty("api-version", version + ""); + } + if (cdiVersion != null) { + con.setRequestProperty("cdi-version", cdiVersion); + } + if (rid != null) { + con.setRequestProperty("rId", rid); + } + + int responseCode = con.getResponseCode(); + + if (responseCode < STATUS_CODE_ERROR_THRESHOLD) { + inputStream = con.getInputStream(); + } else { + inputStream = con.getErrorStream(); + } + + StringBuilder response = new StringBuilder(); + try (BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); } - URL obj = getURL(main, requestID, url); - InputStream inputStream = null; - HttpURLConnection con = null; - - try { - con = (HttpURLConnection) obj.openConnection(); - con.setRequestMethod("DELETE"); - con.setConnectTimeout(connectionTimeoutMS); - con.setReadTimeout(readTimeoutMS + 1000); - if (version != null) { - con.setRequestProperty("api-version", version + ""); - } - if (cdiVersion != null) { - con.setRequestProperty("cdi-version", cdiVersion); - } - if (rid != null) { - con.setRequestProperty("rId", rid); - } - - int responseCode = con.getResponseCode(); - - if (responseCode < STATUS_CODE_ERROR_THRESHOLD) { - inputStream = con.getInputStream(); - } else { - inputStream = con.getErrorStream(); - } - - StringBuilder response = new StringBuilder(); - try (BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) { - String inputLine; - while ((inputLine = in.readLine()) != null) { - response.append(inputLine); - } - } - if (responseCode < STATUS_CODE_ERROR_THRESHOLD) { - if (!isJsonValid(response.toString())) { - return (T) response.toString(); - } - return (T) (new JsonParser().parse(response.toString())); - } - throw new HttpResponseException(responseCode, response.toString()); - } finally { - if (inputStream != null) { - inputStream.close(); - } - - if (con != null) { - con.disconnect(); - } + } + if (responseCode < STATUS_CODE_ERROR_THRESHOLD) { + if (!isJsonValid(response.toString())) { + return (T) response.toString(); } + return (T) (new JsonParser().parse(response.toString())); + } + throw new HttpResponseException(responseCode, response.toString()); + } finally { + if (inputStream != null) { + inputStream.close(); + } + + if (con != null) { + con.disconnect(); + } } + } public static String getMultitenantUrl(TenantIdentifier tenantIdentifier, String path) { StringBuilder sb = new StringBuilder(); diff --git a/src/test/java/io/supertokens/storage/mysql/test/multitenancy/StorageLayerTest.java b/src/test/java/io/supertokens/storage/mysql/test/multitenancy/StorageLayerTest.java index a01b71b..3934d4f 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/multitenancy/StorageLayerTest.java +++ b/src/test/java/io/supertokens/storage/mysql/test/multitenancy/StorageLayerTest.java @@ -745,7 +745,8 @@ public void testTenantCreationAndThenDbDownDbThrowsErrorInRecipesAndDoesntAffect tenantConfigJson); StorageLayer.getMultitenancyStorage(process.getProcess()).createTenant(tenantConfig); - MultitenancyHelper.getInstance(process.getProcess()).refreshTenantsInCoreBasedOnChangesInCoreConfigOrIfTenantListChanged(true); + MultitenancyHelper.getInstance(process.getProcess()) + .refreshTenantsInCoreBasedOnChangesInCoreConfigOrIfTenantListChanged(true); try { EmailPassword.signIn(tid, (StorageLayer.getStorage(tid, process.getProcess())), diff --git a/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestForNoCrashDuringStartup.java b/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestForNoCrashDuringStartup.java index b2ee097..28efce3 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestForNoCrashDuringStartup.java +++ b/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestForNoCrashDuringStartup.java @@ -107,7 +107,8 @@ public void testThatCUDRecoversWhenItFailsToAddEntryDuringCreation() throws Exce assertEquals(2, allTenants.length); // should have the new CUD try { - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); fail(); } catch (HttpResponseException e) { // ignore @@ -117,14 +118,16 @@ public void testThatCUDRecoversWhenItFailsToAddEntryDuringCreation() throws Exce MultitenancyQueries.simulateErrorInAddingTenantIdInTargetStorage_forTesting = false; // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); } @Test public void testThatCUDRecoversWhenTheDbIsDownDuringCreationButDbComesUpLater() throws Exception { Start start = ((Start) StorageLayer.getBaseStorage(process.getProcess())); try { - update(start, "DROP DATABASE st5000;", pst -> {}); + update(start, "DROP DATABASE st5000;", pst -> { + }); } catch (Exception e) { // ignore } @@ -154,17 +157,20 @@ public void testThatCUDRecoversWhenTheDbIsDownDuringCreationButDbComesUpLater() assertEquals(2, allTenants.length); // should have the new CUD try { - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); fail(); } catch (HttpResponseException e) { // ignore assertTrue(e.getMessage().contains("Internal Error")); // db is still down } - update(start, "CREATE DATABASE st5000;", pst -> {}); + update(start, "CREATE DATABASE st5000;", pst -> { + }); // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); } @Test @@ -260,7 +266,8 @@ public void testThatCoreDoesNotCrashDuringStartupWhenCUDCreationFailedToAddEntry MultitenancyQueries.simulateErrorInAddingTenantIdInTargetStorage_forTesting = false; // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); } @Test @@ -291,7 +298,8 @@ public void testThatCoreDoesNotCrashDuringStartupWhenTenantEntryIsInconsistentIn assertEquals(2, allTenants.length); // should have the new CUD Start start = (Start) StorageLayer.getBaseStorage(process.getProcess()); - update(start, "DELETE FROM apps;", pst -> {}); + update(start, "DELETE FROM apps;", pst -> { + }); process.kill(false); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); @@ -306,13 +314,15 @@ public void testThatCoreDoesNotCrashDuringStartupWhenTenantEntryIsInconsistentIn MultitenancyQueries.simulateErrorInAddingTenantIdInTargetStorage_forTesting = false; // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); Session.createNewSession(process.getProcess(), "userid", new JsonObject(), new JsonObject()); } @Test - public void testThatCoreDoesNotCrashDuringStartupWhenAppCreationFailedToAddEntryInTheBaseTenantStorage() throws Exception { + public void testThatCoreDoesNotCrashDuringStartupWhenAppCreationFailedToAddEntryInTheBaseTenantStorage() + throws Exception { JsonObject coreConfig = new JsonObject(); TenantIdentifier tenantIdentifier = new TenantIdentifier(null, "a1", null); @@ -354,7 +364,8 @@ public void testThatCoreDoesNotCrashDuringStartupWhenAppCreationFailedToAddEntry assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); Session.createNewSession( new TenantIdentifier(null, "a1", null), @@ -364,7 +375,8 @@ public void testThatCoreDoesNotCrashDuringStartupWhenAppCreationFailedToAddEntry } @Test - public void testThatCoreDoesNotCrashDuringStartupWhenCUDCreationFailedToAddTenantEntryInTargetStorageWithLoadOnlyCUDConfig() throws Exception { + public void testThatCoreDoesNotCrashDuringStartupWhenCUDCreationFailedToAddTenantEntryInTargetStorageWithLoadOnlyCUDConfig() + throws Exception { JsonObject coreConfig = new JsonObject(); TenantIdentifier tenantIdentifier = new TenantIdentifier("127.0.0.1", null, null); @@ -442,10 +454,12 @@ public void testThatCoreDoesNotCrashDuringStartupWhenCUDCreationFailedToAddTenan assertEquals(2, allTenants.length); // should have the new CUD // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); try { - tpSignInUpAndGetResponse(new TenantIdentifier("localhost", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("localhost", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); fail(); } catch (HttpResponseException e) { // ignore @@ -465,9 +479,11 @@ public void testThatCoreDoesNotCrashDuringStartupWhenCUDCreationFailedToAddTenan assertEquals(2, allTenants.length); // should have the new CUD // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("localhost", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("localhost", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); try { - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); fail(); } catch (HttpResponseException e) { // ignore @@ -488,7 +504,8 @@ public void testThatCoreDoesNotCrashDuringStartupWhenCUDCreationFailedToAddTenan public void testThatTenantComesToLifeOnceTheTargetDbIsUpAfterCoreRestart() throws Exception { Start start = ((Start) StorageLayer.getBaseStorage(process.getProcess())); try { - update(start, "DROP DATABASE st5000;", pst -> {}); + update(start, "DROP DATABASE st5000;", pst -> { + }); } catch (Exception e) { // ignore } @@ -518,7 +535,8 @@ public void testThatTenantComesToLifeOnceTheTargetDbIsUpAfterCoreRestart() throw assertEquals(2, allTenants.length); // should have the new CUD try { - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); fail(); } catch (HttpResponseException e) { // ignore @@ -537,13 +555,16 @@ public void testThatTenantComesToLifeOnceTheTargetDbIsUpAfterCoreRestart() throw // the process should start successfully even though the db is down start = ((Start) StorageLayer.getBaseStorage(process.getProcess())); - update(start, "CREATE DATABASE st5000;", pst -> {}); + update(start, "CREATE DATABASE st5000;", pst -> { + }); // this should succeed now - tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", "test@example.com", process.getProcess(), SemVer.v5_0); + tpSignInUpAndGetResponse(new TenantIdentifier("127.0.0.1", null, null), "google", "googleid1", + "test@example.com", process.getProcess(), SemVer.v5_0); } - public static JsonObject tpSignInUpAndGetResponse(TenantIdentifier tenantIdentifier, String thirdPartyId, String thirdPartyUserId, String email, Main main, SemVer version) + public static JsonObject tpSignInUpAndGetResponse(TenantIdentifier tenantIdentifier, String thirdPartyId, + String thirdPartyUserId, String email, Main main, SemVer version) throws HttpResponseException, IOException { JsonObject emailObject = new JsonObject(); emailObject.addProperty("id", email); diff --git a/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestUserPoolIdChangeBehaviour.java b/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestUserPoolIdChangeBehaviour.java index 77d1ad3..8151051 100644 --- a/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestUserPoolIdChangeBehaviour.java +++ b/src/test/java/io/supertokens/storage/mysql/test/multitenancy/TestUserPoolIdChangeBehaviour.java @@ -15,6 +15,7 @@ */ package io.supertokens.storage.mysql.test.multitenancy; + import com.google.gson.JsonObject; import io.supertokens.ProcessState; import io.supertokens.emailpassword.EmailPassword; @@ -110,7 +111,8 @@ public void testUsersWorkAfterUserPoolIdChanges() throws Exception { String userPoolId2 = storage.getUserPoolId(); assertNotEquals(userPoolId, userPoolId2); - AuthRecipeUserInfo user2 = EmailPassword.signIn(tenantIdentifier, storage, process.getProcess(), "user@example.com", "password"); + AuthRecipeUserInfo user2 = EmailPassword.signIn(tenantIdentifier, storage, process.getProcess(), + "user@example.com", "password"); assertEquals(userInfo, user2); } @@ -160,7 +162,8 @@ public void testUsersWorkAfterUserPoolIdChangesAndServerRestart() throws Excepti String userPoolId2 = storage.getUserPoolId(); assertNotEquals(userPoolId, userPoolId2); - AuthRecipeUserInfo user2 = EmailPassword.signIn(tenantIdentifier, storage, process.getProcess(), "user@example.com", "password"); + AuthRecipeUserInfo user2 = EmailPassword.signIn(tenantIdentifier, storage, process.getProcess(), + "user@example.com", "password"); assertEquals(userInfo, user2); }