From 1a57c247b21fcf427dbc5e2234a4ce21c7d2da53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20S=C3=B3jko?= Date: Tue, 18 Jun 2024 09:29:24 +0200 Subject: [PATCH] chore: release latest changes (#1056) * chore: release latest changes * update yarn lockfile * remove stale files * fix ci env * remove mysql command overwrite * remove mysql overwrite from example * fix cookie cooldown in memory --- .github/ci.env | 3 + .github/workflows/publish.yml | 34 +- .pnp.cjs | 88 +++- ...parser-npm-1.4.6-27287e1e43-b1bbb17bc4.zip | Bin 0 -> 3392 bytes .../axios-npm-1.6.7-d7b9974d1b-a1932b089e.zip | Bin 0 -> 501346 bytes ...cookie-npm-0.4.1-cc5e2ebb42-0f2defd60a.zip | Bin 0 -> 7631 bytes ...parser-npm-1.4.6-a68f84d02a-1e5a63aa82.zip | Bin 0 -> 5473 bytes ...rects-npm-1.15.5-9d14db76ca-d467f13c1c.zip | Bin 0 -> 11155 bytes ...mysql2-npm-3.3.3-d2fe8cf512-4bf7ace8f1.zip | Bin 191309 -> 0 bytes ...mysql2-npm-3.9.7-8fe89e50ac-7f43b17cc0.zip | Bin 0 -> 244506 bytes docker-compose.ci.yml | 1 - docker-compose.example.yml | 1 - package.json | 4 +- packages/analytics/Dockerfile | 6 + packages/analytics/package.json | 4 +- packages/api-gateway/CHANGELOG.md | 18 - packages/api-gateway/Dockerfile | 6 + packages/api-gateway/bin/server.ts | 25 +- packages/api-gateway/package.json | 4 +- .../api-gateway/src/Bootstrap/Container.ts | 8 +- packages/api-gateway/src/Bootstrap/Types.ts | 2 + .../src/Controller/AuthMiddleware.ts | 28 +- .../Controller/GRPCWebSocketAuthMiddleware.ts | 1 + .../src/Controller/LegacyController.ts | 2 - .../src/Controller/ResponseLocals.ts | 1 + .../src/Controller/v1/ActionsController.ts | 13 +- .../src/Controller/v1/UsersController.ts | 27 +- .../Redis/RedisCrossServiceTokenCache.ts | 5 +- .../DirectCall/DirectCallServiceProxy.ts | 33 +- .../src/Service/Http/HttpServiceProxy.ts | 63 ++- .../Service/Proxy/ServiceProxyInterface.ts | 17 +- .../src/Service/Resolver/EndpointResolver.ts | 3 +- .../src/Service/gRPC/GRPCServiceProxy.ts | 70 +++- .../gRPC/GRPCSyncingServerServiceProxy.ts | 1 + packages/auth/.env.sample | 9 + packages/auth/CHANGELOG.md | 18 - packages/auth/Dockerfile | 6 + packages/auth/bin/server.ts | 2 + packages/auth/bin/user_email_backup.ts | 30 +- .../1707759514236-user-roles-content-limit.ts | 25 ++ .../1707813542369-add-session-version.ts | 13 + ...33001993-add-session-private-identifier.ts | 17 + ...-add-revoked-session-private-identifier.ts | 19 + ...39-add-application-and-snjs-to-sessions.ts | 15 + ...9514236-user-roles-content-limit-sqlite.ts | 25 ++ .../1707813542369-add-session-version.ts | 13 + ...33169237-add-session-private-identifier.ts | 37 ++ ...-add-revoked-session-private-identifier.ts | 34 ++ ...39-add-application-and-snjs-to-sessions.ts | 15 + packages/auth/package.json | 11 +- packages/auth/src/Bootstrap/Container.ts | 247 +++++++++-- packages/auth/src/Bootstrap/Types.ts | 16 +- .../src/Controller/AuthController.spec.ts | 149 ------- .../auth/src/Controller/AuthController.ts | 164 +------- .../SubscriptionInvitesController.spec.ts | 23 +- .../auth/src/Domain/Api/ApiVersion.spec.ts | 46 +++ packages/auth/src/Domain/Api/ApiVersion.ts | 41 +- .../auth/src/Domain/Api/ApiVersionProps.ts | 3 + .../src/Domain/Auth/AuthResponse20200115.ts | 4 +- .../Domain/Auth/AuthResponseCreationResult.ts | 10 + .../Auth/AuthResponseFactory20161215.spec.ts | 5 +- .../Auth/AuthResponseFactory20161215.ts | 13 +- .../Auth/AuthResponseFactory20190520.spec.ts | 5 +- .../Auth/AuthResponseFactory20200115.spec.ts | 35 +- .../Auth/AuthResponseFactory20200115.ts | 33 +- .../Auth/AuthResponseFactoryInterface.ts | 11 +- .../Auth/AuthResponseFactoryResolver.spec.ts | 19 +- .../Auth/AuthResponseFactoryResolver.ts | 12 +- .../AuthResponseFactoryResolverInterface.ts | 3 +- .../src/Domain/Auth/AuthenticationMethod.ts | 1 + .../Auth/AuthenticationMethodResolver.spec.ts | 69 +++- .../Auth/AuthenticationMethodResolver.ts | 40 +- .../AuthenticationMethodResolverInterface.ts | 13 +- .../src/Domain/Auth/Cookies/CookieFactory.ts | 28 ++ .../Auth/Cookies/CookieFactoryInterface.ts | 8 + .../src/Domain/Event/DomainEventFactory.ts | 9 +- .../Event/DomainEventFactoryInterface.ts | 7 +- .../CaptchaServerInterface.ts | 3 + .../EphemeralSessionRepositoryInterface.ts | 1 + .../auth/src/Domain/Session/RevokedSession.ts | 10 + .../RevokedSessionRepositoryInterface.ts | 1 + packages/auth/src/Domain/Session/Session.ts | 34 ++ .../Domain/Session/SessionCreationResult.ts | 12 + .../Session/SessionRepositoryInterface.ts | 1 + .../src/Domain/Session/SessionService.spec.ts | 391 +++++++++++------- .../auth/src/Domain/Session/SessionService.ts | 190 +++++---- .../Domain/Session/SessionServiceInterface.ts | 26 +- ...essionTokensCooldownRepositoryInterface.ts | 14 + .../Setting/SettingsAssociationService.ts | 4 - .../ApplyDefaultSubscriptionSettings.spec.ts | 5 +- .../UseCase/AuthenticateRequest.spec.ts | 45 +- .../src/Domain/UseCase/AuthenticateRequest.ts | 9 +- .../Domain/UseCase/AuthenticateRequestDTO.ts | 11 +- .../Domain/UseCase/AuthenticateUser.spec.ts | 74 +++- .../src/Domain/UseCase/AuthenticateUser.ts | 27 +- .../src/Domain/UseCase/AuthenticateUserDTO.ts | 11 +- .../UseCase/AuthenticateUserResponse.ts | 2 +- .../ChangeCredentials.spec.ts | 67 ++- .../ChangeCredentials/ChangeCredentials.ts | 22 +- .../ChangeCredentials/ChangeCredentialsDTO.ts | 2 + .../Domain/UseCase/ClearLoginAttempts.spec.ts | 10 +- .../src/Domain/UseCase/ClearLoginAttempts.ts | 28 +- .../CooldownSessionTokens.ts | 28 ++ .../CooldownSessionTokensDTO.ts | 5 + .../CreateCrossServiceToken.spec.ts | 58 +++ .../CreateCrossServiceToken.ts | 12 +- .../DeleteSessionByToken.spec.ts | 90 ++++ .../DeleteSessionByToken.ts | 30 ++ .../DeleteSessionByTokenDTO.ts | 12 + .../DeleteSetting/DeleteSetting.spec.ts | 16 + .../UseCase/DeleteSetting/DeleteSetting.ts | 12 +- ...bleEmailSettingBasedOnEmailSubscription.ts | 4 - .../GetCooldownSessionTokens.spec.ts | 47 +++ .../GetCooldownSessionTokens.ts | 27 ++ .../GetCooldownSessionTokensDTO.ts | 3 + .../GetCooldownSessionTokensResponse.ts | 4 + .../GetSessionFromToken.spec.ts | 272 ++++++++++++ .../GetSessionFromToken.ts | 160 +++++++ .../GetSessionFromTokenDTO.ts | 12 + .../GetSessionFromTokenResult.ts | 8 + .../GetUserKeyParams.spec.ts | 32 ++ .../GetUserKeyParamsRecovery.ts | 11 + .../GetUserKeyParamsRecoveryDTO.ts | 1 + .../UseCase/IncreaseLoginAttempts.spec.ts | 46 +-- .../Domain/UseCase/IncreaseLoginAttempts.ts | 50 ++- .../UseCase/IncreaseLoginAttemptsResponse.ts | 4 +- .../UseCase/RefreshSessionToken.spec.ts | 183 +++++--- .../src/Domain/UseCase/RefreshSessionToken.ts | 129 +++++- .../Domain/UseCase/RefreshSessionTokenDTO.ts | 15 +- .../UseCase/RefreshSessionTokenResponse.ts | 20 +- .../auth/src/Domain/UseCase/Register.spec.ts | 68 ++- packages/auth/src/Domain/UseCase/Register.ts | 18 +- .../auth/src/Domain/UseCase/RegisterDTO.ts | 2 + .../src/Domain/UseCase/RegisterResponse.ts | 4 +- .../SetSubscriptionSettingValue.spec.ts | 27 +- .../SetSubscriptionSettingValue.ts | 18 +- .../SetSubscriptionSettingValueDTO.ts | 1 + .../auth/src/Domain/UseCase/SignIn.spec.ts | 139 ++++++- packages/auth/src/Domain/UseCase/SignIn.ts | 111 +++-- packages/auth/src/Domain/UseCase/SignInDTO.ts | 15 +- .../auth/src/Domain/UseCase/SignInResponse.ts | 19 +- .../SignInWithRecoveryCodes.spec.ts | 92 +++++ .../SignInWithRecoveryCodes.ts | 50 ++- .../SignInWithRecoveryCodesDTO.ts | 4 + .../TriggerEmailBackupForUser.spec.ts | 25 +- .../TriggerEmailBackupForUser.ts | 25 +- .../TriggerPostSettingUpdateActions.ts | 9 +- .../src/Domain/UseCase/UpdateUser.spec.ts | 60 --- .../auth/src/Domain/UseCase/UpdateUser.ts | 39 -- .../auth/src/Domain/UseCase/UpdateUserDTO.ts | 7 - .../src/Domain/UseCase/UpdateUserResponse.ts | 7 - .../VerifyHumanInteraction.spec.ts | 43 ++ .../VerifyHumanInteraction.ts | 23 ++ .../Domain/User/LockRepositoryInterface.ts | 5 +- .../HumanVerification/HttpCaptchaServer.ts | 31 ++ ...InMemorySessionTokensCooldownRepository.ts | 41 ++ .../AnnotatedAdminController.ts | 9 +- .../AnnotatedAuthController.ts | 59 ++- .../AnnotatedSessionController.ts | 4 +- ...AnnotatedSubscriptionSettingsController.ts | 25 +- .../AnnotatedUsersController.ts | 11 +- .../Base/BaseAdminController.ts | 28 ++ .../Base/BaseAuthController.ts | 383 +++++++++++------ .../Base/BaseSessionController.ts | 60 ++- .../Base/BaseSessionsController.ts | 27 +- .../BaseSubscriptionSettingsController.ts | 83 ++++ .../Base/BaseUsersController.ts | 27 +- .../Redis/RedisEphemeralSessionRepository.ts | 11 + .../src/Infra/Redis/RedisLockRepository.ts | 60 +++ .../RedisSessionTokensCooldownRepository.ts | 42 ++ .../TypeORMEphemeralSessionRepository.ts | 20 + .../Infra/TypeORM/TypeORMLockRepository.ts | 35 +- .../TypeORMRevokedSessionRepository.ts | 7 + .../Infra/TypeORM/TypeORMSessionRepository.ts | 7 + packages/auth/src/Infra/gRPC/AuthServer.ts | 31 +- packages/common/package.json | 2 +- packages/domain-core/package.json | 2 +- .../src/Domain/Email/EmailLevel.ts | 1 - .../src/Domain/Setting/SettingName.ts | 2 - packages/domain-events-infra/package.json | 2 +- .../Redis/RedisDomainEventPublisher.spec.ts | 5 +- packages/domain-events/package.json | 2 +- .../Event/EmailBackupRequestedEventPayload.ts | 2 - packages/files/CHANGELOG.md | 12 - packages/files/Dockerfile | 6 + packages/files/bin/server.ts | 5 +- packages/files/package.json | 5 +- packages/files/src/Bootstrap/Container.ts | 36 +- packages/files/src/Bootstrap/Types.ts | 2 + .../FinishUploadSession.spec.ts | 21 +- .../FinishUploadSession.ts | 4 + .../FinishUploadSessionDTO.ts | 1 + .../UseCase/RemoveFile/RemoveFile.spec.ts | 13 +- .../Domain/UseCase/RemoveFile/RemoveFile.ts | 4 + .../UseCase/RemoveFile/RemoveFileDTO.ts | 1 + .../StreamDownloadFile.spec.ts | 27 +- .../StreamDownloadFile/StreamDownloadFile.ts | 6 + .../StreamDownloadFileDTO.ts | 2 + .../ValetTokenRepositoryInterface.ts | 4 + .../AnnotatedFilesController.spec.ts | 10 +- .../AnnotatedFilesController.ts | 41 +- .../AnnotatedSharedVaultFilesController.ts | 76 ++-- .../SharedVaultValetTokenAuthMiddleware.ts | 40 +- .../SharedVaultValetTokenResponseLocals.ts | 6 + .../ValetTokenAuthMiddleware.spec.ts | 20 +- .../Middleware/ValetTokenAuthMiddleware.ts | 34 +- .../Middleware/ValetTokenResponseLocals.ts | 14 + .../Infra/Redis/RedisValetTokenRepository.ts | 19 + packages/grpc/lib/auth_grpc_pb.d.ts | 20 +- packages/grpc/lib/auth_grpc_pb.js | 28 +- packages/grpc/lib/auth_pb.d.ts | 52 ++- packages/grpc/lib/auth_pb.js | 338 +++++++++++++-- packages/grpc/proto/auth.proto | 11 +- packages/home-server/.env.sample | 4 + packages/home-server/CHANGELOG.md | 28 -- packages/home-server/package.json | 4 +- packages/home-server/src/Server/HomeServer.ts | 4 + packages/predicates/package.json | 2 +- packages/revisions/Dockerfile | 6 + packages/revisions/package.json | 5 +- packages/scheduler/Dockerfile | 6 + packages/scheduler/package.json | 5 +- packages/security/package.json | 2 +- .../src/Domain/Token/CrossServiceTokenData.ts | 1 + packages/settings/src/Domain/index.ts | 1 - packages/sncrypto-node/package.json | 2 +- packages/syncing-server/CHANGELOG.md | 6 - packages/syncing-server/Dockerfile | 6 + packages/syncing-server/package.json | 7 +- .../syncing-server/src/Bootstrap/Container.ts | 18 + .../syncing-server/src/Bootstrap/Types.ts | 2 + .../src/Domain/Item/ItemHash.ts | 4 + .../CheckForContentLimit.spec.ts | 95 +++++ .../CheckForContentLimit.ts | 66 +++ .../CheckForContentLimitDTO.ts | 6 + .../Syncing/SaveItems/SaveItems.spec.ts | 72 ++++ .../UseCase/Syncing/SaveItems/SaveItems.ts | 16 + .../UseCase/Syncing/SaveItems/SaveItemsDTO.ts | 1 + .../Syncing/SyncItems/SyncItems.spec.ts | 12 + .../UseCase/Syncing/SyncItems/SyncItems.ts | 1 + .../UseCase/Syncing/SyncItems/SyncItemsDTO.ts | 1 + .../Base/BaseItemsController.ts | 1 + .../InversifyExpressAuthMiddleware.ts | 1 + .../InversifyExpressUtils/ResponseLocals.ts | 1 + .../src/Infra/gRPC/SyncingServer.ts | 2 + packages/time/package.json | 2 +- packages/websockets/Dockerfile | 6 + packages/websockets/package.json | 5 +- yarn.lock | 75 +++- 249 files changed, 5445 insertions(+), 1781 deletions(-) create mode 100644 .yarn/cache/@types-cookie-parser-npm-1.4.6-27287e1e43-b1bbb17bc4.zip create mode 100644 .yarn/cache/axios-npm-1.6.7-d7b9974d1b-a1932b089e.zip create mode 100644 .yarn/cache/cookie-npm-0.4.1-cc5e2ebb42-0f2defd60a.zip create mode 100644 .yarn/cache/cookie-parser-npm-1.4.6-a68f84d02a-1e5a63aa82.zip create mode 100644 .yarn/cache/follow-redirects-npm-1.15.5-9d14db76ca-d467f13c1c.zip delete mode 100644 .yarn/cache/mysql2-npm-3.3.3-d2fe8cf512-4bf7ace8f1.zip create mode 100644 .yarn/cache/mysql2-npm-3.9.7-8fe89e50ac-7f43b17cc0.zip create mode 100644 packages/auth/migrations/mysql/1707759514236-user-roles-content-limit.ts create mode 100644 packages/auth/migrations/mysql/1707813542369-add-session-version.ts create mode 100644 packages/auth/migrations/mysql/1709133001993-add-session-private-identifier.ts create mode 100644 packages/auth/migrations/mysql/1709206805226-add-revoked-session-private-identifier.ts create mode 100644 packages/auth/migrations/mysql/1710236132439-add-application-and-snjs-to-sessions.ts create mode 100644 packages/auth/migrations/sqlite/1707759514236-user-roles-content-limit-sqlite.ts create mode 100644 packages/auth/migrations/sqlite/1707813542369-add-session-version.ts create mode 100644 packages/auth/migrations/sqlite/1709133169237-add-session-private-identifier.ts create mode 100644 packages/auth/migrations/sqlite/1709208455658-add-revoked-session-private-identifier.ts create mode 100644 packages/auth/migrations/sqlite/1710236132439-add-application-and-snjs-to-sessions.ts delete mode 100644 packages/auth/src/Controller/AuthController.spec.ts create mode 100644 packages/auth/src/Domain/Api/ApiVersion.spec.ts create mode 100644 packages/auth/src/Domain/Api/ApiVersionProps.ts create mode 100644 packages/auth/src/Domain/Auth/AuthResponseCreationResult.ts create mode 100644 packages/auth/src/Domain/Auth/Cookies/CookieFactory.ts create mode 100644 packages/auth/src/Domain/Auth/Cookies/CookieFactoryInterface.ts create mode 100644 packages/auth/src/Domain/HumanVerification/CaptchaServerInterface.ts create mode 100644 packages/auth/src/Domain/Session/SessionCreationResult.ts create mode 100644 packages/auth/src/Domain/Session/SessionTokensCooldownRepositoryInterface.ts create mode 100644 packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokens.ts create mode 100644 packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokensDTO.ts create mode 100644 packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.spec.ts create mode 100644 packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.ts create mode 100644 packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByTokenDTO.ts create mode 100644 packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.spec.ts create mode 100644 packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.ts create mode 100644 packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensDTO.ts create mode 100644 packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensResponse.ts create mode 100644 packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.spec.ts create mode 100644 packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.ts create mode 100644 packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenDTO.ts create mode 100644 packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenResult.ts delete mode 100644 packages/auth/src/Domain/UseCase/UpdateUser.spec.ts delete mode 100644 packages/auth/src/Domain/UseCase/UpdateUser.ts delete mode 100644 packages/auth/src/Domain/UseCase/UpdateUserDTO.ts delete mode 100644 packages/auth/src/Domain/UseCase/UpdateUserResponse.ts create mode 100644 packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.spec.ts create mode 100644 packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.ts create mode 100644 packages/auth/src/Infra/Http/HumanVerification/HttpCaptchaServer.ts create mode 100644 packages/auth/src/Infra/InMemory/InMemorySessionTokensCooldownRepository.ts create mode 100644 packages/auth/src/Infra/Redis/RedisLockRepository.ts create mode 100644 packages/auth/src/Infra/Redis/RedisSessionTokensCooldownRepository.ts create mode 100644 packages/files/src/Domain/ValetToken/ValetTokenRepositoryInterface.ts create mode 100644 packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenResponseLocals.ts create mode 100644 packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenResponseLocals.ts create mode 100644 packages/files/src/Infra/Redis/RedisValetTokenRepository.ts create mode 100644 packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.spec.ts create mode 100644 packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.ts create mode 100644 packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimitDTO.ts diff --git a/.github/ci.env b/.github/ci.env index 504118f27..c90c60eb0 100644 --- a/.github/ci.env +++ b/.github/ci.env @@ -17,6 +17,9 @@ SYNCING_SERVER_LOG_LEVEL=debug FILES_SERVER_LOG_LEVEL=debug REVISIONS_SERVER_LOG_LEVEL=debug API_GATEWAY_LOG_LEVEL=debug +COOKIE_DOMAIN=localhost +COOKIE_SECURE=false +COOKIE_PARTITIONED=false MYSQL_DATABASE=standard_notes_db MYSQL_USER=std_notes_user diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ec9075ee2..c65c7807a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -98,32 +98,30 @@ jobs: - name: Test run: yarn test - # e2e-base: - # needs: build - # name: E2E Base Suite - # uses: standardnotes/server/.github/workflows/common-e2e.yml@main - # with: - # snjs_image_tag: 'latest' - # suite: 'base' + e2e-base: + needs: build + name: E2E Base Suite + uses: standardnotes/server/.github/workflows/common-e2e.yml@main + with: + snjs_image_tag: 'latest' + suite: 'base' - # e2e-vaults: - # needs: build - # name: E2E Vaults Suite - # uses: standardnotes/server/.github/workflows/common-e2e.yml@main - # with: - # snjs_image_tag: 'latest' - # suite: 'vaults' + e2e-vaults: + needs: build + name: E2E Vaults Suite + uses: standardnotes/server/.github/workflows/common-e2e.yml@main + with: + snjs_image_tag: 'latest' + suite: 'vaults' publish-self-hosting: - # needs: [ test, lint, e2e-base, e2e-vaults ] - needs: [ test, lint ] + needs: [ test, lint, e2e-base, e2e-vaults ] name: Publish Self Hosting Docker Image uses: standardnotes/server/.github/workflows/common-self-hosting.yml@main secrets: inherit publish-services: - # needs: [ test, lint, e2e-base, e2e-vaults ] - needs: [ test, lint ] + needs: [ test, lint, e2e-base, e2e-vaults ] runs-on: ubuntu-latest diff --git a/.pnp.cjs b/.pnp.cjs index a05b249f9..57b64b29e 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -6356,7 +6356,7 @@ const RAW_RUNTIME_STATE = ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ ["mixpanel", "npm:0.17.0"],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["prettier", "npm:3.0.3"],\ ["reflect-metadata", "npm:0.2.1"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\ @@ -6396,6 +6396,7 @@ const RAW_RUNTIME_STATE = ["@standardnotes/grpc", "workspace:packages/grpc"],\ ["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/time", "workspace:packages/time"],\ + ["@types/cookie-parser", "npm:1.4.6"],\ ["@types/cors", "npm:2.8.13"],\ ["@types/express", "npm:4.17.17"],\ ["@types/ioredis", "npm:5.0.0"],\ @@ -6407,6 +6408,7 @@ const RAW_RUNTIME_STATE = ["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\ ["agentkeepalive", "npm:4.5.0"],\ ["axios", "npm:1.6.1"],\ + ["cookie-parser", "npm:1.4.6"],\ ["cors", "npm:2.8.5"],\ ["dotenv", "npm:16.1.3"],\ ["eslint", "npm:8.41.0"],\ @@ -6457,6 +6459,7 @@ const RAW_RUNTIME_STATE = ["@standardnotes/sncrypto-node", "workspace:packages/sncrypto-node"],\ ["@standardnotes/time", "workspace:packages/time"],\ ["@types/bcryptjs", "npm:2.4.2"],\ + ["@types/cookie-parser", "npm:1.4.6"],\ ["@types/cors", "npm:2.8.13"],\ ["@types/express", "npm:4.17.17"],\ ["@types/ioredis", "npm:5.0.0"],\ @@ -6468,7 +6471,10 @@ const RAW_RUNTIME_STATE = ["@types/uuid", "npm:9.0.3"],\ ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\ ["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\ + ["agentkeepalive", "npm:4.5.0"],\ + ["axios", "npm:1.6.7"],\ ["bcryptjs", "npm:2.4.3"],\ + ["cookie-parser", "npm:1.4.6"],\ ["cors", "npm:2.8.5"],\ ["dayjs", "npm:1.11.7"],\ ["dotenv", "npm:16.1.3"],\ @@ -6479,7 +6485,7 @@ const RAW_RUNTIME_STATE = ["inversify-express-utils", "npm:6.4.3"],\ ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["otplib", "npm:12.0.1"],\ ["prettier", "npm:3.0.3"],\ ["prettyjson", "npm:1.2.5"],\ @@ -6689,10 +6695,12 @@ const RAW_RUNTIME_STATE = ["@standardnotes/files-server", "workspace:packages/files"],\ ["@standardnotes/revisions-server", "workspace:packages/revisions"],\ ["@standardnotes/syncing-server", "workspace:packages/syncing-server"],\ + ["@types/cookie-parser", "npm:1.4.6"],\ ["@types/cors", "npm:2.8.13"],\ ["@types/express", "npm:4.17.17"],\ ["@typescript-eslint/eslint-plugin", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\ ["@typescript-eslint/parser", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:6.5.0"],\ + ["cookie-parser", "npm:1.4.6"],\ ["cors", "npm:2.8.5"],\ ["dotenv", "npm:16.1.3"],\ ["eslint", "npm:8.41.0"],\ @@ -6790,7 +6798,7 @@ const RAW_RUNTIME_STATE = ["inversify-express-utils", "npm:6.4.3"],\ ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["prettier", "npm:3.0.3"],\ ["reflect-metadata", "npm:0.2.1"],\ ["sqlite3", "virtual:31b5a94a105c89c9294c3d524a7f8929fe63ee5a2efadf21951ca4c0cfd2ecf02e8f4ef5a066bbda091f1e3a56e57c6749069a080618c96b22e51131a330fc4a#npm:5.1.6"],\ @@ -6826,7 +6834,7 @@ const RAW_RUNTIME_STATE = ["inversify", "npm:6.0.1"],\ ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["prettier", "npm:3.0.3"],\ ["reflect-metadata", "npm:0.2.1"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\ @@ -6977,7 +6985,7 @@ const RAW_RUNTIME_STATE = ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ ["jsonwebtoken", "npm:9.0.0"],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["prettier", "npm:3.0.3"],\ ["prettyjson", "npm:1.2.5"],\ ["reflect-metadata", "npm:0.2.1"],\ @@ -7057,7 +7065,7 @@ const RAW_RUNTIME_STATE = ["inversify-express-utils", "npm:6.4.3"],\ ["ioredis", "npm:5.3.2"],\ ["jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.5.0"],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["prettier", "npm:3.0.3"],\ ["reflect-metadata", "npm:0.2.1"],\ ["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\ @@ -7237,6 +7245,16 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@types/cookie-parser", [\ + ["npm:1.4.6", {\ + "packageLocation": "./.yarn/cache/@types-cookie-parser-npm-1.4.6-27287e1e43-b1bbb17bc4.zip/node_modules/@types/cookie-parser/",\ + "packageDependencies": [\ + ["@types/cookie-parser", "npm:1.4.6"],\ + ["@types/express", "npm:4.17.17"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/cors", [\ ["npm:2.8.13", {\ "packageLocation": "./.yarn/cache/@types-cors-npm-2.8.13-4b8ac1068f-7ef197ea19.zip/node_modules/@types/cors/",\ @@ -8497,6 +8515,16 @@ const RAW_RUNTIME_STATE = ["proxy-from-env", "npm:1.1.0"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:1.6.7", {\ + "packageLocation": "./.yarn/cache/axios-npm-1.6.7-d7b9974d1b-a1932b089e.zip/node_modules/axios/",\ + "packageDependencies": [\ + ["axios", "npm:1.6.7"],\ + ["follow-redirects", "virtual:d7b9974d1bba76881cc57a280a16dd4914416a6fc4923c2efbb6328057412974da1e719cef1530b7a62b97d85d828f7e1d49b5f6de3b5b0854d49902ec87827c#npm:1.15.5"],\ + ["form-data", "npm:4.0.0"],\ + ["proxy-from-env", "npm:1.1.0"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["babel-jest", [\ @@ -9608,6 +9636,13 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["cookie", [\ + ["npm:0.4.1", {\ + "packageLocation": "./.yarn/cache/cookie-npm-0.4.1-cc5e2ebb42-0f2defd60a.zip/node_modules/cookie/",\ + "packageDependencies": [\ + ["cookie", "npm:0.4.1"]\ + ],\ + "linkType": "HARD"\ + }],\ ["npm:0.5.0", {\ "packageLocation": "./.yarn/cache/cookie-npm-0.5.0-e2d58a161a-aae7911ddc.zip/node_modules/cookie/",\ "packageDependencies": [\ @@ -9616,6 +9651,17 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["cookie-parser", [\ + ["npm:1.4.6", {\ + "packageLocation": "./.yarn/cache/cookie-parser-npm-1.4.6-a68f84d02a-1e5a63aa82.zip/node_modules/cookie-parser/",\ + "packageDependencies": [\ + ["cookie-parser", "npm:1.4.6"],\ + ["cookie", "npm:0.4.1"],\ + ["cookie-signature", "npm:1.0.6"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["cookie-signature", [\ ["npm:1.0.6", {\ "packageLocation": "./.yarn/cache/cookie-signature-npm-1.0.6-93f325f7f0-f4e1b0a98a.zip/node_modules/cookie-signature/",\ @@ -10864,6 +10910,26 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ + ["npm:1.15.5", {\ + "packageLocation": "./.yarn/cache/follow-redirects-npm-1.15.5-9d14db76ca-d467f13c1c.zip/node_modules/follow-redirects/",\ + "packageDependencies": [\ + ["follow-redirects", "npm:1.15.5"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:d7b9974d1bba76881cc57a280a16dd4914416a6fc4923c2efbb6328057412974da1e719cef1530b7a62b97d85d828f7e1d49b5f6de3b5b0854d49902ec87827c#npm:1.15.5", {\ + "packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-393395f3f6/0/cache/follow-redirects-npm-1.15.5-9d14db76ca-d467f13c1c.zip/node_modules/follow-redirects/",\ + "packageDependencies": [\ + ["follow-redirects", "virtual:d7b9974d1bba76881cc57a280a16dd4914416a6fc4923c2efbb6328057412974da1e719cef1530b7a62b97d85d828f7e1d49b5f6de3b5b0854d49902ec87827c#npm:1.15.5"],\ + ["@types/debug", null],\ + ["debug", null]\ + ],\ + "packagePeers": [\ + "@types/debug",\ + "debug"\ + ],\ + "linkType": "HARD"\ + }],\ ["virtual:ffaff76449f02e83712a7d24e03c564489516739c78ebeffb0fbcdb3893ad9a0e48504f9acfa70fe6f16debe9c8dabde3679d63bf648278ea98a5ff38cf77a9e#npm:1.15.2", {\ "packageLocation": "./.yarn/__virtual__/follow-redirects-virtual-c2d5794c26/0/cache/follow-redirects-npm-1.15.2-1ec1dd82be-8be0d39919.zip/node_modules/follow-redirects/",\ "packageDependencies": [\ @@ -13783,10 +13849,10 @@ const RAW_RUNTIME_STATE = }]\ ]],\ ["mysql2", [\ - ["npm:3.3.3", {\ - "packageLocation": "./.yarn/cache/mysql2-npm-3.3.3-d2fe8cf512-4bf7ace8f1.zip/node_modules/mysql2/",\ + ["npm:3.9.7", {\ + "packageLocation": "./.yarn/cache/mysql2-npm-3.9.7-8fe89e50ac-7f43b17cc0.zip/node_modules/mysql2/",\ "packageDependencies": [\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["denque", "npm:2.1.0"],\ ["generate-function", "npm:2.3.1"],\ ["iconv-lite", "npm:0.6.3"],\ @@ -16836,7 +16902,7 @@ const RAW_RUNTIME_STATE = ["mkdirp", "npm:2.1.6"],\ ["mongodb", null],\ ["mssql", null],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["oracledb", null],\ ["pg", null],\ ["pg-native", null],\ @@ -16928,7 +16994,7 @@ const RAW_RUNTIME_STATE = ["mkdirp", "npm:2.1.6"],\ ["mongodb", null],\ ["mssql", null],\ - ["mysql2", "npm:3.3.3"],\ + ["mysql2", "npm:3.9.7"],\ ["oracledb", null],\ ["pg", null],\ ["pg-native", null],\ diff --git a/.yarn/cache/@types-cookie-parser-npm-1.4.6-27287e1e43-b1bbb17bc4.zip b/.yarn/cache/@types-cookie-parser-npm-1.4.6-27287e1e43-b1bbb17bc4.zip new file mode 100644 index 0000000000000000000000000000000000000000..8d5f3102911ad7343e5c4f0f8bdeeb572697b828 GIT binary patch literal 3392 zcma)<3pms5|Ho&<=9CyY{ghM8Y*~oN6Urf{mW7h@jKWOJY1EuXJP#2`p&F?ab7+My zp;F{n7?z-+xP_xp>o=H-I`zBXfO zAL#GFx0}d%ABgwHy5sQPp#j*Cov2?<{R;SDsxcul=wBn0ei4Dene=4#&_IHn~=Uxb?HIYS5QXWIGDCAMQv zk=Q+nkHpGM{|dN!3*VqEO7knS?EY(VSxydc4I(QzbP1YsQ>{cX{9-u%(EfzU_nWMS zBDXS;UM%-Kd|~K|bCH$1*8=uG{lRX&h_v`vvk(hS zxAQ3cAQCwUo?1C2tS2WBo;qTCb~x-&<|s;Ssbw?$m>ygTm=#ZH+# zSNypJJ?PjtQ5q+`YYN`Ijk+Z__VURFneip|UOw%PPw9`n60??HU@t2d3BmP;ouqDs z$T64vl?;~++*T8Mc8n5}U^cBJ+pWd>(+lM+!V7cqbBWgMrn03Sx(ZbSi=Ee9K5z~p z3OECTuC3!A?$20wo@m)3Izcyn`6RT8RS;RZMd=U0p|qHt>g+S;qDhB|&6EuPdQ3|E ziEEDYwk2Fasgg!wMx)(SD%0;F__0R4Kn=emXSC{;qs;8Sdt-;b-dtFVZDsJTC2rD@bA+f|-8U?fBv;Aewr~1N~V)LCT8K2|Wj`!RDA$ z>`s1|?NVy`6tWi8UzyAiGcbCY^yqw8!z%sNM?VSr$zUa0GTJ;m?sRoeB>!z@0tY8v z1=_|`vPhA@1VREQo5Tn2*mZ$-k9uWen-B(#9=Ack8O*a_Q!ko?Fp#WlDGw`60q|ik z6f*Ct;*dQbUq=)$3AJg)Mq z>Oniomei&0t%aCUvX_Q6l6L|1#bwPw+G7eH7O!u-ONTL2+A;*m-^#-xT5IrstYDHGyv; zE})st7p*pbHtyIpKRiFHs7~7U_VzhngE`aI==^0uXuPggkbAxG&ZspeH%~%N=X7Bq z@vtMAXu@#EC70!;KyZa$-e&tZIf&Tnb)dQCn~~WW5nc6?Y-LV)K7Y2`3LHyn&^LrD z*7kc7mIh~am09dXtrurxDanDoa>?-IDJ`&fOn~8R$M&>2|}|WRUYXT8f@nVNR(!f%B?E8 zIznLrx^?)EEpDhZ!+osC4uwADlY8DR<*qhnO8C@3_D(Gac@Z{;4L23nkYDA$aw@MK zBCS?7eBh_&3D>P6CrV^P$Hs;4M3uZ9{fwD}&0Jntp(4twaWdKc9T{dmW{+KyUefzk zBz3AK}(H_j@5c;g~TI??}trkRpEyZOh0n-fDV zt?&Q<~xU0uTVAHN$<{flzPah zSP%2PnJ5W3(sCA93=tmJ(hFGyd1s|{l_uwkG40!E>5dyF(`wDZfx)Afw`yt)YU9onb zJJNl+Zei)2&Xg3u`-E7drdX72YM(C?b)qP^q^mbiHl+KuCMW+WE;T z2ZxL@YZW$u9pc&Z^ns3}qkSH@@Y8dcqi@2Hf?{iQMyGMw(}*E`;d@5<nuWt? zAfL82%V#Qp4za zcBl`!%UaJ`G`K=Pst8VSJDRz!qIc_CH{!Qc6y%BV_w>ag{6g@7Wc0JZ_;npk!o*rM z$i~29cCSP^6#Js<^+$}PqvT8CQUh*ULB?7BxvB?q$wEF8?YVmA=I&2kYMH#nN19j) zC!%8oE5umBfiM+G%LaGM8Dotd)nv0qb;}`r9VW?@!dGLw(Ksfq>%$)w|7NUzw#omz%!bMM*(h)DuE*y87Vn#F-bix;`?GiXj`dtG zi~pVG|2dhT!9VZO-@!fnzXSfhWB*M4xo*FcrNO^L{{K~svfi|w4FDjperd1&hAawx Geflr3M4s;e literal 0 HcmV?d00001 diff --git a/.yarn/cache/axios-npm-1.6.7-d7b9974d1b-a1932b089e.zip b/.yarn/cache/axios-npm-1.6.7-d7b9974d1b-a1932b089e.zip new file mode 100644 index 0000000000000000000000000000000000000000..7a122000c00054ee0985bdb0243a64658d5b9dd2 GIT binary patch literal 501346 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

tNkwSVGKt;-x{pV!v&D8V}IT4Kt0@hLU_TUfb> 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

    c?BIY<; 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 Y$sz#LOArVG{P}qk1XAz^QZdl~0}gw@rT_o{ literal 0 HcmV?d00001 diff --git a/.yarn/cache/cookie-npm-0.4.1-cc5e2ebb42-0f2defd60a.zip b/.yarn/cache/cookie-npm-0.4.1-cc5e2ebb42-0f2defd60a.zip new file mode 100644 index 0000000000000000000000000000000000000000..2796ed2bc9fc74a9157bef2e2a8adfdecda17aec GIT binary patch literal 7631 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 Ot6#mz-ajN&!2bYuh!52O literal 0 HcmV?d00001 diff --git a/.yarn/cache/cookie-parser-npm-1.4.6-a68f84d02a-1e5a63aa82.zip b/.yarn/cache/cookie-parser-npm-1.4.6-a68f84d02a-1e5a63aa82.zip new file mode 100644 index 0000000000000000000000000000000000000000..6feae6f590cba1bebbbe9d7e5c7957e03141c694 GIT binary patch literal 5473 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 ~q48YVm%;gdGI)Z_$Wx!=uPN14@AuD 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

    gdF;O4W1U>@Dj4sA&`YPE}@F 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 diff --git a/.yarn/cache/mysql2-npm-3.9.7-8fe89e50ac-7f43b17cc0.zip b/.yarn/cache/mysql2-npm-3.9.7-8fe89e50ac-7f43b17cc0.zip new file mode 100644 index 0000000000000000000000000000000000000000..cac716b082da34a6bcf121c882d0178d9c00fdfc GIT binary patch literal 244506 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

    2*+4({6N3nUM;8yPfk#AGjy%~)-77fX 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 KXTl+i(*Fl5%NbJu literal 0 HcmV?d00001 diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 4f0d7b5d8..f449774d4 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -54,7 +54,6 @@ services: ports: - 3306 restart: unless-stopped - command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci volumes: - ./data/mysql:/var/lib/mysql - ./data/import:/docker-entrypoint-initdb.d diff --git a/docker-compose.example.yml b/docker-compose.example.yml index 6bd1e9509..db0ff76f1 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -39,7 +39,6 @@ services: expose: - 3306 restart: unless-stopped - command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci volumes: - ./data/mysql:/var/lib/mysql - ./data/import:/docker-entrypoint-initdb.d diff --git a/package.json b/package.json index ed7b03d04..bdff40b39 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "publish": "lerna publish from-git --yes --no-verify-access --loglevel verbose", "postversion": "./scripts/push-tags-one-by-one.sh", "e2e": "yarn build && PORT=3123 yarn workspace @standardnotes/home-server start", - "start": "yarn workspace @standardnotes/home-server run build && yarn workspace @standardnotes/home-server start" + "start": "yarn build && yarn workspace @standardnotes/home-server start" }, "devDependencies": { "@commitlint/cli": "^17.0.2", @@ -39,7 +39,7 @@ "ts-node": "^10.9.1", "typescript": "^5.0.4" }, - "packageManager": "yarn@4.0.2", + "packageManager": "yarn@4.1.0", "dependenciesMeta": { "grpc-tools@1.12.4": { "unplugged": true diff --git a/packages/analytics/Dockerfile b/packages/analytics/Dockerfile index 71097c352..dce4d4535 100644 --- a/packages/analytics/Dockerfile +++ b/packages/analytics/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/analytics ENTRYPOINT [ "/workspace/packages/analytics/docker/entrypoint.sh" ] diff --git a/packages/analytics/package.json b/packages/analytics/package.json index 48325fca0..e636c4c58 100644 --- a/packages/analytics/package.json +++ b/packages/analytics/package.json @@ -24,7 +24,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "worker": "yarn node dist/bin/worker.js", "report": "yarn node dist/bin/report.js", "setup:env": "cp .env.sample .env", @@ -57,7 +57,7 @@ "inversify": "^6.0.1", "ioredis": "^5.2.4", "mixpanel": "^0.17.0", - "mysql2": "^3.0.1", + "mysql2": "^3.9.7", "reflect-metadata": "^0.2.1", "typeorm": "^0.3.17", "winston": "^3.8.1" diff --git a/packages/api-gateway/CHANGELOG.md b/packages/api-gateway/CHANGELOG.md index aac134742..b281ce74b 100644 --- a/packages/api-gateway/CHANGELOG.md +++ b/packages/api-gateway/CHANGELOG.md @@ -3,24 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -# [1.91.0](https://github.com/standardnotes/server/compare/@standardnotes/api-gateway@1.90.3...@standardnotes/api-gateway@1.91.0) (2024-03-20) - -### Features - -* add CORS_ORIGIN_STRICT_MODE_ENABLED env var to determine if CORS origin should be restricted ([5c02435](https://github.com/standardnotes/server/commit/5c02435ee478b893747d3f9e41062aae12d7ff10)) - -## [1.90.3](https://github.com/standardnotes/server/compare/@standardnotes/api-gateway@1.90.2...@standardnotes/api-gateway@1.90.3) (2024-03-18) - -### Bug Fixes - -* **api-gateway:** response headers cors issue - fixes [#1046](https://github.com/standardnotes/server/issues/1046) ([be668d7](https://github.com/standardnotes/server/commit/be668d7d7a1d9128f625a2bfa807e6a91183b488)) - -## [1.90.2](https://github.com/standardnotes/server/compare/@standardnotes/api-gateway@1.90.1...@standardnotes/api-gateway@1.90.2) (2024-03-18) - -### Bug Fixes - -* cors issues on clients - fixes [#1046](https://github.com/standardnotes/server/issues/1046) ([#1049](https://github.com/standardnotes/server/issues/1049)) ([6d7ca1b](https://github.com/standardnotes/server/commit/6d7ca1b926fd45d744275bd3c1f4c05b010f76c8)) - ## [1.90.1](https://github.com/standardnotes/server/compare/@standardnotes/api-gateway@1.90.0...@standardnotes/api-gateway@1.90.1) (2024-01-19) **Note:** Version bump only for package @standardnotes/api-gateway diff --git a/packages/api-gateway/Dockerfile b/packages/api-gateway/Dockerfile index d410841ab..d6921443f 100644 --- a/packages/api-gateway/Dockerfile +++ b/packages/api-gateway/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/api-gateway ENTRYPOINT [ "/workspace/packages/api-gateway/docker/entrypoint.sh" ] diff --git a/packages/api-gateway/bin/server.ts b/packages/api-gateway/bin/server.ts index 34a067ff4..1dadb375d 100644 --- a/packages/api-gateway/bin/server.ts +++ b/packages/api-gateway/bin/server.ts @@ -27,6 +27,7 @@ import '../src/Controller/v2/RevisionsControllerV2' import helmet from 'helmet' import * as cors from 'cors' +import * as cookieParser from 'cookie-parser' import { text, json, Request, Response, NextFunction } from 'express' import * as winston from 'winston' // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -47,9 +48,24 @@ void container.load().then((container) => { ? `${+env.get('HTTP_REQUEST_PAYLOAD_LIMIT_MEGABYTES', true)}mb` : '50mb' + const logger: winston.Logger = container.get(TYPES.ApiGateway_Logger) + const server = new InversifyExpressServer(container) server.setConfig((app) => { + app.use((request: Request, _response: Response, next: NextFunction) => { + if (request.hostname.includes('standardnotes.org')) { + logger.warn('Request is using deprecated domain', { + origin: request.headers.origin, + method: request.method, + url: request.url, + snjs: request.headers['x-snjs-version'], + application: request.headers['x-application-version'], + }) + } + + next() + }) app.use((_request: Request, response: Response, next: NextFunction) => { response.setHeader('X-API-Gateway-Version', container.get(TYPES.ApiGateway_VERSION)) next() @@ -77,15 +93,15 @@ void container.load().then((container) => { }), ) + app.use(cookieParser()) + app.use(json({ limit: requestPayloadLimit })) app.use( text({ type: ['text/plain', 'application/x-www-form-urlencoded', 'application/x-www-form-urlencoded; charset=utf-8'], }), ) - const corsAllowedOrigins = env.get('CORS_ALLOWED_ORIGINS', true) - ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') - : [] + const corsAllowedOrigins = container.get(TYPES.ApiGateway_CORS_ALLOWED_ORIGINS) app.use( cors({ credentials: true, @@ -136,13 +152,12 @@ void container.load().then((container) => { ) }) - const logger: winston.Logger = container.get(TYPES.ApiGateway_Logger) - server.setErrorConfig((app) => { app.use((error: Record, request: Request, response: Response, _next: NextFunction) => { const locals = response.locals as ResponseLocals logger.error(`${error.stack}`, { + origin: request.headers.origin, codeTag: 'server.ts', method: request.method, url: request.url, diff --git a/packages/api-gateway/package.json b/packages/api-gateway/package.json index 0474329a0..874200996 100644 --- a/packages/api-gateway/package.json +++ b/packages/api-gateway/package.json @@ -1,6 +1,6 @@ { "name": "@standardnotes/api-gateway", - "version": "1.91.0", + "version": "1.90.1", "engines": { "node": ">=18.0.0 <21.0.0" }, @@ -41,6 +41,7 @@ "@standardnotes/time": "workspace:*", "agentkeepalive": "^4.5.0", "axios": "^1.6.1", + "cookie-parser": "^1.4.6", "cors": "2.8.5", "dotenv": "^16.0.1", "express": "^4.18.2", @@ -55,6 +56,7 @@ "winston": "^3.8.1" }, "devDependencies": { + "@types/cookie-parser": "^1", "@types/cors": "^2.8.9", "@types/express": "^4.17.14", "@types/ioredis": "^5.0.0", diff --git a/packages/api-gateway/src/Bootstrap/Container.ts b/packages/api-gateway/src/Bootstrap/Container.ts index d5bffdad0..583980ed1 100644 --- a/packages/api-gateway/src/Bootstrap/Container.ts +++ b/packages/api-gateway/src/Bootstrap/Container.ts @@ -142,6 +142,10 @@ export class ContainerConfigLoader { .bind(TYPES.ApiGateway_CROSS_SERVICE_TOKEN_CACHE_TTL) .toConstantValue(+env.get('CROSS_SERVICE_TOKEN_CACHE_TTL', true)) container.bind(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER).toConstantValue(isConfiguredForHomeServer) + container + .bind(TYPES.ApiGateway_CORS_ALLOWED_ORIGINS) + .toConstantValue(env.get('CORS_ALLOWED_ORIGINS', true) ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') : []) + container.bind(TYPES.ApiGateway_CAPTCHA_UI_URL).toConstantValue(env.get('CAPTCHA_UI_URL', true)) // Middleware container @@ -157,14 +161,14 @@ export class ContainerConfigLoader { // Services container.bind(TYPES.ApiGateway_Timer).toConstantValue(new Timer()) - if (isConfiguredForHomeServer) { + if (isConfiguredForInMemoryCache) { container .bind(TYPES.ApiGateway_CrossServiceTokenCache) .toConstantValue(new InMemoryCrossServiceTokenCache(container.get(TYPES.ApiGateway_Timer))) } else { container .bind(TYPES.ApiGateway_CrossServiceTokenCache) - .to(RedisCrossServiceTokenCache) + .toConstantValue(new RedisCrossServiceTokenCache(container.get(TYPES.ApiGateway_Redis))) } container .bind(TYPES.ApiGateway_EndpointResolver) diff --git a/packages/api-gateway/src/Bootstrap/Types.ts b/packages/api-gateway/src/Bootstrap/Types.ts index 8c355bfbe..72359feb6 100644 --- a/packages/api-gateway/src/Bootstrap/Types.ts +++ b/packages/api-gateway/src/Bootstrap/Types.ts @@ -5,6 +5,7 @@ export const TYPES = { ApiGateway_SNS: Symbol.for('ApiGateway_SNS'), ApiGateway_DomainEventPublisher: Symbol.for('ApiGateway_DomainEventPublisher'), // env vars + ApiGateway_CORS_ALLOWED_ORIGINS: Symbol.for('ApiGateway_CORS_ALLOWED_ORIGINS'), ApiGateway_SNS_TOPIC_ARN: Symbol.for('ApiGateway_SNS_TOPIC_ARN'), ApiGateway_SNS_AWS_REGION: Symbol.for('ApiGateway_SNS_AWS_REGION'), ApiGateway_SYNCING_SERVER_JS_URL: Symbol.for('ApiGateway_SYNCING_SERVER_JS_URL'), @@ -24,6 +25,7 @@ export const TYPES = { ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING: Symbol.for( 'ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING', ), + ApiGateway_CAPTCHA_UI_URL: Symbol.for('ApiGateway_CAPTCHA_UI_URL'), // Middleware ApiGateway_RequiredCrossServiceTokenMiddleware: Symbol.for('ApiGateway_RequiredCrossServiceTokenMiddleware'), ApiGateway_OptionalCrossServiceTokenMiddleware: Symbol.for('ApiGateway_OptionalCrossServiceTokenMiddleware'), diff --git a/packages/api-gateway/src/Controller/AuthMiddleware.ts b/packages/api-gateway/src/Controller/AuthMiddleware.ts index 28f8dc08f..807c137bd 100644 --- a/packages/api-gateway/src/Controller/AuthMiddleware.ts +++ b/packages/api-gateway/src/Controller/AuthMiddleware.ts @@ -42,9 +42,33 @@ export abstract class AuthMiddleware extends BaseMiddleware { } if (crossServiceToken === null) { + const cookiesFromHeaders = new Map() + request.headers.cookie?.split(';').forEach((cookie) => { + const parts = cookie.split('=') + if (parts.length === 2) { + const existingCookies = cookiesFromHeaders.get(parts[0].trim()) + if (existingCookies) { + existingCookies.push(parts[1].trim()) + cookiesFromHeaders.set(parts[0].trim(), existingCookies) + } else { + cookiesFromHeaders.set(parts[0].trim(), [parts[1].trim()]) + } + } + }) const authResponse = await this.serviceProxy.validateSession({ - authorization: authHeaderValue, - sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue, + headers: { + authorization: authHeaderValue.replace('Bearer ', ''), + sharedVaultOwnerContext: sharedVaultOwnerContextHeaderValue, + }, + requestMetadata: { + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, + url: request.url, + method: request.method, + userAgent: request.headers['user-agent'], + secChUa: request.headers['sec-ch-ua'] as string, + }, + cookies: cookiesFromHeaders, }) if (!this.handleSessionValidationResponse(authResponse, response, next)) { diff --git a/packages/api-gateway/src/Controller/GRPCWebSocketAuthMiddleware.ts b/packages/api-gateway/src/Controller/GRPCWebSocketAuthMiddleware.ts index d375fec30..95c6ab7ad 100644 --- a/packages/api-gateway/src/Controller/GRPCWebSocketAuthMiddleware.ts +++ b/packages/api-gateway/src/Controller/GRPCWebSocketAuthMiddleware.ts @@ -100,6 +100,7 @@ export class GRPCWebSocketAuthMiddleware extends BaseMiddleware { roles: decodedToken.roles, isFreeUser: decodedToken.roles.length === 1 && decodedToken.roles[0].name === RoleName.NAMES.CoreUser, readOnlyAccess: decodedToken.session?.readonly_access ?? false, + hasContentLimit: decodedToken.hasContentLimit, } as ResponseLocals) } catch (error) { this.logger.error( diff --git a/packages/api-gateway/src/Controller/LegacyController.ts b/packages/api-gateway/src/Controller/LegacyController.ts index 1e176d0b0..fa348af46 100644 --- a/packages/api-gateway/src/Controller/LegacyController.ts +++ b/packages/api-gateway/src/Controller/LegacyController.ts @@ -20,8 +20,6 @@ export class LegacyController extends BaseHttpController { ['DELETE:/session', 'DELETE:session'], ['DELETE:/session/all', 'DELETE:session/all'], ['POST:/session/refresh', 'POST:session/refresh'], - ['POST:/auth/sign_in', 'POST:auth/sign_in'], - ['GET:/auth/params', 'GET:auth/params'], ]) this.PARAMETRIZED_AUTH_ROUTES = new Map([ diff --git a/packages/api-gateway/src/Controller/ResponseLocals.ts b/packages/api-gateway/src/Controller/ResponseLocals.ts index 903831864..79b400ecd 100644 --- a/packages/api-gateway/src/Controller/ResponseLocals.ts +++ b/packages/api-gateway/src/Controller/ResponseLocals.ts @@ -26,4 +26,5 @@ export interface ResponseLocals { sharedVaultOwnerContext?: { upload_bytes_limit: number } + hasContentLimit: boolean } diff --git a/packages/api-gateway/src/Controller/v1/ActionsController.ts b/packages/api-gateway/src/Controller/v1/ActionsController.ts index 79d97952e..44aaada08 100644 --- a/packages/api-gateway/src/Controller/v1/ActionsController.ts +++ b/packages/api-gateway/src/Controller/v1/ActionsController.ts @@ -4,12 +4,14 @@ import { BaseHttpController, controller, httpGet, httpPost } from 'inversify-exp import { TYPES } from '../../Bootstrap/Types' import { ServiceProxyInterface } from '../../Service/Proxy/ServiceProxyInterface' import { EndpointResolverInterface } from '../../Service/Resolver/EndpointResolverInterface' +import { JsonResult } from 'inversify-express-utils/lib/results' @controller('/v1') export class ActionsController extends BaseHttpController { constructor( @inject(TYPES.ApiGateway_ServiceProxy) private serviceProxy: ServiceProxyInterface, @inject(TYPES.ApiGateway_EndpointResolver) private endpointResolver: EndpointResolverInterface, + @inject(TYPES.ApiGateway_CAPTCHA_UI_URL) private captchaUIUrl: string, ) { super() } @@ -19,7 +21,7 @@ export class ActionsController extends BaseHttpController { await this.serviceProxy.callAuthServer( request, response, - this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/sign_in'), + this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_sign_in'), request.body, ) } @@ -29,7 +31,7 @@ export class ActionsController extends BaseHttpController { await this.serviceProxy.callAuthServer( request, response, - this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'auth/params'), + this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_params'), request.body, ) } @@ -83,4 +85,11 @@ export class ActionsController extends BaseHttpController { request.body, ) } + + @httpGet('/meta') + async serverMetadata(): Promise { + return this.json({ + captchaUIUrl: this.captchaUIUrl, + }) + } } diff --git a/packages/api-gateway/src/Controller/v1/UsersController.ts b/packages/api-gateway/src/Controller/v1/UsersController.ts index 0629cadfa..c85d6c550 100644 --- a/packages/api-gateway/src/Controller/v1/UsersController.ts +++ b/packages/api-gateway/src/Controller/v1/UsersController.ts @@ -6,7 +6,6 @@ import { controller, httpDelete, httpGet, - httpPatch, httpPost, httpPut, results, @@ -39,16 +38,6 @@ export class UsersController extends BaseHttpController { await this.httpService.callPaymentsServer(request, response, 'api/pro_users/send-activation-code', request.body) } - @httpPatch('/:userId', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware) - async updateUser(request: Request, response: Response): Promise { - await this.httpService.callAuthServer( - request, - response, - this.endpointResolver.resolveEndpointOrMethodIdentifier('PATCH', 'users/:userId', request.params.userId), - request.body, - ) - } - @httpPut('/:userUuid/password', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware) async changePassword(request: Request, response: Response): Promise { this.logger.debug( @@ -86,7 +75,7 @@ export class UsersController extends BaseHttpController { await this.httpService.callAuthServer( request, response, - this.endpointResolver.resolveEndpointOrMethodIdentifier('GET', 'auth/params'), + this.endpointResolver.resolveEndpointOrMethodIdentifier('POST', 'auth/pkce_params'), ) } @@ -142,6 +131,20 @@ export class UsersController extends BaseHttpController { ) } + @httpPut('/:userUuid/subscription-settings', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware) + async putSubscriptionSetting(request: Request, response: Response): Promise { + await this.httpService.callAuthServer( + request, + response, + this.endpointResolver.resolveEndpointOrMethodIdentifier( + 'PUT', + 'users/:userUuid/subscription-settings', + request.params.userUuid, + ), + request.body, + ) + } + @httpGet('/:userUuid/settings/:settingName', TYPES.ApiGateway_RequiredCrossServiceTokenMiddleware) async getSetting(request: Request, response: Response): Promise { await this.httpService.callAuthServer( diff --git a/packages/api-gateway/src/Infra/Redis/RedisCrossServiceTokenCache.ts b/packages/api-gateway/src/Infra/Redis/RedisCrossServiceTokenCache.ts index ab5502350..afda3a725 100644 --- a/packages/api-gateway/src/Infra/Redis/RedisCrossServiceTokenCache.ts +++ b/packages/api-gateway/src/Infra/Redis/RedisCrossServiceTokenCache.ts @@ -1,15 +1,12 @@ -import { inject, injectable } from 'inversify' import * as IORedis from 'ioredis' -import { TYPES } from '../../Bootstrap/Types' import { CrossServiceTokenCacheInterface } from '../../Service/Cache/CrossServiceTokenCacheInterface' -@injectable() export class RedisCrossServiceTokenCache implements CrossServiceTokenCacheInterface { private readonly PREFIX = 'cst' private readonly USER_CST_PREFIX = 'user-cst' - constructor(@inject(TYPES.ApiGateway_Redis) private redisClient: IORedis.Redis) {} + constructor(private redisClient: IORedis.Redis) {} async set(dto: { key: string diff --git a/packages/api-gateway/src/Service/DirectCall/DirectCallServiceProxy.ts b/packages/api-gateway/src/Service/DirectCall/DirectCallServiceProxy.ts index 3d5565821..b634816bf 100644 --- a/packages/api-gateway/src/Service/DirectCall/DirectCallServiceProxy.ts +++ b/packages/api-gateway/src/Service/DirectCall/DirectCallServiceProxy.ts @@ -10,23 +10,44 @@ export class DirectCallServiceProxy implements ServiceProxyInterface { private filesServerUrl: string, ) {} - async validateSession( + async validateSession(dto: { headers: { authorization: string sharedVaultOwnerContext?: string - }, - _retryAttempt?: number, - ): Promise<{ status: number; data: unknown; headers: { contentType: string } }> { + } + cookies?: Map + snjs?: string + application?: string + retryAttempt?: number + }): Promise<{ + status: number + data: unknown + headers: { + contentType: string + } + }> { const authService = this.serviceContainer.get(ServiceIdentifier.create(ServiceIdentifier.NAMES.Auth).getValue()) if (!authService) { throw new Error('Auth service not found') } + let stringOfCookies = '' + for (const cookieName of dto.cookies?.keys() ?? []) { + for (const cookieValue of dto.cookies?.get(cookieName) as string[]) { + stringOfCookies += `${cookieName}=${cookieValue}; ` + } + } + const serviceResponse = (await authService.handleRequest( { + body: { + authTokenFromHeaders: dto.headers.authorization, + sharedVaultOwnerContext: dto.headers.sharedVaultOwnerContext, + }, headers: { - authorization: headers.authorization, - 'x-shared-vault-owner-context': headers.sharedVaultOwnerContext, + 'x-snjs-version': dto.snjs, + 'x-application-version': dto.application, + cookie: stringOfCookies.trim(), }, } as never, {} as never, diff --git a/packages/api-gateway/src/Service/Http/HttpServiceProxy.ts b/packages/api-gateway/src/Service/Http/HttpServiceProxy.ts index 2d9f70a90..75bc1decc 100644 --- a/packages/api-gateway/src/Service/Http/HttpServiceProxy.ts +++ b/packages/api-gateway/src/Service/Http/HttpServiceProxy.ts @@ -28,20 +28,51 @@ export class HttpServiceProxy implements ServiceProxyInterface { @inject(TYPES.ApiGateway_Timer) private timer: TimerInterface, ) {} - async validateSession( + async validateSession(dto: { headers: { authorization: string sharedVaultOwnerContext?: string - }, - retryAttempt?: number, - ): Promise<{ status: number; data: unknown; headers: { contentType: string } }> { + } + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } + cookies?: Map + retryAttempt?: number + }): Promise<{ + status: number + data: unknown + headers: { + contentType: string + } + }> { try { + let stringOfCookies = '' + for (const cookieName of dto.cookies?.keys() ?? []) { + for (const cookieValue of dto.cookies?.get(cookieName) as string[]) { + stringOfCookies += `${cookieName}=${cookieValue}; ` + } + } + const authResponse = await this.httpClient.request({ method: 'POST', headers: { - Authorization: headers.authorization, Accept: 'application/json', - 'x-shared-vault-owner-context': headers.sharedVaultOwnerContext, + Cookie: stringOfCookies.trim(), + 'x-snjs-version': dto.requestMetadata.snjs, + 'x-application-version': dto.requestMetadata.application, + 'x-origin-user-agent': dto.requestMetadata.userAgent, + 'x-origin-sec-ch-ua': dto.requestMetadata.secChUa, + 'x-origin-url': dto.requestMetadata.url, + 'x-origin-method': dto.requestMetadata.method, + }, + data: { + authTokenFromHeaders: dto.headers.authorization, + sharedVaultOwnerContext: dto.headers.sharedVaultOwnerContext, }, validateStatus: (status: number) => { return status >= 200 && status < 500 @@ -58,13 +89,18 @@ export class HttpServiceProxy implements ServiceProxyInterface { } } catch (error) { const requestDidNotMakeIt = this.requestTimedOutOrDidNotReachDestination(error as Record) - const tooManyRetryAttempts = retryAttempt && retryAttempt > 2 + const tooManyRetryAttempts = dto.retryAttempt && dto.retryAttempt > 2 if (!tooManyRetryAttempts && requestDidNotMakeIt) { await this.timer.sleep(50) - const nextRetryAttempt = retryAttempt ? retryAttempt + 1 : 1 + const nextRetryAttempt = dto.retryAttempt ? dto.retryAttempt + 1 : 1 - return this.validateSession(headers, nextRetryAttempt) + return this.validateSession({ + headers: dto.headers, + cookies: dto.cookies, + requestMetadata: dto.requestMetadata, + retryAttempt: nextRetryAttempt, + }) } throw error @@ -186,9 +222,18 @@ export class HttpServiceProxy implements ServiceProxyInterface { headers[headerName] = request.headers[headerName] as string } + headers['x-origin-url'] = request.url + headers['x-origin-method'] = request.method + headers['x-snjs-version'] = request.headers['x-snjs-version'] as string + headers['x-application-version'] = request.headers['x-application-version'] as string + headers['x-origin-user-agent'] = request.headers['user-agent'] as string + headers['x-origin-sec-ch-ua'] = request.headers['sec-ch-ua'] as string + delete headers.host delete headers['content-length'] + headers.cookie = request.headers.cookie as string + if ('authToken' in locals && locals.authToken) { headers['X-Auth-Token'] = locals.authToken } diff --git a/packages/api-gateway/src/Service/Proxy/ServiceProxyInterface.ts b/packages/api-gateway/src/Service/Proxy/ServiceProxyInterface.ts index 80b2ebb98..b87e144ec 100644 --- a/packages/api-gateway/src/Service/Proxy/ServiceProxyInterface.ts +++ b/packages/api-gateway/src/Service/Proxy/ServiceProxyInterface.ts @@ -49,13 +49,22 @@ export interface ServiceProxyInterface { endpointOrMethodIdentifier: string, payload?: Record | string, ): Promise - validateSession( + validateSession(dto: { headers: { authorization: string sharedVaultOwnerContext?: string - }, - retryAttempt?: number, - ): Promise<{ + } + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } + cookies?: Map + retryAttempt?: number + }): Promise<{ status: number data: unknown headers: { diff --git a/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts b/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts index 3fcb6c1c6..f3abb5f72 100644 --- a/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts +++ b/packages/api-gateway/src/Service/Resolver/EndpointResolver.ts @@ -7,8 +7,6 @@ export class EndpointResolver implements EndpointResolverInterface { // Auth Middleware ['[POST]:sessions/validate', 'auth.sessions.validate'], // Actions Controller - ['[POST]:auth/sign_in', 'auth.signIn'], - ['[GET]:auth/params', 'auth.params'], ['[POST]:auth/sign_out', 'auth.signOut'], ['[POST]:auth/recovery/codes', 'auth.generateRecoveryCodes'], ['[POST]:auth/recovery/login', 'auth.signInWithRecoveryCodes'], @@ -48,6 +46,7 @@ export class EndpointResolver implements EndpointResolverInterface { ['[PUT]:users/:userUuid/settings', 'auth.users.updateSetting'], ['[GET]:users/:userUuid/settings/:settingName', 'auth.users.getSetting'], ['[DELETE]:users/:userUuid/settings/:settingName', 'auth.users.deleteSetting'], + ['[PUT]:users/:userUuid/subscription-settings', 'auth.users.updateSubscriptionSetting'], ['[GET]:users/:userUuid/subscription-settings/:subscriptionSettingName', 'auth.users.getSubscriptionSetting'], ['[GET]:users/:userUuid/features', 'auth.users.getFeatures'], ['[GET]:users/:userUuid/subscription', 'auth.users.getSubscription'], diff --git a/packages/api-gateway/src/Service/gRPC/GRPCServiceProxy.ts b/packages/api-gateway/src/Service/gRPC/GRPCServiceProxy.ts index bd9832cdc..5fad1cf07 100644 --- a/packages/api-gateway/src/Service/gRPC/GRPCServiceProxy.ts +++ b/packages/api-gateway/src/Service/gRPC/GRPCServiceProxy.ts @@ -2,7 +2,7 @@ import { AxiosInstance, AxiosError, AxiosResponse, Method } from 'axios' import { Request, Response } from 'express' import { Logger } from 'winston' import { TimerInterface } from '@standardnotes/time' -import { IAuthClient, AuthorizationHeader, SessionValidationResponse } from '@standardnotes/grpc' +import { Cookie, IAuthClient, RequestValidationOptions, SessionValidationResponse } from '@standardnotes/grpc' import * as grpc from '@grpc/grpc-js' import { CrossServiceTokenCacheInterface } from '../Cache/CrossServiceTokenCacheInterface' @@ -30,23 +30,56 @@ export class GRPCServiceProxy implements ServiceProxyInterface { private gRPCSyncingServerServiceProxy: GRPCSyncingServerServiceProxy, ) {} - async validateSession( + async validateSession(dto: { headers: { authorization: string sharedVaultOwnerContext?: string - }, - retryAttempt?: number, - ): Promise<{ status: number; data: unknown; headers: { contentType: string } }> { + } + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } + cookies?: Map + retryAttempt?: number + }): Promise<{ + status: number + data: unknown + headers: { + contentType: string + } + }> { const promise = new Promise((resolve, reject) => { try { - const request = new AuthorizationHeader() - request.setBearerToken(headers.authorization) + const request = new RequestValidationOptions() + request.setBearerToken(dto.headers.authorization) - const metadata = new grpc.Metadata() - metadata.set('x-shared-vault-owner-context', headers.sharedVaultOwnerContext ?? '') + for (const cookieName of dto.cookies?.keys() ?? []) { + for (const cookieValue of dto.cookies?.get(cookieName) as string[]) { + const cookie = new Cookie() + cookie.setName(cookieName) + cookie.setValue(cookieValue) + + request.addCookie(cookie) + } + } + if (dto.headers.sharedVaultOwnerContext) { + request.setSharedVaultOwnerContext(dto.headers.sharedVaultOwnerContext) + } this.logger.debug('[GRPCServiceProxy] Validating session via gRPC') + const metadata = new grpc.Metadata() + metadata.set('x-snjs-version', dto.requestMetadata.snjs as string) + metadata.set('x-application-version', dto.requestMetadata.application as string) + metadata.set('x-origin-user-agent', dto.requestMetadata.userAgent as string) + metadata.set('x-origin-sec-ch-ua', dto.requestMetadata.secChUa as string) + metadata.set('x-origin-url', dto.requestMetadata.url) + metadata.set('x-origin-method', dto.requestMetadata.method) + this.authClient.validate( request, metadata, @@ -90,8 +123,8 @@ export class GRPCServiceProxy implements ServiceProxyInterface { try { const result = await promise - if (retryAttempt) { - this.logger.debug(`Request to Auth Server succeeded after ${retryAttempt} retries`) + if (dto.retryAttempt) { + this.logger.info(`Request to Auth Server succeeded after ${dto.retryAttempt} retries`) } return result as { status: number; data: unknown; headers: { contentType: string } } @@ -99,15 +132,20 @@ export class GRPCServiceProxy implements ServiceProxyInterface { const requestDidNotMakeIt = 'code' in (error as Record) && (error as Record).code === Status.UNAVAILABLE - const tooManyRetryAttempts = retryAttempt && retryAttempt > 2 + const tooManyRetryAttempts = dto.retryAttempt && dto.retryAttempt > 2 if (!tooManyRetryAttempts && requestDidNotMakeIt) { await this.timer.sleep(50) - const nextRetryAttempt = retryAttempt ? retryAttempt + 1 : 1 + const nextRetryAttempt = dto.retryAttempt ? dto.retryAttempt + 1 : 1 - this.logger.debug(`Retrying request to Auth Server for the ${nextRetryAttempt} time`) + this.logger.warn(`Retrying request to Auth Server for the ${nextRetryAttempt} time`) - return this.validateSession(headers, nextRetryAttempt) + return this.validateSession({ + headers: dto.headers, + cookies: dto.cookies, + requestMetadata: dto.requestMetadata, + retryAttempt: nextRetryAttempt, + }) } throw error @@ -265,6 +303,8 @@ export class GRPCServiceProxy implements ServiceProxyInterface { delete headers.host delete headers['content-length'] + headers.cookie = request.headers.cookie as string + if ('authToken' in locals && locals.authToken) { headers['X-Auth-Token'] = locals.authToken } diff --git a/packages/api-gateway/src/Service/gRPC/GRPCSyncingServerServiceProxy.ts b/packages/api-gateway/src/Service/gRPC/GRPCSyncingServerServiceProxy.ts index 6648f61d2..c6b9fb108 100644 --- a/packages/api-gateway/src/Service/gRPC/GRPCSyncingServerServiceProxy.ts +++ b/packages/api-gateway/src/Service/gRPC/GRPCSyncingServerServiceProxy.ts @@ -45,6 +45,7 @@ export class GRPCSyncingServerServiceProxy { metadata.set('x-session-uuid', locals.session.uuid) } metadata.set('x-is-free-user', locals.isFreeUser ? 'true' : 'false') + metadata.set('x-has-content-limit', locals.hasContentLimit ? 'true' : 'false') this.syncingClient.syncItems(syncRequest, metadata, (error, syncResponse) => { if (error) { diff --git a/packages/auth/.env.sample b/packages/auth/.env.sample index 304a28eb2..4e4aa9f78 100644 --- a/packages/auth/.env.sample +++ b/packages/auth/.env.sample @@ -29,6 +29,11 @@ CACHE_TYPE=redis DISABLE_USER_REGISTRATION=false +COOKIE_DOMAIN= +COOKIE_SAME_SITE= +COOKIE_SECURE= +COOKIE_PARTITIONED= + ACCESS_TOKEN_AGE=5184000 REFRESH_TOKEN_AGE=31556926 @@ -49,6 +54,10 @@ VALET_TOKEN_TTL= WEB_SOCKET_CONNECTION_TOKEN_SECRET= +# Human verfication +CAPTCHA_SERVER_URL= +CAPTCHA_UI_URL= + # (Optional) U2F Setup U2F_RELYING_PARTY_ID= U2F_RELYING_PARTY_NAME= diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index 5106fedef..fe0e2ec25 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -3,24 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -## [1.178.3](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.178.2...@standardnotes/auth-server@1.178.3) (2024-03-18) - -### Bug Fixes - -* **auth:** allow registration on new api versions - fixes [#1046](https://github.com/standardnotes/server/issues/1046) ([#1048](https://github.com/standardnotes/server/issues/1048)) ([f939caf](https://github.com/standardnotes/server/commit/f939caf2d9a781d42989ad6e92a5c7150ff48e19)) - -## [1.178.2](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.178.1...@standardnotes/auth-server@1.178.2) (2024-03-15) - -### Bug Fixes - -* allow handling of new api version ([9d49764](https://github.com/standardnotes/server/commit/9d49764b841e73655e19523eddf10498addc9fb4)) - -## [1.178.1](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.178.0...@standardnotes/auth-server@1.178.1) (2024-02-09) - -### Bug Fixes - -* allow expired offline subscriptions to receive dashboard emails ([#1041](https://github.com/standardnotes/server/issues/1041)) ([4fe8e9a](https://github.com/standardnotes/server/commit/4fe8e9a79f652f3e39608d6683cb17cc08bb8717)) - # [1.178.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.177.20...@standardnotes/auth-server@1.178.0) (2024-01-19) ### Features diff --git a/packages/auth/Dockerfile b/packages/auth/Dockerfile index dbbe0b4b0..b10a1324b 100644 --- a/packages/auth/Dockerfile +++ b/packages/auth/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/auth ENTRYPOINT [ "/workspace/packages/auth/docker/entrypoint.sh" ] diff --git a/packages/auth/bin/server.ts b/packages/auth/bin/server.ts index 85f380f0f..6ba1416cc 100644 --- a/packages/auth/bin/server.ts +++ b/packages/auth/bin/server.ts @@ -20,6 +20,7 @@ import '../src/Infra/InversifyExpressUtils/AnnotatedHealthCheckController' import '../src/Infra/InversifyExpressUtils/AnnotatedFeaturesController' import * as cors from 'cors' +import * as cookieParser from 'cookie-parser' import * as grpc from '@grpc/grpc-js' import { urlencoded, json, Request, Response, NextFunction } from 'express' import * as winston from 'winston' @@ -53,6 +54,7 @@ void container.load().then((container) => { }) app.use(json()) app.use(urlencoded({ extended: true })) + app.use(cookieParser()) app.use(cors()) }) diff --git a/packages/auth/bin/user_email_backup.ts b/packages/auth/bin/user_email_backup.ts index 16c36421b..3de647018 100644 --- a/packages/auth/bin/user_email_backup.ts +++ b/packages/auth/bin/user_email_backup.ts @@ -9,28 +9,23 @@ import TYPES from '../src/Bootstrap/Types' import { Env } from '../src/Bootstrap/Env' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventFactoryInterface } from '../src/Domain/Event/DomainEventFactoryInterface' -import { SettingRepositoryInterface } from '../src/Domain/Setting/SettingRepositoryInterface' -import { MuteFailedBackupsEmailsOption } from '@standardnotes/settings' import { RoleServiceInterface } from '../src/Domain/Role/RoleServiceInterface' import { PermissionName } from '@standardnotes/features' import { UserRepositoryInterface } from '../src/Domain/User/UserRepositoryInterface' import { GetUserKeyParams } from '../src/Domain/UseCase/GetUserKeyParams/GetUserKeyParams' -import { Email, SettingName } from '@standardnotes/domain-core' +import { Email } from '@standardnotes/domain-core' const inputArgs = process.argv.slice(2) const backupEmail = inputArgs[0] const requestBackups = async ( userRepository: UserRepositoryInterface, - settingRepository: SettingRepositoryInterface, roleService: RoleServiceInterface, domainEventFactory: DomainEventFactoryInterface, domainEventPublisher: DomainEventPublisherInterface, getUserKeyParamsUseCase: GetUserKeyParams, ): Promise => { const permissionName = PermissionName.DailyEmailBackup - const muteEmailsSettingName = SettingName.NAMES.MuteFailedBackupsEmails - const muteEmailsSettingValue = MuteFailedBackupsEmailsOption.Muted const emailOrError = Email.create(backupEmail) if (emailOrError.isFailed()) { @@ -48,24 +43,13 @@ const requestBackups = async ( throw new Error(`User ${backupEmail} is not permitted for email backups`) } - let userHasEmailsMuted = false - const emailsMutedSetting = await settingRepository.findOneByNameAndUserUuid(muteEmailsSettingName, user.uuid) - if (emailsMutedSetting !== null && emailsMutedSetting.props.value !== null) { - userHasEmailsMuted = emailsMutedSetting.props.value === muteEmailsSettingValue - } - const keyParamsResponse = await getUserKeyParamsUseCase.execute({ userUuid: user.uuid, authenticated: false, }) await domainEventPublisher.publish( - domainEventFactory.createEmailBackupRequestedEvent( - user.uuid, - emailsMutedSetting?.id.toString() as string, - userHasEmailsMuted, - keyParamsResponse.keyParams, - ), + domainEventFactory.createEmailBackupRequestedEvent(user.uuid, keyParamsResponse.keyParams), ) return @@ -82,7 +66,6 @@ void container.load().then((container) => { logger.info(`Starting email backup requesting for ${backupEmail} ...`) - const settingRepository: SettingRepositoryInterface = container.get(TYPES.Auth_SettingRepository) const userRepository: UserRepositoryInterface = container.get(TYPES.Auth_UserRepository) const roleService: RoleServiceInterface = container.get(TYPES.Auth_RoleService) const domainEventFactory: DomainEventFactoryInterface = container.get(TYPES.Auth_DomainEventFactory) @@ -90,14 +73,7 @@ void container.load().then((container) => { const getUserKeyParamsUseCase: GetUserKeyParams = container.get(TYPES.Auth_GetUserKeyParams) Promise.resolve( - requestBackups( - userRepository, - settingRepository, - roleService, - domainEventFactory, - domainEventPublisher, - getUserKeyParamsUseCase, - ), + requestBackups(userRepository, roleService, domainEventFactory, domainEventPublisher, getUserKeyParamsUseCase), ) .then(() => { logger.info(`Email backup requesting complete for ${backupEmail}`) diff --git a/packages/auth/migrations/mysql/1707759514236-user-roles-content-limit.ts b/packages/auth/migrations/mysql/1707759514236-user-roles-content-limit.ts new file mode 100644 index 000000000..377ee1e39 --- /dev/null +++ b/packages/auth/migrations/mysql/1707759514236-user-roles-content-limit.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class UserRolesContentLimit1707759514236 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + 'INSERT INTO `permissions` (uuid, name) VALUES ("f8b4ced2-6a59-49f8-9ade-416a5f5ffc61", "server:content-limit")', + ) + await queryRunner.query( + 'INSERT INTO `roles` (uuid, name, version) VALUES ("ab2e15c9-9252-43f3-829c-6f0af3315791", "CORE_USER", 4)', + ) + await queryRunner.query( + 'INSERT INTO `role_permissions` (permission_uuid, role_uuid) VALUES \ + ("b04a7670-934e-4ab1-b8a3-0f27ff159511", "ab2e15c9-9252-43f3-829c-6f0af3315791"), \ + ("eb0575a2-6e26-49e3-9501-f2e75d7dbda3", "ab2e15c9-9252-43f3-829c-6f0af3315791"), \ + ("f8b4ced2-6a59-49f8-9ade-416a5f5ffc61", "ab2e15c9-9252-43f3-829c-6f0af3315791") \ + ', + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DELETE FROM `role_permissions` WHERE role_uuid="ab2e15c9-9252-43f3-829c-6f0af3315791"') + await queryRunner.query('DELETE FROM `permissions` WHERE uuid="f8b4ced2-6a59-49f8-9ade-416a5f5ffc61"') + await queryRunner.query('DELETE FROM `roles` WHERE uuid="ab2e15c9-9252-43f3-829c-6f0af3315791"') + } +} diff --git a/packages/auth/migrations/mysql/1707813542369-add-session-version.ts b/packages/auth/migrations/mysql/1707813542369-add-session-version.ts new file mode 100644 index 000000000..9ae56a332 --- /dev/null +++ b/packages/auth/migrations/mysql/1707813542369-add-session-version.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddSessionVersion1707813542369 implements MigrationInterface { + name = 'AddSessionVersion1707813542369' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` ADD `version` smallint NULL DEFAULT 1') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `version`') + } +} diff --git a/packages/auth/migrations/mysql/1709133001993-add-session-private-identifier.ts b/packages/auth/migrations/mysql/1709133001993-add-session-private-identifier.ts new file mode 100644 index 000000000..1abf0c4d4 --- /dev/null +++ b/packages/auth/migrations/mysql/1709133001993-add-session-private-identifier.ts @@ -0,0 +1,17 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddSessionPrivateIdentifier1709133001993 implements MigrationInterface { + name = 'AddSessionPrivateIdentifier1709133001993' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `sessions` ADD `private_identifier` varchar(36) NULL COMMENT 'Used to identify a session without exposing the UUID in client-side cookies.'", + ) + await queryRunner.query('CREATE INDEX `index_sessions_on_private_identifier` ON `sessions` (`private_identifier`)') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX `index_sessions_on_private_identifier` ON `sessions`') + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `private_identifier`') + } +} diff --git a/packages/auth/migrations/mysql/1709206805226-add-revoked-session-private-identifier.ts b/packages/auth/migrations/mysql/1709206805226-add-revoked-session-private-identifier.ts new file mode 100644 index 000000000..4b634cdb8 --- /dev/null +++ b/packages/auth/migrations/mysql/1709206805226-add-revoked-session-private-identifier.ts @@ -0,0 +1,19 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddRevokedSessionPrivateIdentifier1709206805226 implements MigrationInterface { + name = 'AddRevokedSessionPrivateIdentifier1709206805226' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + "ALTER TABLE `revoked_sessions` ADD `private_identifier` varchar(36) NULL COMMENT 'Used to identify a session without exposing the UUID in client-side cookies.'", + ) + await queryRunner.query( + 'CREATE INDEX `index_revoked_sessions_on_private_identifier` ON `revoked_sessions` (`private_identifier`)', + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX `index_revoked_sessions_on_private_identifier` ON `revoked_sessions`') + await queryRunner.query('ALTER TABLE `revoked_sessions` DROP COLUMN `private_identifier`') + } +} diff --git a/packages/auth/migrations/mysql/1710236132439-add-application-and-snjs-to-sessions.ts b/packages/auth/migrations/mysql/1710236132439-add-application-and-snjs-to-sessions.ts new file mode 100644 index 000000000..fc80e0d43 --- /dev/null +++ b/packages/auth/migrations/mysql/1710236132439-add-application-and-snjs-to-sessions.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddApplicationAndSnjsToSessions1710236132439 implements MigrationInterface { + name = 'AddApplicationAndSnjsToSessions1710236132439' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` ADD `application` varchar(255) NULL') + await queryRunner.query('ALTER TABLE `sessions` ADD `snjs` varchar(255) NULL') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `snjs`') + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `application`') + } +} diff --git a/packages/auth/migrations/sqlite/1707759514236-user-roles-content-limit-sqlite.ts b/packages/auth/migrations/sqlite/1707759514236-user-roles-content-limit-sqlite.ts new file mode 100644 index 000000000..377ee1e39 --- /dev/null +++ b/packages/auth/migrations/sqlite/1707759514236-user-roles-content-limit-sqlite.ts @@ -0,0 +1,25 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class UserRolesContentLimit1707759514236 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + 'INSERT INTO `permissions` (uuid, name) VALUES ("f8b4ced2-6a59-49f8-9ade-416a5f5ffc61", "server:content-limit")', + ) + await queryRunner.query( + 'INSERT INTO `roles` (uuid, name, version) VALUES ("ab2e15c9-9252-43f3-829c-6f0af3315791", "CORE_USER", 4)', + ) + await queryRunner.query( + 'INSERT INTO `role_permissions` (permission_uuid, role_uuid) VALUES \ + ("b04a7670-934e-4ab1-b8a3-0f27ff159511", "ab2e15c9-9252-43f3-829c-6f0af3315791"), \ + ("eb0575a2-6e26-49e3-9501-f2e75d7dbda3", "ab2e15c9-9252-43f3-829c-6f0af3315791"), \ + ("f8b4ced2-6a59-49f8-9ade-416a5f5ffc61", "ab2e15c9-9252-43f3-829c-6f0af3315791") \ + ', + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DELETE FROM `role_permissions` WHERE role_uuid="ab2e15c9-9252-43f3-829c-6f0af3315791"') + await queryRunner.query('DELETE FROM `permissions` WHERE uuid="f8b4ced2-6a59-49f8-9ade-416a5f5ffc61"') + await queryRunner.query('DELETE FROM `roles` WHERE uuid="ab2e15c9-9252-43f3-829c-6f0af3315791"') + } +} diff --git a/packages/auth/migrations/sqlite/1707813542369-add-session-version.ts b/packages/auth/migrations/sqlite/1707813542369-add-session-version.ts new file mode 100644 index 000000000..9ae56a332 --- /dev/null +++ b/packages/auth/migrations/sqlite/1707813542369-add-session-version.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddSessionVersion1707813542369 implements MigrationInterface { + name = 'AddSessionVersion1707813542369' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` ADD `version` smallint NULL DEFAULT 1') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `version`') + } +} diff --git a/packages/auth/migrations/sqlite/1709133169237-add-session-private-identifier.ts b/packages/auth/migrations/sqlite/1709133169237-add-session-private-identifier.ts new file mode 100644 index 000000000..703c82a39 --- /dev/null +++ b/packages/auth/migrations/sqlite/1709133169237-add-session-private-identifier.ts @@ -0,0 +1,37 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddSessionPrivateIdentifier1709133169237 implements MigrationInterface { + name = 'AddSessionPrivateIdentifier1709133169237' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX "index_sessions_on_updated_at"') + await queryRunner.query('DROP INDEX "index_sessions_on_user_uuid"') + await queryRunner.query( + 'CREATE TABLE "temporary_sessions" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(255), "hashed_access_token" varchar(255) NOT NULL, "hashed_refresh_token" varchar(255) NOT NULL, "access_expiration" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "refresh_expiration" datetime NOT NULL, "api_version" varchar(255), "user_agent" text, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "readonly_access" tinyint NOT NULL DEFAULT (0), "version" smallint DEFAULT (1), "private_identifier" varchar(36))', + ) + await queryRunner.query( + 'INSERT INTO "temporary_sessions"("uuid", "user_uuid", "hashed_access_token", "hashed_refresh_token", "access_expiration", "refresh_expiration", "api_version", "user_agent", "created_at", "updated_at", "readonly_access", "version") SELECT "uuid", "user_uuid", "hashed_access_token", "hashed_refresh_token", "access_expiration", "refresh_expiration", "api_version", "user_agent", "created_at", "updated_at", "readonly_access", "version" FROM "sessions"', + ) + await queryRunner.query('DROP TABLE "sessions"') + await queryRunner.query('ALTER TABLE "temporary_sessions" RENAME TO "sessions"') + await queryRunner.query('CREATE INDEX "index_sessions_on_updated_at" ON "sessions" ("updated_at") ') + await queryRunner.query('CREATE INDEX "index_sessions_on_user_uuid" ON "sessions" ("user_uuid") ') + await queryRunner.query('CREATE INDEX "index_sessions_on_private_identifier" ON "sessions" ("private_identifier") ') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX "index_sessions_on_private_identifier"') + await queryRunner.query('DROP INDEX "index_sessions_on_user_uuid"') + await queryRunner.query('DROP INDEX "index_sessions_on_updated_at"') + await queryRunner.query('ALTER TABLE "sessions" RENAME TO "temporary_sessions"') + await queryRunner.query( + 'CREATE TABLE "sessions" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(255), "hashed_access_token" varchar(255) NOT NULL, "hashed_refresh_token" varchar(255) NOT NULL, "access_expiration" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), "refresh_expiration" datetime NOT NULL, "api_version" varchar(255), "user_agent" text, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "readonly_access" tinyint NOT NULL DEFAULT (0), "version" smallint DEFAULT (1))', + ) + await queryRunner.query( + 'INSERT INTO "sessions"("uuid", "user_uuid", "hashed_access_token", "hashed_refresh_token", "access_expiration", "refresh_expiration", "api_version", "user_agent", "created_at", "updated_at", "readonly_access", "version") SELECT "uuid", "user_uuid", "hashed_access_token", "hashed_refresh_token", "access_expiration", "refresh_expiration", "api_version", "user_agent", "created_at", "updated_at", "readonly_access", "version" FROM "temporary_sessions"', + ) + await queryRunner.query('DROP TABLE "temporary_sessions"') + await queryRunner.query('CREATE INDEX "index_sessions_on_user_uuid" ON "sessions" ("user_uuid") ') + await queryRunner.query('CREATE INDEX "index_sessions_on_updated_at" ON "sessions" ("updated_at") ') + } +} diff --git a/packages/auth/migrations/sqlite/1709208455658-add-revoked-session-private-identifier.ts b/packages/auth/migrations/sqlite/1709208455658-add-revoked-session-private-identifier.ts new file mode 100644 index 000000000..2ae026630 --- /dev/null +++ b/packages/auth/migrations/sqlite/1709208455658-add-revoked-session-private-identifier.ts @@ -0,0 +1,34 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddRevokedSessionPrivateIdentifier1709208455658 implements MigrationInterface { + name = 'AddRevokedSessionPrivateIdentifier1709208455658' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX "index_revoked_sessions_on_user_uuid"') + await queryRunner.query( + 'CREATE TABLE "temporary_revoked_sessions" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "received" tinyint NOT NULL DEFAULT (0), "created_at" datetime NOT NULL, "received_at" datetime, "user_agent" text, "api_version" varchar(255), "private_identifier" varchar(36), CONSTRAINT "FK_edaf18faca67e682be39b5ecae5" FOREIGN KEY ("user_uuid") REFERENCES "users" ("uuid") ON DELETE CASCADE ON UPDATE NO ACTION)', + ) + await queryRunner.query( + 'INSERT INTO "temporary_revoked_sessions"("uuid", "user_uuid", "received", "created_at", "received_at", "user_agent", "api_version") SELECT "uuid", "user_uuid", "received", "created_at", "received_at", "user_agent", "api_version" FROM "revoked_sessions"', + ) + await queryRunner.query('DROP TABLE "revoked_sessions"') + await queryRunner.query('ALTER TABLE "temporary_revoked_sessions" RENAME TO "revoked_sessions"') + await queryRunner.query('CREATE INDEX "index_revoked_sessions_on_user_uuid" ON "revoked_sessions" ("user_uuid") ') + await queryRunner.query( + 'CREATE INDEX "index_revoked_sessions_on_private_identifier" ON "revoked_sessions" ("private_identifier") ', + ) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX "index_revoked_sessions_on_user_uuid"') + await queryRunner.query('ALTER TABLE "revoked_sessions" RENAME TO "temporary_revoked_sessions"') + await queryRunner.query( + 'CREATE TABLE "revoked_sessions" ("uuid" varchar PRIMARY KEY NOT NULL, "user_uuid" varchar(36) NOT NULL, "received" tinyint NOT NULL DEFAULT (0), "created_at" datetime NOT NULL, "received_at" datetime, "user_agent" text, "api_version" varchar(255), CONSTRAINT "FK_edaf18faca67e682be39b5ecae5" FOREIGN KEY ("user_uuid") REFERENCES "users" ("uuid") ON DELETE CASCADE ON UPDATE NO ACTION)', + ) + await queryRunner.query( + 'INSERT INTO "revoked_sessions"("uuid", "user_uuid", "received", "created_at", "received_at", "user_agent", "api_version") SELECT "uuid", "user_uuid", "received", "created_at", "received_at", "user_agent", "api_version" FROM "temporary_revoked_sessions"', + ) + await queryRunner.query('DROP TABLE "temporary_revoked_sessions"') + await queryRunner.query('CREATE INDEX "index_revoked_sessions_on_user_uuid" ON "revoked_sessions" ("user_uuid") ') + } +} diff --git a/packages/auth/migrations/sqlite/1710236132439-add-application-and-snjs-to-sessions.ts b/packages/auth/migrations/sqlite/1710236132439-add-application-and-snjs-to-sessions.ts new file mode 100644 index 000000000..fc80e0d43 --- /dev/null +++ b/packages/auth/migrations/sqlite/1710236132439-add-application-and-snjs-to-sessions.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class AddApplicationAndSnjsToSessions1710236132439 implements MigrationInterface { + name = 'AddApplicationAndSnjsToSessions1710236132439' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` ADD `application` varchar(255) NULL') + await queryRunner.query('ALTER TABLE `sessions` ADD `snjs` varchar(255) NULL') + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `snjs`') + await queryRunner.query('ALTER TABLE `sessions` DROP COLUMN `application`') + } +} diff --git a/packages/auth/package.json b/packages/auth/package.json index 647c7e7d7..2245d9f66 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@standardnotes/auth-server", - "version": "1.178.3", + "version": "1.178.0", "engines": { "node": ">=18.0.0 <21.0.0" }, @@ -24,8 +24,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --fix --ext .ts", - "pretest": "yarn lint && yarn build", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "start": "yarn node dist/bin/server.js", "worker": "yarn node dist/bin/worker.js", "cleanup": "yarn node dist/bin/cleanup.js", @@ -60,7 +59,10 @@ "@standardnotes/sncrypto-common": "^1.13.4", "@standardnotes/sncrypto-node": "workspace:*", "@standardnotes/time": "workspace:*", + "agentkeepalive": "^4.5.0", + "axios": "^1.6.7", "bcryptjs": "2.4.3", + "cookie-parser": "^1.4.6", "cors": "2.8.5", "dayjs": "^1.11.6", "dotenv": "^16.0.1", @@ -68,7 +70,7 @@ "inversify": "^6.0.1", "inversify-express-utils": "^6.4.3", "ioredis": "^5.2.4", - "mysql2": "^3.0.1", + "mysql2": "^3.9.7", "otplib": "12.0.1", "prettyjson": "^1.2.5", "reflect-metadata": "^0.2.1", @@ -80,6 +82,7 @@ }, "devDependencies": { "@types/bcryptjs": "^2.4.2", + "@types/cookie-parser": "^1", "@types/cors": "^2.8.9", "@types/express": "^4.17.14", "@types/ioredis": "^5.0.0", diff --git a/packages/auth/src/Bootstrap/Container.ts b/packages/auth/src/Bootstrap/Container.ts index 634d87315..1ebd4256b 100644 --- a/packages/auth/src/Bootstrap/Container.ts +++ b/packages/auth/src/Bootstrap/Container.ts @@ -1,6 +1,8 @@ import * as winston from 'winston' +import * as AgentKeepAlive from 'agentkeepalive' import Redis from 'ioredis' import { SNSClient, SNSClientConfig } from '@aws-sdk/client-sns' +import axios, { AxiosInstance } from 'axios' import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs' import { S3Client } from '@aws-sdk/client-s3' import { Container } from 'inversify' @@ -36,13 +38,11 @@ import { AuthResponseFactoryResolver } from '../Domain/Auth/AuthResponseFactoryR import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts' import { IncreaseLoginAttempts } from '../Domain/UseCase/IncreaseLoginAttempts' import { GetUserKeyParams } from '../Domain/UseCase/GetUserKeyParams/GetUserKeyParams' -import { UpdateUser } from '../Domain/UseCase/UpdateUser' import { RedisEphemeralSessionRepository } from '../Infra/Redis/RedisEphemeralSessionRepository' import { GetActiveSessionsForUser } from '../Domain/UseCase/GetActiveSessionsForUser' import { DeleteOtherSessionsForUser } from '../Domain/UseCase/DeleteOtherSessionsForUser' import { DeleteSessionForUser } from '../Domain/UseCase/DeleteSessionForUser' import { Register } from '../Domain/UseCase/Register' -import { LockRepository } from '../Infra/Redis/LockRepository' import { TypeORMRevokedSessionRepository } from '../Infra/TypeORM/TypeORMRevokedSessionRepository' import { AuthenticationMethodResolver } from '../Domain/Auth/AuthenticationMethodResolver' import { RevokedSession } from '../Domain/Session/RevokedSession' @@ -286,6 +286,19 @@ import { FixStorageQuotaForUser } from '../Domain/UseCase/FixStorageQuotaForUser import { FileQuotaRecalculatedEventHandler } from '../Domain/Handler/FileQuotaRecalculatedEventHandler' import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface' import { SubscriptionStateFetchedEventHandler } from '../Domain/Handler/SubscriptionStateFetchedEventHandler' +import { CaptchaServerInterface } from '../Domain/HumanVerification/CaptchaServerInterface' +import { VerifyHumanInteraction } from '../Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction' +import { HttpCaptchaServer } from '../Infra/Http/HumanVerification/HttpCaptchaServer' +import { CookieFactoryInterface } from '../Domain/Auth/Cookies/CookieFactoryInterface' +import { CookieFactory } from '../Domain/Auth/Cookies/CookieFactory' +import { RedisLockRepository } from '../Infra/Redis/RedisLockRepository' +import { DeleteSessionByToken } from '../Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken' +import { GetSessionFromToken } from '../Domain/UseCase/GetSessionFromToken/GetSessionFromToken' +import { CooldownSessionTokens } from '../Domain/UseCase/CooldownSessionTokens/CooldownSessionTokens' +import { SessionTokensCooldownRepositoryInterface } from '../Domain/Session/SessionTokensCooldownRepositoryInterface' +import { RedisSessionTokensCooldownRepository } from '../Infra/Redis/RedisSessionTokensCooldownRepository' +import { InMemorySessionTokensCooldownRepository } from '../Infra/InMemory/InMemorySessionTokensCooldownRepository' +import { GetCooldownSessionTokens } from '../Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens' export class ContainerConfigLoader { constructor(private mode: 'server' | 'worker' = 'server') {} @@ -330,6 +343,8 @@ export class ContainerConfigLoader { const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted' const isConfiguredForHomeServerOrSelfHosting = isConfiguredForHomeServer || isConfiguredForSelfHosting const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory' + const captchaServerUrl = env.get('CAPTCHA_SERVER_URL', true) + const captchaUIUrl = env.get('CAPTCHA_UI_URL', true) container .bind(TYPES.Auth_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING) @@ -597,9 +612,17 @@ export class ContainerConfigLoader { container .bind(TYPES.Auth_MAX_LOGIN_ATTEMPTS) .toConstantValue(env.get('MAX_LOGIN_ATTEMPTS', true) ? +env.get('MAX_LOGIN_ATTEMPTS', true) : 6) + container + .bind(TYPES.Auth_MAX_CAPTCHA_LOGIN_ATTEMPTS) + .toConstantValue(env.get('MAX_CAPTCHA_LOGIN_ATTEMPTS', true) ? +env.get('MAX_CAPTCHA_LOGIN_ATTEMPTS', true) : 6) container .bind(TYPES.Auth_FAILED_LOGIN_LOCKOUT) .toConstantValue(env.get('FAILED_LOGIN_LOCKOUT', true) ? +env.get('FAILED_LOGIN_LOCKOUT', true) : 3600) + container + .bind(TYPES.Auth_FAILED_LOGIN_CAPTCHA_LOCKOUT) + .toConstantValue( + env.get('FAILED_LOGIN_CAPTCHA_LOCKOUT', true) ? +env.get('FAILED_LOGIN_CAPTCHA_LOCKOUT', true) : 86400, + ) container.bind(TYPES.Auth_PSEUDO_KEY_PARAMS_KEY).toConstantValue(env.get('PSEUDO_KEY_PARAMS_KEY')) container .bind(TYPES.Auth_EPHEMERAL_SESSION_AGE) @@ -633,6 +656,10 @@ export class ContainerConfigLoader { container .bind(TYPES.Auth_READONLY_USERS) .toConstantValue(env.get('READONLY_USERS', true) ? env.get('READONLY_USERS', true).split(',') : []) + container.bind(TYPES.Auth_CAPTCHA_SERVER_URL).toConstantValue(captchaServerUrl) + container.bind(TYPES.Auth_CAPTCHA_UI_URL).toConstantValue(captchaUIUrl) + container.bind(TYPES.Auth_HUMAN_VERIFICATION_ENABLED).toConstantValue(!!captchaServerUrl && !!captchaUIUrl) + container.bind(TYPES.Auth_FORCE_LEGACY_SESSIONS).toConstantValue(env.get('E2E_TESTING', true) === 'true') if (isConfiguredForInMemoryCache) { container @@ -652,6 +679,7 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_Timer), container.get(TYPES.Auth_MAX_LOGIN_ATTEMPTS), container.get(TYPES.Auth_FAILED_LOGIN_LOCKOUT), + container.get(TYPES.Auth_FAILED_LOGIN_CAPTCHA_LOCKOUT), ), ) container @@ -679,9 +707,21 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_Timer), ), ) + container + .bind(TYPES.Auth_SessionTokensCooldownRepository) + .toConstantValue(new InMemorySessionTokensCooldownRepository()) } else { container.bind(TYPES.Auth_PKCERepository).to(RedisPKCERepository) - container.bind(TYPES.Auth_LockRepository).to(LockRepository) + container + .bind(TYPES.Auth_LockRepository) + .toConstantValue( + new RedisLockRepository( + container.get(TYPES.Auth_Redis), + container.get(TYPES.Auth_MAX_LOGIN_ATTEMPTS), + container.get(TYPES.Auth_FAILED_LOGIN_LOCKOUT), + container.get(TYPES.Auth_FAILED_LOGIN_CAPTCHA_LOCKOUT), + ), + ) container .bind(TYPES.Auth_EphemeralSessionRepository) .to(RedisEphemeralSessionRepository) @@ -691,6 +731,9 @@ export class ContainerConfigLoader { container .bind(TYPES.Auth_SubscriptionTokenRepository) .to(RedisSubscriptionTokenRepository) + container + .bind(TYPES.Auth_SessionTokensCooldownRepository) + .toConstantValue(new RedisSessionTokensCooldownRepository(container.get(TYPES.Auth_Redis))) } container @@ -740,6 +783,41 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_UserSubscriptionRepository), container.get(TYPES.Auth_READONLY_USERS), container.get(TYPES.Auth_GetSetting), + container.get(TYPES.Auth_FORCE_LEGACY_SESSIONS), + ), + ) + container + .bind(TYPES.Auth_GetCooldownSessionTokens) + .toConstantValue( + new GetCooldownSessionTokens( + container.get(TYPES.Auth_SessionTokensCooldownRepository), + ), + ) + container + .bind(TYPES.Auth_GetSessionFromToken) + .toConstantValue( + new GetSessionFromToken( + container.get(TYPES.Auth_SessionRepository), + container.get(TYPES.Auth_EphemeralSessionRepository), + container.get(TYPES.Auth_GetCooldownSessionTokens), + container.get(TYPES.Auth_Logger), + ), + ) + container + .bind(TYPES.Auth_DeleteSessionByToken) + .toConstantValue( + new DeleteSessionByToken( + container.get(TYPES.Auth_GetSessionFromToken), + container.get(TYPES.Auth_SessionRepository), + container.get(TYPES.Auth_EphemeralSessionRepository), + ), + ) + container + .bind(TYPES.Auth_CooldownSessionTokens) + .toConstantValue( + new CooldownSessionTokens( + env.get('COOLDOWN_SESSION_TOKENS_TTL', true) ? +env.get('COOLDOWN_SESSION_TOKENS_TTL', true) : 120, + container.get(TYPES.Auth_SessionTokensCooldownRepository), ), ) container.bind(TYPES.Auth_AuthResponseFactory20161215).to(AuthResponseFactory20161215) @@ -780,7 +858,16 @@ export class ContainerConfigLoader { .toConstantValue(new TokenEncoder(container.get(TYPES.Auth_VALET_TOKEN_SECRET))) container .bind(TYPES.Auth_AuthenticationMethodResolver) - .to(AuthenticationMethodResolver) + .toConstantValue( + new AuthenticationMethodResolver( + container.get(TYPES.Auth_UserRepository), + container.get(TYPES.Auth_SessionService), + container.get>(TYPES.Auth_SessionTokenDecoder), + container.get>(TYPES.Auth_FallbackSessionTokenDecoder), + container.get(TYPES.Auth_GetSessionFromToken), + container.get(TYPES.Auth_Logger), + ), + ) container.bind(TYPES.Auth_DomainEventFactory).to(DomainEventFactory) container .bind(TYPES.Auth_SettingsAssociationService) @@ -819,6 +906,43 @@ export class ContainerConfigLoader { .bind>(TYPES.Auth_BooleanSelector) .toConstantValue(new DeterministicSelector()) + const httpAgentKeepAliveTimeout = env.get('HTTP_AGENT_KEEP_ALIVE_TIMEOUT', true) + ? +env.get('HTTP_AGENT_KEEP_ALIVE_TIMEOUT', true) + : 4_000 + + container.bind(TYPES.Auth_HTTPClient).toConstantValue( + axios.create({ + httpAgent: new AgentKeepAlive({ + keepAlive: true, + timeout: 2 * httpAgentKeepAliveTimeout, + freeSocketTimeout: httpAgentKeepAliveTimeout, + }), + }), + ) + + container + .bind(TYPES.Auth_CaptchaServer) + .toConstantValue( + new HttpCaptchaServer( + container.get(TYPES.Auth_Logger), + container.get(TYPES.Auth_HTTPClient), + container.get(TYPES.Auth_CAPTCHA_SERVER_URL), + ), + ) + + container + .bind(TYPES.Auth_CookieFactory) + .toConstantValue( + new CookieFactory( + ['None', 'Lax', 'Strict'].includes(env.get('COOKIE_SAME_SITE', true)) + ? (env.get('COOKIE_SAME_SITE', true) as 'None' | 'Lax' | 'Strict') + : 'None', + env.get('COOKIE_DOMAIN', true) ?? 'standardnotes.com', + env.get('COOKIE_SECURE', true) ? env.get('COOKIE_SECURE', true) === 'true' : true, + env.get('COOKIE_PARTITIONED', true) ? env.get('COOKIE_PARTITIONED', true) === 'true' : true, + ), + ) + // Middleware container.bind(TYPES.Auth_SessionMiddleware).to(SessionMiddleware) container.bind(TYPES.Auth_LockMiddleware).to(LockMiddleware) @@ -953,6 +1077,7 @@ export class ContainerConfigLoader { new SetSubscriptionSettingValue( container.get(TYPES.Auth_SubscriptionSettingRepository), container.get(TYPES.Auth_GetSubscriptionSetting), + container.get(TYPES.Auth_SettingsAssociationService), container.get(TYPES.Auth_Timer), ), ) @@ -997,10 +1122,36 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_DomainEventPublisher), container.get(TYPES.Auth_Timer), container.get(TYPES.Auth_GetSetting), + container.get(TYPES.Auth_CooldownSessionTokens), + container.get(TYPES.Auth_GetSessionFromToken), container.get(TYPES.Auth_Logger), ), ) - container.bind(TYPES.Auth_SignIn).to(SignIn) + container + .bind(TYPES.Auth_VerifyHumanInteraction) + .toConstantValue( + new VerifyHumanInteraction( + container.get(TYPES.Auth_HUMAN_VERIFICATION_ENABLED), + container.get(TYPES.Auth_CaptchaServer), + ), + ) + container + .bind(TYPES.Auth_SignIn) + .toConstantValue( + new SignIn( + container.get(TYPES.Auth_UserRepository), + container.get(TYPES.Auth_AuthResponseFactoryResolver), + container.get(TYPES.Auth_DomainEventPublisher), + container.get(TYPES.Auth_DomainEventFactory), + container.get(TYPES.Auth_SessionService), + container.get(TYPES.Auth_PKCERepository), + container.get(TYPES.Auth_Crypter), + container.get(TYPES.Auth_Logger), + container.get(TYPES.Auth_MAX_LOGIN_ATTEMPTS), + container.get(TYPES.Auth_LockRepository), + container.get(TYPES.Auth_VerifyHumanInteraction), + ), + ) container .bind(TYPES.Auth_VerifyMFA) .toConstantValue( @@ -1017,8 +1168,24 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_Logger), ), ) - container.bind(TYPES.Auth_ClearLoginAttempts).to(ClearLoginAttempts) - container.bind(TYPES.Auth_IncreaseLoginAttempts).to(IncreaseLoginAttempts) + container + .bind(TYPES.Auth_ClearLoginAttempts) + .toConstantValue( + new ClearLoginAttempts( + container.get(TYPES.Auth_UserRepository), + container.get(TYPES.Auth_LockRepository), + container.get(TYPES.Auth_Logger), + ), + ) + container + .bind(TYPES.Auth_IncreaseLoginAttempts) + .toConstantValue( + new IncreaseLoginAttempts( + container.get(TYPES.Auth_UserRepository), + container.get(TYPES.Auth_LockRepository), + container.get(TYPES.Auth_MAX_LOGIN_ATTEMPTS), + ), + ) container .bind(TYPES.Auth_GetUserKeyParamsRecovery) .toConstantValue( @@ -1029,7 +1196,6 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_GetSetting), ), ) - container.bind(TYPES.Auth_UpdateUser).to(UpdateUser) container .bind(TYPES.Auth_ApplyDefaultSettings) .toConstantValue( @@ -1130,6 +1296,9 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_ClearLoginAttempts), container.get(TYPES.Auth_DeleteSetting), container.get(TYPES.Auth_AuthenticatorRepository), + container.get(TYPES.Auth_MAX_LOGIN_ATTEMPTS), + container.get(TYPES.Auth_LockRepository), + container.get(TYPES.Auth_VerifyHumanInteraction), ), ) container @@ -1262,7 +1431,6 @@ export class ContainerConfigLoader { .toConstantValue( new TriggerEmailBackupForUser( container.get(TYPES.Auth_RoleService), - container.get(TYPES.Auth_GetSetting), container.get(TYPES.Auth_GetUserKeyParams), container.get(TYPES.Auth_DomainEventPublisher), container.get(TYPES.Auth_DomainEventFactory), @@ -1337,15 +1505,9 @@ export class ContainerConfigLoader { .bind(TYPES.Auth_AuthController) .toConstantValue( new AuthController( - container.get(TYPES.Auth_ClearLoginAttempts), - container.get(TYPES.Auth_Register), - container.get(TYPES.Auth_DomainEventPublisher), - container.get(TYPES.Auth_DomainEventFactory), - container.get(TYPES.Auth_SignInWithRecoveryCodes), - container.get(TYPES.Auth_GetUserKeyParamsRecovery), - container.get(TYPES.Auth_GenerateRecoveryCodes), - container.get(TYPES.Auth_Logger), - container.get(TYPES.Auth_SessionService), + container.get(TYPES.Auth_GetUserKeyParamsRecovery), + container.get(TYPES.Auth_GenerateRecoveryCodes), + container.get(TYPES.Auth_Logger), ), ) container @@ -1664,14 +1826,23 @@ export class ContainerConfigLoader { .bind(TYPES.Auth_BaseAuthController) .toConstantValue( new BaseAuthController( - container.get(TYPES.Auth_VerifyMFA), - container.get(TYPES.Auth_SignIn), - container.get(TYPES.Auth_GetUserKeyParams), - container.get(TYPES.Auth_ClearLoginAttempts), - container.get(TYPES.Auth_IncreaseLoginAttempts), - container.get(TYPES.Auth_Logger), - container.get(TYPES.Auth_AuthController), - container.get(TYPES.Auth_ControllerContainer), + container.get(TYPES.Auth_VerifyMFA), + container.get(TYPES.Auth_SignIn), + container.get(TYPES.Auth_GetUserKeyParams), + container.get(TYPES.Auth_ClearLoginAttempts), + container.get(TYPES.Auth_IncreaseLoginAttempts), + container.get(TYPES.Auth_Logger), + container.get(TYPES.Auth_AuthController), + container.get(TYPES.Auth_Register), + container.get(TYPES.Auth_DomainEventPublisher), + container.get(TYPES.Auth_DomainEventFactory), + container.get(TYPES.Auth_SessionService), + container.get(TYPES.Auth_VerifyHumanInteraction), + container.get(TYPES.Auth_CookieFactory), + container.get(TYPES.Auth_SignInWithRecoveryCodes), + container.get(TYPES.Auth_DeleteSessionByToken), + container.get(TYPES.Auth_CAPTCHA_UI_URL), + container.get(TYPES.Auth_ControllerContainer), ), ) @@ -1738,6 +1909,7 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_ClearLoginAttempts), container.get(TYPES.Auth_IncreaseLoginAttempts), container.get(TYPES.Auth_ChangeCredentials), + container.get(TYPES.Auth_CookieFactory), container.get(TYPES.Auth_ControllerContainer), ), ) @@ -1745,11 +1917,12 @@ export class ContainerConfigLoader { .bind(TYPES.Auth_BaseAdminController) .toConstantValue( new BaseAdminController( - container.get(TYPES.Auth_DeleteSetting), - container.get(TYPES.Auth_UserRepository), - container.get(TYPES.Auth_CreateSubscriptionToken), - container.get(TYPES.Auth_CreateOfflineSubscriptionToken), - container.get(TYPES.Auth_ControllerContainer), + container.get(TYPES.Auth_DeleteSetting), + container.get(TYPES.Auth_GetSetting), + container.get(TYPES.Auth_UserRepository), + container.get(TYPES.Auth_CreateSubscriptionToken), + container.get(TYPES.Auth_CreateOfflineSubscriptionToken), + container.get(TYPES.Auth_ControllerContainer), ), ) container @@ -1772,9 +1945,12 @@ export class ContainerConfigLoader { new BaseSubscriptionSettingsController( container.get(TYPES.Auth_GetSubscriptionSetting), container.get(TYPES.Auth_GetSharedOrRegularSubscriptionForUser), + container.get(TYPES.Auth_SetSubscriptionSettingValue), + container.get(TYPES.Auth_TriggerPostSettingUpdateActions), container.get>( TYPES.Auth_SubscriptionSettingHttpMapper, ), + container.get(TYPES.Auth_Logger), container.get(TYPES.Auth_ControllerContainer), ), ) @@ -1799,10 +1975,11 @@ export class ContainerConfigLoader { .bind(TYPES.Auth_BaseSessionController) .toConstantValue( new BaseSessionController( - container.get(TYPES.Auth_DeleteSessionForUser), - container.get(TYPES.Auth_DeleteOtherSessionsForUser), - container.get(TYPES.Auth_RefreshSessionToken), - container.get(TYPES.Auth_ControllerContainer), + container.get(TYPES.Auth_DeleteSessionForUser), + container.get(TYPES.Auth_DeleteOtherSessionsForUser), + container.get(TYPES.Auth_RefreshSessionToken), + container.get(TYPES.Auth_CookieFactory), + container.get(TYPES.Auth_ControllerContainer), ), ) container diff --git a/packages/auth/src/Bootstrap/Types.ts b/packages/auth/src/Bootstrap/Types.ts index 2a04b5000..118260349 100644 --- a/packages/auth/src/Bootstrap/Types.ts +++ b/packages/auth/src/Bootstrap/Types.ts @@ -34,6 +34,7 @@ const TYPES = { Auth_UserSubscriptionRepository: Symbol.for('Auth_UserSubscriptionRepository'), Auth_OfflineUserSubscriptionRepository: Symbol.for('Auth_OfflineUserSubscriptionRepository'), Auth_SubscriptionTokenRepository: Symbol.for('Auth_SubscriptionTokenRepository'), + Auth_SessionTokensCooldownRepository: Symbol.for('Auth_SessionTokensCooldownRepository'), Auth_OfflineSubscriptionTokenRepository: Symbol.for('Auth_OfflineSubscriptionTokenRepository'), Auth_SharedSubscriptionInvitationRepository: Symbol.for('Auth_SharedSubscriptionInvitationRepository'), Auth_PKCERepository: Symbol.for('Auth_PKCERepository'), @@ -84,7 +85,9 @@ const TYPES = { Auth_REFRESH_TOKEN_AGE: Symbol.for('Auth_REFRESH_TOKEN_AGE'), Auth_EPHEMERAL_SESSION_AGE: Symbol.for('Auth_EPHEMERAL_SESSION_AGE'), Auth_MAX_LOGIN_ATTEMPTS: Symbol.for('Auth_MAX_LOGIN_ATTEMPTS'), + Auth_MAX_CAPTCHA_LOGIN_ATTEMPTS: Symbol.for('Auth_MAX_CAPTCHA_LOGIN_ATTEMPTS'), Auth_FAILED_LOGIN_LOCKOUT: Symbol.for('Auth_FAILED_LOGIN_LOCKOUT'), + Auth_FAILED_LOGIN_CAPTCHA_LOCKOUT: Symbol.for('Auth_FAILED_LOGIN_CAPTCHA_LOCKOUT'), Auth_PSEUDO_KEY_PARAMS_KEY: Symbol.for('Auth_PSEUDO_KEY_PARAMS_KEY'), Auth_REDIS_URL: Symbol.for('Auth_REDIS_URL'), Auth_DISABLE_USER_REGISTRATION: Symbol.for('Auth_DISABLE_USER_REGISTRATION'), @@ -100,6 +103,10 @@ const TYPES = { Auth_U2F_REQUIRE_USER_VERIFICATION: Symbol.for('Auth_U2F_REQUIRE_USER_VERIFICATION'), Auth_READONLY_USERS: Symbol.for('Auth_READONLY_USERS'), Auth_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING: Symbol.for('Auth_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING'), + Auth_CAPTCHA_SERVER_URL: Symbol.for('Auth_CAPTCHA_SERVER_URL'), + Auth_CAPTCHA_UI_URL: Symbol.for('Auth_CAPTCHA_UI_URL'), + Auth_HUMAN_VERIFICATION_ENABLED: Symbol.for('Auth_HUMAN_VERIFICATION_ENABLED'), + Auth_FORCE_LEGACY_SESSIONS: Symbol.for('Auth_FORCE_LEGACY_SESSIONS'), // use cases Auth_AuthenticateUser: Symbol.for('Auth_AuthenticateUser'), Auth_AuthenticateRequest: Symbol.for('Auth_AuthenticateRequest'), @@ -109,7 +116,6 @@ const TYPES = { Auth_ClearLoginAttempts: Symbol.for('Auth_ClearLoginAttempts'), Auth_IncreaseLoginAttempts: Symbol.for('Auth_IncreaseLoginAttempts'), Auth_GetUserKeyParams: Symbol.for('Auth_GetUserKeyParams'), - Auth_UpdateUser: Symbol.for('Auth_UpdateUser'), Auth_Register: Symbol.for('Auth_Register'), Auth_GetActiveSessionsForUser: Symbol.for('Auth_GetActiveSessionsForUser'), Auth_DeleteOtherSessionsForUser: Symbol.for('Auth_DeleteOtherSessionsForUser'), @@ -158,6 +164,10 @@ const TYPES = { Auth_ApplyDefaultSettings: Symbol.for('Auth_ApplyDefaultSettings'), Auth_ActivatePremiumFeatures: Symbol.for('Auth_ActivatePremiumFeatures'), Auth_SignInWithRecoveryCodes: Symbol.for('Auth_SignInWithRecoveryCodes'), + Auth_GetSessionFromToken: Symbol.for('Auth_GetSessionFromToken'), + Auth_DeleteSessionByToken: Symbol.for('Auth_DeleteSessionByToken'), + Auth_CooldownSessionTokens: Symbol.for('Auth_CooldownSessionTokens'), + Auth_GetCooldownSessionTokens: Symbol.for('Auth_GetCooldownSessionTokens'), Auth_GetUserKeyParamsRecovery: Symbol.for('Auth_GetUserKeyParamsRecovery'), Auth_UpdateStorageQuotaUsedForUser: Symbol.for('Auth_UpdateStorageQuotaUsedForUser'), Auth_AddSharedVaultUser: Symbol.for('Auth_AddSharedVaultUser'), @@ -171,6 +181,7 @@ const TYPES = { Auth_DeleteAccountsFromCSVFile: Symbol.for('Auth_DeleteAccountsFromCSVFile'), Auth_RenewSharedSubscriptions: Symbol.for('Auth_RenewSharedSubscriptions'), Auth_FixStorageQuotaForUser: Symbol.for('Auth_FixStorageQuotaForUser'), + Auth_VerifyHumanInteraction: Symbol.for('Auth_VerifyHumanInteraction'), // Handlers Auth_AccountDeletionRequestedEventHandler: Symbol.for('Auth_AccountDeletionRequestedEventHandler'), Auth_AccountDeletionVerificationPassedEventHandler: Symbol.for('Auth_AccountDeletionVerificationPassedEventHandler'), @@ -207,6 +218,7 @@ const TYPES = { Auth_FileQuotaRecalculatedEventHandler: Symbol.for('Auth_FileQuotaRecalculatedEventHandler'), Auth_SubscriptionStateFetchedEventHandler: Symbol.for('Auth_SubscriptionStateFetchedEventHandler'), // Services + Auth_CookieFactory: Symbol.for('Auth_CookieFactory'), Auth_DeviceDetector: Symbol.for('Auth_DeviceDetector'), Auth_SessionService: Symbol.for('Auth_SessionService'), Auth_OfflineSettingService: Symbol.for('Auth_OfflineSettingService'), @@ -259,6 +271,8 @@ const TYPES = { Auth_BaseListedController: Symbol.for('Auth_BaseListedController'), Auth_BaseFeaturesController: Symbol.for('Auth_BaseFeaturesController'), Auth_CSVFileReader: Symbol.for('Auth_CSVFileReader'), + Auth_CaptchaServer: Symbol.for('Auth_CaptchaServer'), + Auth_HTTPClient: Symbol.for('Auth_HTTPClient'), } export default TYPES diff --git a/packages/auth/src/Controller/AuthController.spec.ts b/packages/auth/src/Controller/AuthController.spec.ts deleted file mode 100644 index a8faf2f88..000000000 --- a/packages/auth/src/Controller/AuthController.spec.ts +++ /dev/null @@ -1,149 +0,0 @@ -import 'reflect-metadata' - -import { DomainEventInterface, DomainEventPublisherInterface } from '@standardnotes/domain-events' - -import { AuthController } from './AuthController' -import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts' -import { User } from '../Domain/User/User' -import { Register } from '../Domain/UseCase/Register' -import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface' -import { KeyParamsOrigination, ProtocolVersion } from '@standardnotes/common' -import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes' -import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery' -import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes' -import { Logger } from 'winston' -import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface' -import { ApiVersion } from '../Domain/Api/ApiVersion' - -describe('AuthController', () => { - let clearLoginAttempts: ClearLoginAttempts - let register: Register - let domainEventPublisher: DomainEventPublisherInterface - let domainEventFactory: DomainEventFactoryInterface - let event: DomainEventInterface - let user: User - let doSignInWithRecoveryCodes: SignInWithRecoveryCodes - let getUserKeyParamsRecovery: GetUserKeyParamsRecovery - let doGenerateRecoveryCodes: GenerateRecoveryCodes - let logger: Logger - let sessionService: SessionServiceInterface - - const createController = () => - new AuthController( - clearLoginAttempts, - register, - domainEventPublisher, - domainEventFactory, - doSignInWithRecoveryCodes, - getUserKeyParamsRecovery, - doGenerateRecoveryCodes, - logger, - sessionService, - ) - - beforeEach(() => { - register = {} as jest.Mocked - register.execute = jest.fn() - - user = {} as jest.Mocked - user.email = 'test@test.te' - - clearLoginAttempts = {} as jest.Mocked - clearLoginAttempts.execute = jest.fn() - - event = {} as jest.Mocked - - domainEventPublisher = {} as jest.Mocked - domainEventPublisher.publish = jest.fn() - - domainEventFactory = {} as jest.Mocked - domainEventFactory.createUserRegisteredEvent = jest.fn().mockReturnValue(event) - - logger = {} as jest.Mocked - logger.debug = jest.fn() - - sessionService = {} as jest.Mocked - sessionService.deleteSessionByToken = jest.fn().mockReturnValue('1-2-3') - }) - - it('should register a user', async () => { - register.execute = jest.fn().mockReturnValue({ success: true, authResponse: { user } }) - - const response = await createController().register({ - email: 'test@test.te', - password: 'asdzxc', - version: ProtocolVersion.V004, - api: ApiVersion.v20200115, - origination: KeyParamsOrigination.Registration, - userAgent: 'Google Chrome', - identifier: 'test@test.te', - pw_nonce: '11', - ephemeral: false, - }) - - expect(register.execute).toHaveBeenCalledWith({ - apiVersion: '20200115', - kpOrigination: 'registration', - updatedWithUserAgent: 'Google Chrome', - ephemeralSession: false, - version: '004', - email: 'test@test.te', - password: 'asdzxc', - pwNonce: '11', - }) - - expect(domainEventPublisher.publish).toHaveBeenCalledWith(event) - - expect(response.status).toEqual(200) - expect(response.data).toEqual({ user: { email: 'test@test.te' } }) - }) - - it('should not register a user if request param is missing', async () => { - const response = await createController().register({ - email: 'test@test.te', - password: '', - version: ProtocolVersion.V004, - api: ApiVersion.v20200115, - origination: KeyParamsOrigination.Registration, - userAgent: 'Google Chrome', - identifier: 'test@test.te', - pw_nonce: '11', - ephemeral: false, - }) - - expect(domainEventPublisher.publish).not.toHaveBeenCalled() - - expect(response.status).toEqual(400) - }) - - it('should respond with error if registering a user fails', async () => { - register.execute = jest.fn().mockReturnValue({ success: false, errorMessage: 'Something bad happened' }) - - const response = await createController().register({ - email: 'test@test.te', - password: 'test', - version: ProtocolVersion.V004, - api: ApiVersion.v20200115, - origination: KeyParamsOrigination.Registration, - userAgent: 'Google Chrome', - identifier: 'test@test.te', - pw_nonce: '11', - ephemeral: false, - }) - - expect(domainEventPublisher.publish).not.toHaveBeenCalled() - - expect(response.status).toEqual(400) - }) - - it('should throw error on the delete user method as it is still a part of the payments server', async () => { - let caughtError = null - try { - await createController().deleteAccount({} as never) - } catch (error) { - caughtError = error - } - - expect(caughtError).not.toBeNull() - }) -}) diff --git a/packages/auth/src/Controller/AuthController.ts b/packages/auth/src/Controller/AuthController.ts index 7611fe3d9..c0190272c 100644 --- a/packages/auth/src/Controller/AuthController.ts +++ b/packages/auth/src/Controller/AuthController.ts @@ -1,42 +1,23 @@ -import { DomainEventPublisherInterface } from '@standardnotes/domain-events' -import { - UserRegistrationRequestParams, - UserServerInterface, - UserDeletionResponseBody, - UserRegistrationResponseBody, - UserUpdateRequestParams, -} from '@standardnotes/api' -import { ErrorTag, HttpResponse, HttpStatusCode } from '@standardnotes/responses' -import { ProtocolVersion } from '@standardnotes/common' +import { UserDeletionResponseBody, UserUpdateRequestParams } from '@standardnotes/api' +import { HttpResponse, HttpStatusCode } from '@standardnotes/responses' -import { ClearLoginAttempts } from '../Domain/UseCase/ClearLoginAttempts' -import { Register } from '../Domain/UseCase/Register' -import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface' -import { SignInWithRecoveryCodes } from '../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes' -import { SignInWithRecoveryCodesRequestParams } from '../Infra/Http/Request/SignInWithRecoveryCodesRequestParams' import { GetUserKeyParamsRecovery } from '../Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery' import { RecoveryKeyParamsRequestParams } from '../Infra/Http/Request/RecoveryKeyParamsRequestParams' -import { SignInWithRecoveryCodesResponseBody } from '../Infra/Http/Response/SignInWithRecoveryCodesResponseBody' import { RecoveryKeyParamsResponseBody } from '../Infra/Http/Response/RecoveryKeyParamsResponseBody' import { GenerateRecoveryCodesResponseBody } from '../Infra/Http/Response/GenerateRecoveryCodesResponseBody' import { GenerateRecoveryCodes } from '../Domain/UseCase/GenerateRecoveryCodes/GenerateRecoveryCodes' import { GenerateRecoveryCodesRequestParams } from '../Infra/Http/Request/GenerateRecoveryCodesRequestParams' import { Logger } from 'winston' -import { SessionServiceInterface } from '../Domain/Session/SessionServiceInterface' -import { ApiVersion } from '../Domain/Api/ApiVersion' import { UserUpdateResponse } from '@standardnotes/api/dist/Domain/Response/User/UserUpdateResponse' -export class AuthController implements UserServerInterface { +/** + * DEPRECATED: This controller is deprecated and will be removed in the future. + */ +export class AuthController { constructor( - private clearLoginAttempts: ClearLoginAttempts, - private registerUser: Register, - private domainEventPublisher: DomainEventPublisherInterface, - private domainEventFactory: DomainEventFactoryInterface, - private doSignInWithRecoveryCodes: SignInWithRecoveryCodes, private getUserKeyParamsRecovery: GetUserKeyParamsRecovery, private doGenerateRecoveryCodes: GenerateRecoveryCodes, private logger: Logger, - private sessionService: SessionServiceInterface, ) {} async update(_params: UserUpdateRequestParams): Promise> { @@ -47,57 +28,6 @@ export class AuthController implements UserServerInterface { throw new Error('This method is implemented on the payments server.') } - async register(params: UserRegistrationRequestParams): Promise> { - if (!params.email || !params.password) { - return { - status: HttpStatusCode.BadRequest, - data: { - error: { - message: 'Please enter an email and a password to register.', - }, - }, - } - } - - const registerResult = await this.registerUser.execute({ - email: params.email, - password: params.password, - updatedWithUserAgent: params.userAgent as string, - apiVersion: params.api, - ephemeralSession: params.ephemeral, - pwNonce: params.pw_nonce, - kpOrigination: params.origination, - kpCreated: params.created, - version: params.version, - }) - - if (!registerResult.success) { - return { - status: HttpStatusCode.BadRequest, - data: { - error: { - message: registerResult.errorMessage, - }, - }, - } - } - - await this.clearLoginAttempts.execute({ email: registerResult.authResponse.user.email as string }) - - await this.domainEventPublisher.publish( - this.domainEventFactory.createUserRegisteredEvent({ - userUuid: registerResult.authResponse.user.uuid, - email: registerResult.authResponse.user.email, - protocolVersion: (registerResult.authResponse.user.protocolVersion) as ProtocolVersion, - }), - ) - - return { - status: HttpStatusCode.Success, - data: registerResult.authResponse, - } - } - async generateRecoveryCodes( params: GenerateRecoveryCodesRequestParams, ): Promise> { @@ -124,62 +54,11 @@ export class AuthController implements UserServerInterface { } } - async signInWithRecoveryCodes( - params: SignInWithRecoveryCodesRequestParams, - ): Promise> { - if (params.apiVersion !== ApiVersion.v20200115) { - return { - status: HttpStatusCode.BadRequest, - data: { - error: { - message: 'Invalid API version.', - }, - }, - } - } - - const result = await this.doSignInWithRecoveryCodes.execute({ - userAgent: params.userAgent, - username: params.username, - password: params.password, - codeVerifier: params.codeVerifier, - recoveryCodes: params.recoveryCodes, - }) - - if (result.isFailed()) { - this.logger.debug(`Failed to sign in with recovery codes: ${result.getError()}`) - - return { - status: HttpStatusCode.Unauthorized, - data: { - error: { - message: 'Invalid login credentials.', - }, - }, - } - } - - return { - status: HttpStatusCode.Success, - data: result.getValue(), - } - } - async recoveryKeyParams( params: RecoveryKeyParamsRequestParams, ): Promise> { - if (params.apiVersion !== ApiVersion.v20200115) { - return { - status: HttpStatusCode.BadRequest, - data: { - error: { - message: 'Invalid API version.', - }, - }, - } - } - const result = await this.getUserKeyParamsRecovery.execute({ + apiVersion: params.apiVersion, username: params.username, codeChallenge: params.codeChallenge, recoveryCodes: params.recoveryCodes, @@ -205,33 +84,4 @@ export class AuthController implements UserServerInterface { }, } } - - async signOut(params: Record): Promise { - if (params.readOnlyAccess) { - return { - status: HttpStatusCode.Unauthorized, - data: { - error: { - tag: ErrorTag.ReadOnlyAccess, - message: 'Session has read-only access.', - }, - }, - } - } - - const userUuid = await this.sessionService.deleteSessionByToken( - (params.authorizationHeader as string).replace('Bearer ', ''), - ) - - let headers = undefined - if (userUuid !== null) { - headers = new Map([['x-invalidate-cache', userUuid]]) - } - - return { - status: HttpStatusCode.NoContent, - data: {}, - headers, - } - } } diff --git a/packages/auth/src/Controller/SubscriptionInvitesController.spec.ts b/packages/auth/src/Controller/SubscriptionInvitesController.spec.ts index 247507cfb..67491756f 100644 --- a/packages/auth/src/Controller/SubscriptionInvitesController.spec.ts +++ b/packages/auth/src/Controller/SubscriptionInvitesController.spec.ts @@ -53,7 +53,10 @@ describe('SubscriptionInvitesController', () => { invitations: [], }) - const result = await createController().listInvites({ api: ApiVersion.v20200115, inviterEmail: 'test@test.te' }) + const result = await createController().listInvites({ + api: ApiVersion.VERSIONS.v20200115, + inviterEmail: 'test@test.te', + }) expect(listSharedSubscriptionInvitations.execute).toHaveBeenCalledWith({ inviterEmail: 'test@test.te', @@ -68,7 +71,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().cancelInvite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, inviteUuid: '1-2-3', inviterEmail: 'test@test.te', }) @@ -87,7 +90,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().cancelInvite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, inviteUuid: '1-2-3', }) @@ -100,7 +103,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().declineInvite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, inviteUuid: '1-2-3', }) @@ -117,7 +120,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().declineInvite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, inviteUuid: '1-2-3', }) @@ -134,7 +137,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().acceptInvite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, inviteUuid: '1-2-3', }) @@ -151,7 +154,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().acceptInvite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, inviteUuid: '1-2-3', }) @@ -168,7 +171,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().invite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, identifier: 'invitee@test.te', inviterUuid: '1-2-3', inviterEmail: 'test@test.te', @@ -187,7 +190,7 @@ describe('SubscriptionInvitesController', () => { it('should not invite to user subscription if the identifier is missing in request', async () => { const result = await createController().invite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, identifier: '', inviterUuid: '1-2-3', inviterEmail: 'test@test.te', @@ -205,7 +208,7 @@ describe('SubscriptionInvitesController', () => { }) const result = await createController().invite({ - api: ApiVersion.v20200115, + api: ApiVersion.VERSIONS.v20200115, identifier: 'invitee@test.te', inviterUuid: '1-2-3', inviterEmail: 'test@test.te', diff --git a/packages/auth/src/Domain/Api/ApiVersion.spec.ts b/packages/auth/src/Domain/Api/ApiVersion.spec.ts new file mode 100644 index 000000000..7e5345a39 --- /dev/null +++ b/packages/auth/src/Domain/Api/ApiVersion.spec.ts @@ -0,0 +1,46 @@ +import { ApiVersion } from './ApiVersion' + +describe('ApiVersion', () => { + it('should create a value object', () => { + const valueOrError = ApiVersion.create(ApiVersion.VERSIONS.v20200115) + + expect(valueOrError.isFailed()).toBeFalsy() + expect(valueOrError.getValue().value).toEqual('20200115') + }) + + it('should not create an invalid value object', () => { + for (const value of ['', undefined, null, 0, 'SOME_VERSION']) { + const valueOrError = ApiVersion.create(value as string) + + expect(valueOrError.isFailed()).toBeTruthy() + } + }) + + it('should tell if the version is supported for registration', () => { + const version = ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue() + + expect(version.isSupportedForRegistration()).toBeTruthy() + + const version2 = ApiVersion.create(ApiVersion.VERSIONS.v20240226).getValue() + + expect(version2.isSupportedForRegistration()).toBeTruthy() + + const version3 = ApiVersion.create(ApiVersion.VERSIONS.v20161215).getValue() + + expect(version3.isSupportedForRegistration()).toBeFalsy() + }) + + it('should tell if the version is supported for recovery sign in', () => { + const version = ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue() + + expect(version.isSupportedForRecoverySignIn()).toBeTruthy() + + const version2 = ApiVersion.create(ApiVersion.VERSIONS.v20240226).getValue() + + expect(version2.isSupportedForRecoverySignIn()).toBeTruthy() + + const version3 = ApiVersion.create(ApiVersion.VERSIONS.v20161215).getValue() + + expect(version3.isSupportedForRecoverySignIn()).toBeFalsy() + }) +}) diff --git a/packages/auth/src/Domain/Api/ApiVersion.ts b/packages/auth/src/Domain/Api/ApiVersion.ts index 90d2a9f0b..be804f341 100644 --- a/packages/auth/src/Domain/Api/ApiVersion.ts +++ b/packages/auth/src/Domain/Api/ApiVersion.ts @@ -1,6 +1,37 @@ -export enum ApiVersion { - v20161215 = '20161215', - v20190520 = '20190520', - v20200115 = '20200115', - v20240226 = '20240226', +import { Result, ValueObject } from '@standardnotes/domain-core' + +import { ApiVersionProps } from './ApiVersionProps' + +export class ApiVersion extends ValueObject { + static readonly VERSIONS = { + v20161215: '20161215', + v20190520: '20190520', + v20200115: '20200115', + v20240226: '20240226', + } + + get value(): string { + return this.props.value + } + + private constructor(props: ApiVersionProps) { + super(props) + } + + static create(version: string): Result { + const isValidVersion = Object.values(this.VERSIONS).includes(version) + if (!isValidVersion) { + return Result.fail(`Invalid api version: ${version}`) + } else { + return Result.ok(new ApiVersion({ value: version })) + } + } + + isSupportedForRegistration(): boolean { + return [ApiVersion.VERSIONS.v20200115, ApiVersion.VERSIONS.v20240226].includes(this.props.value) + } + + isSupportedForRecoverySignIn(): boolean { + return [ApiVersion.VERSIONS.v20200115, ApiVersion.VERSIONS.v20240226].includes(this.props.value) + } } diff --git a/packages/auth/src/Domain/Api/ApiVersionProps.ts b/packages/auth/src/Domain/Api/ApiVersionProps.ts new file mode 100644 index 000000000..0b211eaf0 --- /dev/null +++ b/packages/auth/src/Domain/Api/ApiVersionProps.ts @@ -0,0 +1,3 @@ +export interface ApiVersionProps { + value: string +} diff --git a/packages/auth/src/Domain/Auth/AuthResponse20200115.ts b/packages/auth/src/Domain/Auth/AuthResponse20200115.ts index 3efdd1a78..9ded0462f 100644 --- a/packages/auth/src/Domain/Auth/AuthResponse20200115.ts +++ b/packages/auth/src/Domain/Auth/AuthResponse20200115.ts @@ -3,6 +3,6 @@ import { KeyParamsData, SessionBody } from '@standardnotes/responses' import { AuthResponse } from './AuthResponse' export interface AuthResponse20200115 extends AuthResponse { - session: SessionBody - key_params: KeyParamsData + sessionBody: SessionBody + keyParams: KeyParamsData } diff --git a/packages/auth/src/Domain/Auth/AuthResponseCreationResult.ts b/packages/auth/src/Domain/Auth/AuthResponseCreationResult.ts new file mode 100644 index 000000000..43aaffddc --- /dev/null +++ b/packages/auth/src/Domain/Auth/AuthResponseCreationResult.ts @@ -0,0 +1,10 @@ +import { Session } from '../Session/Session' +import { AuthResponse20161215 } from './AuthResponse20161215' +import { AuthResponse20200115 } from './AuthResponse20200115' + +export interface AuthResponseCreationResult { + response?: AuthResponse20200115 + legacyResponse?: AuthResponse20161215 + session?: Session + cookies?: { accessToken: string; refreshToken: string } +} diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.spec.ts b/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.spec.ts index a2f855c08..433d7a4e2 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.spec.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.spec.ts @@ -6,6 +6,7 @@ import { Logger } from 'winston' import { ProjectorInterface } from '../../Projection/ProjectorInterface' import { User } from '../User/User' import { AuthResponseFactory20161215 } from './AuthResponseFactory20161215' +import { ApiVersion } from '../Api/ApiVersion' describe('AuthResponseFactory20161215', () => { let userProjector: ProjectorInterface @@ -32,13 +33,13 @@ describe('AuthResponseFactory20161215', () => { it('should create a 20161215 auth response', async () => { const result = await createFactory().createResponse({ user, - apiVersion: '20161215', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20161215).getValue(), userAgent: 'Google Chrome', ephemeralSession: false, readonlyAccess: false, }) - expect(result.response).toEqual({ + expect(result.legacyResponse).toEqual({ user: { foo: 'bar' }, token: 'foobar', }) diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.ts b/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.ts index 80710b0ed..a44266c72 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactory20161215.ts @@ -8,10 +8,9 @@ import TYPES from '../../Bootstrap/Types' import { ProjectorInterface } from '../../Projection/ProjectorInterface' import { User } from '../User/User' -import { AuthResponse20161215 } from './AuthResponse20161215' -import { AuthResponse20200115 } from './AuthResponse20200115' import { AuthResponseFactoryInterface } from './AuthResponseFactoryInterface' -import { Session } from '../Session/Session' +import { AuthResponseCreationResult } from './AuthResponseCreationResult' +import { ApiVersion } from '../Api/ApiVersion' @injectable() export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface { @@ -23,11 +22,13 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface async createResponse(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string ephemeralSession: boolean readonlyAccess: boolean - }): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> { + snjs?: string + application?: string + }): Promise { this.logger.debug(`Creating JWT auth response for user ${dto.user.uuid}`) const data: SessionTokenData = { @@ -40,7 +41,7 @@ export class AuthResponseFactory20161215 implements AuthResponseFactoryInterface this.logger.debug(`Created JWT token for user ${dto.user.uuid}: ${token}`) return { - response: { + legacyResponse: { user: this.userProjector.projectSimple(dto.user) as { uuid: string email: string diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactory20190520.spec.ts b/packages/auth/src/Domain/Auth/AuthResponseFactory20190520.spec.ts index 1e9344d6e..86641b47e 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactory20190520.spec.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactory20190520.spec.ts @@ -5,6 +5,7 @@ import { Logger } from 'winston' import { ProjectorInterface } from '../../Projection/ProjectorInterface' import { User } from '../User/User' import { AuthResponseFactory20190520 } from './AuthResponseFactory20190520' +import { ApiVersion } from '../Api/ApiVersion' describe('AuthResponseFactory20190520', () => { let userProjector: ProjectorInterface @@ -31,13 +32,13 @@ describe('AuthResponseFactory20190520', () => { it('should create a 20161215 auth response', async () => { const result = await createFactory().createResponse({ user, - apiVersion: '20161215', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20161215).getValue(), userAgent: 'Google Chrome', ephemeralSession: false, readonlyAccess: false, }) - expect(result.response).toEqual({ + expect(result.legacyResponse).toEqual({ user: { foo: 'bar' }, token: 'foobar', }) diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.spec.ts b/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.spec.ts index f6e1b030e..2b08c36e2 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.spec.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.spec.ts @@ -12,6 +12,7 @@ import { AuthResponseFactory20200115 } from './AuthResponseFactory20200115' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' import { Session } from '../Session/Session' +import { ApiVersion } from '../Api/ApiVersion' describe('AuthResponseFactory20200115', () => { let sessionService: SessionServiceInterface @@ -51,10 +52,10 @@ describe('AuthResponseFactory20200115', () => { sessionService = {} as jest.Mocked sessionService.createNewSessionForUser = jest .fn() - .mockReturnValue({ sessionHttpRepresentation: sessionPayload, session: {} as jest.Mocked }) + .mockReturnValue({ sessionHttpRepresentation: sessionPayload, sessionBody: {} as jest.Mocked }) sessionService.createNewEphemeralSessionForUser = jest .fn() - .mockReturnValue({ sessionHttpRepresentation: sessionPayload, session: {} as jest.Mocked }) + .mockReturnValue({ sessionHttpRepresentation: sessionPayload, sessionBody: {} as jest.Mocked }) keyParamsFactory = {} as jest.Mocked keyParamsFactory.create = jest.fn().mockReturnValue({ @@ -83,13 +84,13 @@ describe('AuthResponseFactory20200115', () => { const result = await createFactory().createResponse({ user, - apiVersion: '20161215', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20161215).getValue(), userAgent: 'Google Chrome', ephemeralSession: false, readonlyAccess: false, }) - expect(result.response).toEqual({ + expect(result.legacyResponse).toEqual({ user: { foo: 'bar' }, token: expect.any(String), }) @@ -100,18 +101,18 @@ describe('AuthResponseFactory20200115', () => { const result = await createFactory().createResponse({ user, - apiVersion: '20200115', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', ephemeralSession: false, readonlyAccess: false, }) expect(result.response).toEqual({ - key_params: { + keyParams: { key1: 'value1', key2: 'value2', }, - session: { + sessionBody: { access_token: 'access_token', refresh_token: 'refresh_token', access_expiration: 123, @@ -131,18 +132,18 @@ describe('AuthResponseFactory20200115', () => { const result = await createFactory().createResponse({ user, - apiVersion: '20200115', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', ephemeralSession: false, readonlyAccess: false, }) expect(result.response).toEqual({ - key_params: { + keyParams: { key1: 'value1', key2: 'value2', }, - session: { + sessionBody: { access_token: 'access_token', refresh_token: 'refresh_token', access_expiration: 123, @@ -160,18 +161,18 @@ describe('AuthResponseFactory20200115', () => { const result = await createFactory().createResponse({ user, - apiVersion: '20200115', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', ephemeralSession: true, readonlyAccess: false, }) expect(result.response).toEqual({ - key_params: { + keyParams: { key1: 'value1', key2: 'value2', }, - session: { + sessionBody: { access_token: 'access_token', refresh_token: 'refresh_token', access_expiration: 123, @@ -192,23 +193,23 @@ describe('AuthResponseFactory20200115', () => { ...sessionPayload, readonly_access: true, }, - session: {} as jest.Mocked, + sessionBody: {} as jest.Mocked, }) const result = await createFactory().createResponse({ user, - apiVersion: '20200115', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', ephemeralSession: false, readonlyAccess: true, }) expect(result.response).toEqual({ - key_params: { + keyParams: { key1: 'value1', key2: 'value2', }, - session: { + sessionBody: { access_token: 'access_token', refresh_token: 'refresh_token', access_expiration: 123, diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.ts b/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.ts index aca69c781..5682c2fc7 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactory20200115.ts @@ -4,7 +4,6 @@ import { TokenEncoderInterface, } from '@standardnotes/security' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' -import { SessionBody } from '@standardnotes/responses' import { inject, injectable } from 'inversify' import { Logger } from 'winston' @@ -17,9 +16,9 @@ import { User } from '../User/User' import { AuthResponseFactory20190520 } from './AuthResponseFactory20190520' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' -import { AuthResponse20161215 } from './AuthResponse20161215' -import { AuthResponse20200115 } from './AuthResponse20200115' -import { Session } from '../Session/Session' +import { SessionCreationResult } from '../Session/SessionCreationResult' +import { AuthResponseCreationResult } from './AuthResponseCreationResult' +import { ApiVersion } from '../Api/ApiVersion' @injectable() export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 { @@ -37,11 +36,13 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 { override async createResponse(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string ephemeralSession: boolean readonlyAccess: boolean - }): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> { + snjs?: string + application?: string + }): Promise { if (!dto.user.supportsSessions()) { this.logger.debug(`User ${dto.user.uuid} does not support sessions. Falling back to JWT auth response`) @@ -50,29 +51,31 @@ export class AuthResponseFactory20200115 extends AuthResponseFactory20190520 { const sessionCreationResult = await this.createSession(dto) - this.logger.debug( - 'Created session payload for user %s: %O', - dto.user.uuid, - sessionCreationResult.sessionHttpRepresentation, - ) + this.logger.debug('Created session payload for user', { + userId: dto.user.uuid, + session: sessionCreationResult, + }) return { response: { - session: sessionCreationResult.sessionHttpRepresentation, - key_params: this.keyParamsFactory.create(dto.user, true), + sessionBody: sessionCreationResult.sessionHttpRepresentation, + keyParams: this.keyParamsFactory.create(dto.user, true), user: this.userProjector.projectSimple(dto.user) as SimpleUserProjection, }, session: sessionCreationResult.session, + cookies: sessionCreationResult.sessionCookieRepresentation, } } private async createSession(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string ephemeralSession: boolean readonlyAccess: boolean - }): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> { + snjs?: string + application?: string + }): Promise { if (dto.ephemeralSession) { return this.sessionService.createNewEphemeralSessionForUser(dto) } diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactoryInterface.ts b/packages/auth/src/Domain/Auth/AuthResponseFactoryInterface.ts index 25c64e0cf..611223c98 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactoryInterface.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactoryInterface.ts @@ -1,14 +1,15 @@ -import { Session } from '../Session/Session' +import { ApiVersion } from '../Api/ApiVersion' import { User } from '../User/User' -import { AuthResponse20161215 } from './AuthResponse20161215' -import { AuthResponse20200115 } from './AuthResponse20200115' +import { AuthResponseCreationResult } from './AuthResponseCreationResult' export interface AuthResponseFactoryInterface { createResponse(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string ephemeralSession: boolean readonlyAccess: boolean - }): Promise<{ response: AuthResponse20161215 | AuthResponse20200115; session?: Session }> + snjs?: string + application?: string + }): Promise } diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.spec.ts b/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.spec.ts index 08f446859..97a12adba 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.spec.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.spec.ts @@ -5,6 +5,7 @@ import { AuthResponseFactory20161215 } from './AuthResponseFactory20161215' import { AuthResponseFactory20190520 } from './AuthResponseFactory20190520' import { AuthResponseFactory20200115 } from './AuthResponseFactory20200115' import { AuthResponseFactoryResolver } from './AuthResponseFactoryResolver' +import { ApiVersion } from '../Api/ApiVersion' describe('AuthResponseFactoryResolver', () => { let authResponseFactory20161215: AuthResponseFactory20161215 @@ -30,18 +31,26 @@ describe('AuthResponseFactoryResolver', () => { }) it('should resolve 2016 response factory', () => { - expect(createResolver().resolveAuthResponseFactoryVersion('20161215')).toEqual(authResponseFactory20161215) + expect( + createResolver().resolveAuthResponseFactoryVersion(ApiVersion.create(ApiVersion.VERSIONS.v20161215).getValue()), + ).toEqual(authResponseFactory20161215) }) it('should resolve 2019 response factory', () => { - expect(createResolver().resolveAuthResponseFactoryVersion('20190520')).toEqual(authResponseFactory20190520) + expect( + createResolver().resolveAuthResponseFactoryVersion(ApiVersion.create(ApiVersion.VERSIONS.v20190520).getValue()), + ).toEqual(authResponseFactory20190520) }) it('should resolve 2020 response factory', () => { - expect(createResolver().resolveAuthResponseFactoryVersion('20200115')).toEqual(authResponseFactory20200115) + expect( + createResolver().resolveAuthResponseFactoryVersion(ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue()), + ).toEqual(authResponseFactory20200115) }) - it('should resolve 2016 response factory as default', () => { - expect(createResolver().resolveAuthResponseFactoryVersion('')).toEqual(authResponseFactory20161215) + it('should resolve 2024 response factory', () => { + expect( + createResolver().resolveAuthResponseFactoryVersion(ApiVersion.create(ApiVersion.VERSIONS.v20240226).getValue()), + ).toEqual(authResponseFactory20200115) }) }) diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.ts b/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.ts index 29a079f39..67d0ffca2 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactoryResolver.ts @@ -17,14 +17,14 @@ export class AuthResponseFactoryResolver implements AuthResponseFactoryResolverI @inject(TYPES.Auth_Logger) private logger: Logger, ) {} - resolveAuthResponseFactoryVersion(apiVersion: string): AuthResponseFactoryInterface { - this.logger.debug(`Resolving auth response factory for api version: ${apiVersion}`) + resolveAuthResponseFactoryVersion(apiVersion: ApiVersion): AuthResponseFactoryInterface { + this.logger.debug(`Resolving auth response factory for api version: ${apiVersion.value}`) - switch (apiVersion) { - case ApiVersion.v20190520: + switch (apiVersion.value) { + case ApiVersion.VERSIONS.v20190520: return this.authResponseFactory20190520 - case ApiVersion.v20200115: - case ApiVersion.v20240226: + case ApiVersion.VERSIONS.v20200115: + case ApiVersion.VERSIONS.v20240226: return this.authResponseFactory20200115 default: return this.authResponseFactory20161215 diff --git a/packages/auth/src/Domain/Auth/AuthResponseFactoryResolverInterface.ts b/packages/auth/src/Domain/Auth/AuthResponseFactoryResolverInterface.ts index 3663288aa..7baded09b 100644 --- a/packages/auth/src/Domain/Auth/AuthResponseFactoryResolverInterface.ts +++ b/packages/auth/src/Domain/Auth/AuthResponseFactoryResolverInterface.ts @@ -1,5 +1,6 @@ +import { ApiVersion } from '../Api/ApiVersion' import { AuthResponseFactoryInterface } from './AuthResponseFactoryInterface' export interface AuthResponseFactoryResolverInterface { - resolveAuthResponseFactoryVersion(apiVersion: string): AuthResponseFactoryInterface + resolveAuthResponseFactoryVersion(apiVersion: ApiVersion): AuthResponseFactoryInterface } diff --git a/packages/auth/src/Domain/Auth/AuthenticationMethod.ts b/packages/auth/src/Domain/Auth/AuthenticationMethod.ts index 627174847..f493d3f98 100644 --- a/packages/auth/src/Domain/Auth/AuthenticationMethod.ts +++ b/packages/auth/src/Domain/Auth/AuthenticationMethod.ts @@ -7,5 +7,6 @@ export type AuthenticationMethod = { user: User | null claims?: Record session?: Session + givenTokensWereInCooldown?: boolean revokedSession?: RevokedSession } diff --git a/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.spec.ts b/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.spec.ts index 68f98ebc5..63211901d 100644 --- a/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.spec.ts +++ b/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.spec.ts @@ -10,19 +10,29 @@ import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { AuthenticationMethodResolver } from './AuthenticationMethodResolver' import { Logger } from 'winston' +import { GetSessionFromToken } from '../UseCase/GetSessionFromToken/GetSessionFromToken' +import { Result } from '@standardnotes/domain-core' describe('AuthenticationMethodResolver', () => { let userRepository: UserRepositoryInterface let sessionService: SessionServiceInterface let sessionTokenDecoder: TokenDecoderInterface let fallbackTokenDecoder: TokenDecoderInterface + let getSessionFromToken: GetSessionFromToken let user: User let session: Session let revokedSession: RevokedSession let logger: Logger const createResolver = () => - new AuthenticationMethodResolver(userRepository, sessionService, sessionTokenDecoder, fallbackTokenDecoder, logger) + new AuthenticationMethodResolver( + userRepository, + sessionService, + sessionTokenDecoder, + fallbackTokenDecoder, + getSessionFromToken, + logger, + ) beforeEach(() => { logger = {} as jest.Mocked @@ -41,10 +51,12 @@ describe('AuthenticationMethodResolver', () => { userRepository.findOneByUuid = jest.fn().mockReturnValue(user) sessionService = {} as jest.Mocked - sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session: undefined, isEphemeral: false }) sessionService.getRevokedSessionFromToken = jest.fn() sessionService.markRevokedSessionAsReceived = jest.fn().mockReturnValue(revokedSession) + getSessionFromToken = {} as jest.Mocked + getSessionFromToken.execute = jest.fn().mockReturnValue(Result.fail('No session found.')) + sessionTokenDecoder = {} as jest.Mocked> sessionTokenDecoder.decodeToken = jest.fn() @@ -55,7 +67,12 @@ describe('AuthenticationMethodResolver', () => { it('should resolve jwt authentication method', async () => { sessionTokenDecoder.decodeToken = jest.fn().mockReturnValue({ user_uuid: '00000000-0000-0000-0000-000000000000' }) - expect(await createResolver().resolve('test')).toEqual({ + expect( + await createResolver().resolve({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }), + ).toEqual({ claims: { user_uuid: '00000000-0000-0000-0000-000000000000', }, @@ -67,31 +84,56 @@ describe('AuthenticationMethodResolver', () => { it('should not resolve jwt authentication method with invalid user uuid', async () => { sessionTokenDecoder.decodeToken = jest.fn().mockReturnValue({ user_uuid: 'invalid' }) - expect(await createResolver().resolve('test')).toBeUndefined + expect( + await createResolver().resolve({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }), + ).toBeUndefined }) it('should resolve session authentication method', async () => { - sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session, isEphemeral: false }) + getSessionFromToken.execute = jest + .fn() + .mockReturnValue(Result.ok({ session, isEphemeral: false, givenTokensWereInCooldown: false })) - expect(await createResolver().resolve('test')).toEqual({ + expect( + await createResolver().resolve({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }), + ).toEqual({ session, type: 'session_token', user, + givenTokensWereInCooldown: false, }) }) it('should not resolve session authentication method with invalid user uuid on session', async () => { - sessionService.getSessionFromToken = jest + getSessionFromToken.execute = jest .fn() - .mockReturnValue({ session: { userUuid: 'invalid' }, isEphemeral: false }) + .mockReturnValue( + Result.ok({ session: { userUuid: 'invalid' }, isEphemeral: false, givenTokensWereInCooldown: false }), + ) - expect(await createResolver().resolve('test')).toBeUndefined + expect( + await createResolver().resolve({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }), + ).toBeUndefined }) it('should resolve archvied session authentication method', async () => { sessionService.getRevokedSessionFromToken = jest.fn().mockReturnValue(revokedSession) - expect(await createResolver().resolve('test')).toEqual({ + expect( + await createResolver().resolve({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }), + ).toEqual({ revokedSession, type: 'revoked', user: null, @@ -101,6 +143,11 @@ describe('AuthenticationMethodResolver', () => { }) it('should indicated that authentication method cannot be resolved', async () => { - expect(await createResolver().resolve('test')).toBeUndefined + expect( + await createResolver().resolve({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }), + ).toBeUndefined }) }) diff --git a/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.ts b/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.ts index 3b231fb00..35fca409a 100644 --- a/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.ts +++ b/packages/auth/src/Domain/Auth/AuthenticationMethodResolver.ts @@ -1,30 +1,39 @@ import { SessionTokenData, TokenDecoderInterface } from '@standardnotes/security' -import { inject, injectable } from 'inversify' -import TYPES from '../../Bootstrap/Types' import { SessionServiceInterface } from '../Session/SessionServiceInterface' import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { AuthenticationMethod } from './AuthenticationMethod' import { AuthenticationMethodResolverInterface } from './AuthenticationMethodResolverInterface' import { Logger } from 'winston' import { Uuid } from '@standardnotes/domain-core' +import { GetSessionFromToken } from '../UseCase/GetSessionFromToken/GetSessionFromToken' -@injectable() export class AuthenticationMethodResolver implements AuthenticationMethodResolverInterface { constructor( - @inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface, - @inject(TYPES.Auth_SessionService) private sessionService: SessionServiceInterface, - @inject(TYPES.Auth_SessionTokenDecoder) private sessionTokenDecoder: TokenDecoderInterface, - @inject(TYPES.Auth_FallbackSessionTokenDecoder) + private userRepository: UserRepositoryInterface, + private sessionService: SessionServiceInterface, + private sessionTokenDecoder: TokenDecoderInterface, private fallbackSessionTokenDecoder: TokenDecoderInterface, - @inject(TYPES.Auth_Logger) private logger: Logger, + private getSessionFromToken: GetSessionFromToken, + private logger: Logger, ) {} - async resolve(token: string): Promise { - let decodedToken: SessionTokenData | undefined = this.sessionTokenDecoder.decodeToken(token) + async resolve(dto: { + authTokenFromHeaders: string + authCookies?: Map + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } + }): Promise { + let decodedToken: SessionTokenData | undefined = this.sessionTokenDecoder.decodeToken(dto.authTokenFromHeaders) if (decodedToken === undefined) { this.logger.debug('Could not decode token with primary decoder, trying fallback decoder.') - decodedToken = this.fallbackSessionTokenDecoder.decodeToken(token) + decodedToken = this.fallbackSessionTokenDecoder.decodeToken(dto.authTokenFromHeaders) } if (decodedToken) { @@ -47,8 +56,10 @@ export class AuthenticationMethodResolver implements AuthenticationMethodResolve } } - const { session } = await this.sessionService.getSessionFromToken(token) - if (session) { + const resultOrError = await this.getSessionFromToken.execute(dto) + if (!resultOrError.isFailed()) { + const { session, givenTokensWereInCooldown } = resultOrError.getValue() + this.logger.debug('Token decoded successfully. Session found.') const userUuidOrError = Uuid.create(session.userUuid) @@ -61,10 +72,11 @@ export class AuthenticationMethodResolver implements AuthenticationMethodResolve type: 'session_token', user: await this.userRepository.findOneByUuid(userUuid), session: session, + givenTokensWereInCooldown: givenTokensWereInCooldown, } } - const revokedSession = await this.sessionService.getRevokedSessionFromToken(token) + const revokedSession = await this.sessionService.getRevokedSessionFromToken(dto.authTokenFromHeaders) if (revokedSession) { this.logger.debug('Token decoded successfully. Revoked session found.') diff --git a/packages/auth/src/Domain/Auth/AuthenticationMethodResolverInterface.ts b/packages/auth/src/Domain/Auth/AuthenticationMethodResolverInterface.ts index d36fff1dd..e4212a350 100644 --- a/packages/auth/src/Domain/Auth/AuthenticationMethodResolverInterface.ts +++ b/packages/auth/src/Domain/Auth/AuthenticationMethodResolverInterface.ts @@ -1,5 +1,16 @@ import { AuthenticationMethod } from './AuthenticationMethod' export interface AuthenticationMethodResolverInterface { - resolve(token: string): Promise + resolve(dto: { + authTokenFromHeaders: string + authCookies?: Map + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } + }): Promise } diff --git a/packages/auth/src/Domain/Auth/Cookies/CookieFactory.ts b/packages/auth/src/Domain/Auth/Cookies/CookieFactory.ts new file mode 100644 index 000000000..5ce2dcc38 --- /dev/null +++ b/packages/auth/src/Domain/Auth/Cookies/CookieFactory.ts @@ -0,0 +1,28 @@ +import { CookieFactoryInterface } from './CookieFactoryInterface' + +export class CookieFactory implements CookieFactoryInterface { + constructor( + private sameSite: 'None' | 'Lax' | 'Strict', + private domain: string, + private secure: boolean, + private partitioned: boolean, + ) {} + + createCookieHeaderValue(dto: { + sessionUuid: string + accessToken: string + refreshToken: string + refreshTokenExpiration: Date + }): string[] { + return [ + `access_token_${dto.sessionUuid}=${dto.accessToken}; HttpOnly;${this.secure ? 'Secure; ' : ' '}Path=/;${ + this.partitioned ? 'Partitioned; ' : ' ' + }SameSite=${this.sameSite}; Domain=${this.domain}; Expires=${dto.refreshTokenExpiration.toUTCString()};`, + `refresh_token_${dto.sessionUuid}=${dto.refreshToken}; HttpOnly;${ + this.secure ? 'Secure; ' : ' ' + }Path=/v1/sessions/refresh;${this.partitioned ? 'Partitioned; ' : ' '}SameSite=${this.sameSite}; Domain=${ + this.domain + }; Expires=${dto.refreshTokenExpiration.toUTCString()};`, + ] + } +} diff --git a/packages/auth/src/Domain/Auth/Cookies/CookieFactoryInterface.ts b/packages/auth/src/Domain/Auth/Cookies/CookieFactoryInterface.ts new file mode 100644 index 000000000..f42a91681 --- /dev/null +++ b/packages/auth/src/Domain/Auth/Cookies/CookieFactoryInterface.ts @@ -0,0 +1,8 @@ +export interface CookieFactoryInterface { + createCookieHeaderValue(dto: { + sessionUuid: string + accessToken: string + refreshToken: string + refreshTokenExpiration: Date + }): string[] +} diff --git a/packages/auth/src/Domain/Event/DomainEventFactory.ts b/packages/auth/src/Domain/Event/DomainEventFactory.ts index 4d3940923..8b5e300b8 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactory.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactory.ts @@ -305,12 +305,7 @@ export class DomainEventFactory implements DomainEventFactoryInterface { } } - createEmailBackupRequestedEvent( - userUuid: string, - muteEmailsSettingUuid: string, - userHasEmailsMuted: boolean, - keyParams: KeyParamsData, - ): EmailBackupRequestedEvent { + createEmailBackupRequestedEvent(userUuid: string, keyParams: KeyParamsData): EmailBackupRequestedEvent { return { type: 'EMAIL_BACKUP_REQUESTED', createdAt: this.timer.getUTCDate(), @@ -323,8 +318,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface { }, payload: { userUuid, - userHasEmailsMuted, - muteEmailsSettingUuid, keyParams, }, } diff --git a/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts b/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts index 693d5b04b..a67283172 100644 --- a/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts +++ b/packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts @@ -43,12 +43,7 @@ export interface DomainEventFactoryInterface { email: string protocolVersion: ProtocolVersion }): UserRegisteredEvent - createEmailBackupRequestedEvent( - userUuid: string, - muteEmailsSettingUuid: string, - userHasEmailsMuted: boolean, - keyParams: KeyParamsData, - ): EmailBackupRequestedEvent + createEmailBackupRequestedEvent(userUuid: string, keyParams: KeyParamsData): EmailBackupRequestedEvent createAccountDeletionRequestedEvent(dto: { userUuid: string email: string diff --git a/packages/auth/src/Domain/HumanVerification/CaptchaServerInterface.ts b/packages/auth/src/Domain/HumanVerification/CaptchaServerInterface.ts new file mode 100644 index 000000000..09879d93b --- /dev/null +++ b/packages/auth/src/Domain/HumanVerification/CaptchaServerInterface.ts @@ -0,0 +1,3 @@ +export interface CaptchaServerInterface { + verify(hvmToken: string): Promise +} diff --git a/packages/auth/src/Domain/Session/EphemeralSessionRepositoryInterface.ts b/packages/auth/src/Domain/Session/EphemeralSessionRepositoryInterface.ts index 276160cec..b01af2e60 100644 --- a/packages/auth/src/Domain/Session/EphemeralSessionRepositoryInterface.ts +++ b/packages/auth/src/Domain/Session/EphemeralSessionRepositoryInterface.ts @@ -2,6 +2,7 @@ import { EphemeralSession } from './EphemeralSession' export interface EphemeralSessionRepositoryInterface { findOneByUuid(uuid: string): Promise + findOneByPrivateIdentifier(privateIdentifier: string): Promise findOneByUuidAndUserUuid(uuid: string, userUuid: string): Promise findAllByUserUuid(userUuid: string): Promise> deleteOne(uuid: string, userUuid: string): Promise diff --git a/packages/auth/src/Domain/Session/RevokedSession.ts b/packages/auth/src/Domain/Session/RevokedSession.ts index 306ff6985..31e230ae2 100644 --- a/packages/auth/src/Domain/Session/RevokedSession.ts +++ b/packages/auth/src/Domain/Session/RevokedSession.ts @@ -6,6 +6,16 @@ export class RevokedSession { @PrimaryGeneratedColumn('uuid') declare uuid: string + @Column({ + name: 'private_identifier', + length: 36, + nullable: true, + type: 'varchar', + comment: 'Used to identify a session without exposing the UUID in client-side cookies.', + }) + @Index('index_revoked_sessions_on_private_identifier') + declare privateIdentifier: string | null + @Column({ name: 'user_uuid', length: 36, diff --git a/packages/auth/src/Domain/Session/RevokedSessionRepositoryInterface.ts b/packages/auth/src/Domain/Session/RevokedSessionRepositoryInterface.ts index 9277bb373..4745e4235 100644 --- a/packages/auth/src/Domain/Session/RevokedSessionRepositoryInterface.ts +++ b/packages/auth/src/Domain/Session/RevokedSessionRepositoryInterface.ts @@ -2,6 +2,7 @@ import { RevokedSession } from './RevokedSession' export interface RevokedSessionRepositoryInterface { findOneByUuid(uuid: string): Promise + findOneByPrivateIdentifier(privateIdentifier: string): Promise findAllByUserUuid(userUuid: string): Promise> insert(revokedSession: RevokedSession): Promise update(revokedSession: RevokedSession): Promise diff --git a/packages/auth/src/Domain/Session/Session.ts b/packages/auth/src/Domain/Session/Session.ts index 3dd5f9da7..9c689c4c3 100644 --- a/packages/auth/src/Domain/Session/Session.ts +++ b/packages/auth/src/Domain/Session/Session.ts @@ -13,6 +13,16 @@ export class Session { @Index('index_sessions_on_user_uuid') declare userUuid: string + @Column({ + name: 'private_identifier', + length: 36, + nullable: true, + type: 'varchar', + comment: 'Used to identify a session without exposing the UUID in client-side cookies.', + }) + @Index('index_sessions_on_private_identifier') + declare privateIdentifier: string | null + @Column({ name: 'hashed_access_token', length: 255, @@ -75,4 +85,28 @@ export class Session { default: 0, }) declare readonlyAccess: boolean + + @Column({ + name: 'version', + type: 'smallint', + nullable: true, + default: 1, + }) + declare version: number | null + + @Column({ + name: 'application', + type: 'varchar', + length: 255, + nullable: true, + }) + declare application: string | null + + @Column({ + name: 'snjs', + type: 'varchar', + length: 255, + nullable: true, + }) + declare snjs: string | null } diff --git a/packages/auth/src/Domain/Session/SessionCreationResult.ts b/packages/auth/src/Domain/Session/SessionCreationResult.ts new file mode 100644 index 000000000..c08870251 --- /dev/null +++ b/packages/auth/src/Domain/Session/SessionCreationResult.ts @@ -0,0 +1,12 @@ +import { SessionBody } from '@standardnotes/responses' + +import { Session } from './Session' + +export interface SessionCreationResult { + sessionHttpRepresentation: SessionBody + sessionCookieRepresentation: { + accessToken: string + refreshToken: string + } + session: Session +} diff --git a/packages/auth/src/Domain/Session/SessionRepositoryInterface.ts b/packages/auth/src/Domain/Session/SessionRepositoryInterface.ts index a75402668..3f563934d 100644 --- a/packages/auth/src/Domain/Session/SessionRepositoryInterface.ts +++ b/packages/auth/src/Domain/Session/SessionRepositoryInterface.ts @@ -4,6 +4,7 @@ import { Session } from './Session' export interface SessionRepositoryInterface { findOneByUuid(uuid: string): Promise + findOneByPrivateIdentifier(privateIdentifier: string): Promise findOneByUuidAndUserUuid(uuid: string, userUuid: string): Promise findAllByRefreshExpirationAndUserUuid(userUuid: string): Promise> findAllByUserUuid(userUuid: string): Promise> diff --git a/packages/auth/src/Domain/Session/SessionService.spec.ts b/packages/auth/src/Domain/Session/SessionService.spec.ts index b5fbf6daf..adec59552 100644 --- a/packages/auth/src/Domain/Session/SessionService.spec.ts +++ b/packages/auth/src/Domain/Session/SessionService.spec.ts @@ -36,7 +36,7 @@ describe('SessionService', () => { let userSubscriptionRepository: UserSubscriptionRepositoryInterface const readonlyUsers = ['demo@standardnotes.com'] - const createService = () => + const createService = (forceLegacySessions = false) => new SessionService( sessionRepository, ephemeralSessionRepository, @@ -51,6 +51,7 @@ describe('SessionService', () => { userSubscriptionRepository, readonlyUsers, getSetting, + forceLegacySessions, ) beforeEach(() => { @@ -58,16 +59,18 @@ describe('SessionService', () => { existingSession.uuid = '2e1e43' existingSession.userUuid = '1-2-3' existingSession.userAgent = 'Chrome' - existingSession.apiVersion = ApiVersion.v20200115 + existingSession.apiVersion = ApiVersion.VERSIONS.v20200115 existingSession.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' existingSession.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' existingSession.readonlyAccess = false + existingSession.version = SessionService.HEADER_BASED_SESSION_VERSION revokedSession = {} as jest.Mocked revokedSession.uuid = '2e1e43' sessionRepository = {} as jest.Mocked sessionRepository.findOneByUuid = jest.fn().mockReturnValue(null) + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockReturnValue(null) sessionRepository.deleteOneByUuid = jest.fn() sessionRepository.insert = jest.fn() sessionRepository.update = jest.fn() @@ -79,6 +82,7 @@ describe('SessionService', () => { ephemeralSessionRepository.insert = jest.fn() ephemeralSessionRepository.update = jest.fn() ephemeralSessionRepository.findOneByUuid = jest.fn() + ephemeralSessionRepository.findOneByPrivateIdentifier = jest.fn() ephemeralSessionRepository.deleteOne = jest.fn() revokedSessionRepository = {} as jest.Mocked @@ -140,25 +144,91 @@ describe('SessionService', () => { }) it('should refresh access and refresh tokens for a session', async () => { - expect(await createService().refreshTokens({ session: existingSession, isEphemeral: false })).toEqual({ - access_expiration: 123, - access_token: expect.any(String), - refresh_token: expect.any(String), - refresh_expiration: 123, - readonly_access: false, + expect( + await createService().refreshTokens({ + session: existingSession, + isEphemeral: false, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), + }), + ).toEqual({ + sessionHttpRepresentation: { + access_expiration: 123, + access_token: expect.any(String), + refresh_token: expect.any(String), + refresh_expiration: 123, + readonly_access: false, + }, + sessionCookieRepresentation: { + accessToken: 'foobar', + refreshToken: 'foobar', + }, + session: existingSession, }) expect(sessionRepository.update).toHaveBeenCalled() expect(ephemeralSessionRepository.update).not.toHaveBeenCalled() }) + it('should refresh access and refresh tokens for a session and turn it into a cookie based session', async () => { + expect( + await createService().refreshTokens({ + session: existingSession, + isEphemeral: false, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20240226).getValue(), + }), + ).toEqual({ + sessionHttpRepresentation: { + access_expiration: 123, + access_token: expect.any(String), + refresh_token: expect.any(String), + refresh_expiration: 123, + readonly_access: false, + }, + sessionCookieRepresentation: { + accessToken: 'foobar', + refreshToken: 'foobar', + }, + session: existingSession, + }) + + expect(sessionRepository.update).toHaveBeenCalledWith({ + apiVersion: ApiVersion.VERSIONS.v20240226, + hashedAccessToken: expect.any(String), + hashedRefreshToken: expect.any(String), + refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), + readonlyAccess: false, + userAgent: 'Chrome', + userUuid: '1-2-3', + uuid: expect.any(String), + version: 2, + accessExpiration: expect.any(Date), + snjs: null, + application: null, + }) + expect(ephemeralSessionRepository.update).not.toHaveBeenCalled() + }) + it('should refresh access and refresh tokens for an ephemeral session', async () => { - expect(await createService().refreshTokens({ session: existingEphemeralSession, isEphemeral: true })).toEqual({ - access_expiration: 123, - access_token: expect.any(String), - refresh_token: expect.any(String), - refresh_expiration: 123, - readonly_access: false, + expect( + await createService().refreshTokens({ + session: existingEphemeralSession, + isEphemeral: true, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), + }), + ).toEqual({ + sessionHttpRepresentation: { + access_expiration: 123, + access_token: expect.any(String), + refresh_token: expect.any(String), + refresh_expiration: 123, + readonly_access: false, + }, + sessionCookieRepresentation: { + accessToken: 'foobar', + refreshToken: 'foobar', + }, + session: existingEphemeralSession, }) expect(sessionRepository.update).not.toHaveBeenCalled() @@ -171,7 +241,7 @@ describe('SessionService', () => { const result = await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -179,16 +249,137 @@ describe('SessionService', () => { expect(sessionRepository.insert).toHaveBeenCalledWith(expect.any(Session)) expect(sessionRepository.insert).toHaveBeenCalledWith({ accessExpiration: expect.any(Date), - apiVersion: '003', + apiVersion: ApiVersion.VERSIONS.v20200115, createdAt: expect.any(Date), hashedAccessToken: expect.any(String), hashedRefreshToken: expect.any(String), refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), + updatedAt: expect.any(Date), + userAgent: 'Google Chrome', + userUuid: '123', + uuid: expect.any(String), + readonlyAccess: false, + version: 1, + snjs: null, + application: null, + }) + + expect(result.sessionHttpRepresentation).toEqual({ + access_expiration: 123, + access_token: expect.any(String), + refresh_expiration: 123, + refresh_token: expect.any(String), + readonly_access: false, + }) + }) + + it('should create new cookie based session for a user', async () => { + const user = {} as jest.Mocked + user.uuid = '123' + + const result = await createService().createNewSessionForUser({ + user, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20240226).getValue(), + userAgent: 'Google Chrome', + readonlyAccess: false, + }) + + expect(sessionRepository.insert).toHaveBeenCalledWith(expect.any(Session)) + expect(sessionRepository.insert).toHaveBeenCalledWith({ + accessExpiration: expect.any(Date), + apiVersion: ApiVersion.VERSIONS.v20240226, + createdAt: expect.any(Date), + hashedAccessToken: expect.any(String), + hashedRefreshToken: expect.any(String), + refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), + updatedAt: expect.any(Date), + userAgent: 'Google Chrome', + userUuid: '123', + uuid: expect.any(String), + readonlyAccess: false, + version: 2, + snjs: null, + application: null, + }) + + expect(result.sessionHttpRepresentation).toEqual({ + access_expiration: 123, + access_token: expect.any(String), + refresh_expiration: 123, + refresh_token: expect.any(String), + readonly_access: false, + }) + }) + + it('should create new legacy session for a user if cookie mode is disabled', async () => { + const user = {} as jest.Mocked + user.uuid = '123' + + const result = await createService(true).createNewSessionForUser({ + user, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20240226).getValue(), + userAgent: 'Google Chrome', + readonlyAccess: false, + }) + + expect(sessionRepository.insert).toHaveBeenCalledWith(expect.any(Session)) + expect(sessionRepository.insert).toHaveBeenCalledWith({ + accessExpiration: expect.any(Date), + apiVersion: ApiVersion.VERSIONS.v20240226, + createdAt: expect.any(Date), + hashedAccessToken: expect.any(String), + hashedRefreshToken: expect.any(String), + refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), + updatedAt: expect.any(Date), + userAgent: 'Google Chrome', + userUuid: '123', + uuid: expect.any(String), + readonlyAccess: false, + version: 1, + snjs: null, + application: null, + }) + + expect(result.sessionHttpRepresentation).toEqual({ + access_expiration: 123, + access_token: expect.any(String), + refresh_expiration: 123, + refresh_token: expect.any(String), + readonly_access: false, + }) + }) + + it('should create new session for a user', async () => { + const user = {} as jest.Mocked + user.uuid = '123' + + const result = await createService().createNewSessionForUser({ + user, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), + userAgent: 'Google Chrome', + readonlyAccess: false, + }) + + expect(sessionRepository.insert).toHaveBeenCalledWith(expect.any(Session)) + expect(sessionRepository.insert).toHaveBeenCalledWith({ + accessExpiration: expect.any(Date), + apiVersion: ApiVersion.VERSIONS.v20200115, + createdAt: expect.any(Date), + hashedAccessToken: expect.any(String), + hashedRefreshToken: expect.any(String), + privateIdentifier: expect.any(String), + refreshExpiration: expect.any(Date), updatedAt: expect.any(Date), userAgent: 'Google Chrome', userUuid: '123', uuid: expect.any(String), readonlyAccess: false, + version: 1, + snjs: null, + application: null, }) expect(result.sessionHttpRepresentation).toEqual({ @@ -207,7 +398,7 @@ describe('SessionService', () => { const result = await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -215,16 +406,20 @@ describe('SessionService', () => { expect(sessionRepository.insert).toHaveBeenCalledWith(expect.any(Session)) expect(sessionRepository.insert).toHaveBeenCalledWith({ accessExpiration: expect.any(Date), - apiVersion: '003', + apiVersion: ApiVersion.VERSIONS.v20200115, createdAt: expect.any(Date), hashedAccessToken: expect.any(String), hashedRefreshToken: expect.any(String), refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), updatedAt: expect.any(Date), userAgent: 'Google Chrome', userUuid: '123', uuid: expect.any(String), readonlyAccess: true, + version: 1, + snjs: null, + application: null, }) expect(result.sessionHttpRepresentation).toEqual({ @@ -249,7 +444,7 @@ describe('SessionService', () => { const result = await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -257,15 +452,19 @@ describe('SessionService', () => { expect(sessionRepository.insert).toHaveBeenCalledWith(expect.any(Session)) expect(sessionRepository.insert).toHaveBeenCalledWith({ accessExpiration: expect.any(Date), - apiVersion: '003', + apiVersion: ApiVersion.VERSIONS.v20200115, createdAt: expect.any(Date), hashedAccessToken: expect.any(String), hashedRefreshToken: expect.any(String), refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), updatedAt: expect.any(Date), userUuid: '123', uuid: expect.any(String), readonlyAccess: false, + version: 1, + snjs: null, + application: null, }) expect(result.sessionHttpRepresentation).toEqual({ @@ -284,7 +483,7 @@ describe('SessionService', () => { await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -304,7 +503,7 @@ describe('SessionService', () => { await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -325,7 +524,7 @@ describe('SessionService', () => { const result = await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -353,7 +552,7 @@ describe('SessionService', () => { const result = await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -381,7 +580,7 @@ describe('SessionService', () => { const result = await createService().createNewSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -406,7 +605,7 @@ describe('SessionService', () => { const result = await createService().createNewEphemeralSessionForUser({ user, - apiVersion: '003', + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), userAgent: 'Google Chrome', readonlyAccess: false, }) @@ -414,16 +613,20 @@ describe('SessionService', () => { expect(ephemeralSessionRepository.insert).toHaveBeenCalledWith(expect.any(EphemeralSession)) expect(ephemeralSessionRepository.insert).toHaveBeenCalledWith({ accessExpiration: expect.any(Date), - apiVersion: '003', + apiVersion: ApiVersion.VERSIONS.v20200115, createdAt: expect.any(Date), hashedAccessToken: expect.any(String), hashedRefreshToken: expect.any(String), refreshExpiration: expect.any(Date), + privateIdentifier: expect.any(String), updatedAt: expect.any(Date), userAgent: 'Google Chrome', userUuid: '123', uuid: expect.any(String), readonlyAccess: false, + version: 1, + snjs: null, + application: null, }) expect(result.sessionHttpRepresentation).toEqual({ @@ -435,57 +638,6 @@ describe('SessionService', () => { }) }) - it('should delete a session by token', async () => { - sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { - if (uuid === '2') { - return existingSession - } - - return null - }) - - await createService().deleteSessionByToken('1:2:3') - - expect(sessionRepository.deleteOneByUuid).toHaveBeenCalledWith('2e1e43') - expect(ephemeralSessionRepository.deleteOne).not.toHaveBeenCalled() - }) - - it('should delete an ephemeral session by token', async () => { - ephemeralSessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { - if (uuid === '2') { - return existingEphemeralSession - } - - return null - }) - - await createService().deleteSessionByToken('1:2:3') - - expect(sessionRepository.deleteOneByUuid).not.toHaveBeenCalled() - expect(ephemeralSessionRepository.deleteOne).toHaveBeenCalledWith('2-3-4', '1-2-3') - }) - - it('should not delete a session by token if session is not found', async () => { - sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { - if (uuid === '2') { - return existingSession - } - - return null - }) - - await createService().deleteSessionByToken('1:4:3') - - expect(sessionRepository.deleteOneByUuid).not.toHaveBeenCalled() - expect(ephemeralSessionRepository.deleteOne).not.toHaveBeenCalled() - }) - - it('should determine if a refresh token is valid', async () => { - expect(createService().isRefreshTokenMatchingHashedSessionToken(existingSession, '1:2:3')).toBeTruthy() - expect(createService().isRefreshTokenMatchingHashedSessionToken(existingSession, '1:2:4')).toBeFalsy() - expect(createService().isRefreshTokenMatchingHashedSessionToken(existingSession, '1:2')).toBeFalsy() - }) - it('should return device info based on user agent', () => { expect(createService().getDeviceInfo(existingSession)).toEqual('Chrome 69.0 on Mac 10.13') }) @@ -626,67 +778,6 @@ describe('SessionService', () => { expect(createService().getDeviceInfo(existingSession)).toEqual('Unknown Client on Unknown OS') }) - it('should retrieve a session from a session token', async () => { - sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { - if (uuid === '2') { - return existingSession - } - - return null - }) - - const { session, isEphemeral } = await createService().getSessionFromToken('1:2:3') - - expect(session).toEqual(session) - expect(isEphemeral).toBeFalsy() - }) - - it('should retrieve an ephemeral session from a session token', async () => { - ephemeralSessionRepository.findOneByUuid = jest.fn().mockReturnValue(existingEphemeralSession) - sessionRepository.findOneByUuid = jest.fn().mockReturnValue(null) - - const { session, isEphemeral } = await createService().getSessionFromToken('1:2:3') - - expect(session).toEqual(existingEphemeralSession) - expect(isEphemeral).toBeTruthy() - }) - - it('should not retrieve a session from a session token that has access token missing', async () => { - sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { - if (uuid === '2') { - return existingSession - } - - return null - }) - - const { session } = await createService().getSessionFromToken('1:2') - - expect(session).toBeUndefined() - }) - - it('should not retrieve a session that is missing', async () => { - sessionRepository.findOneByUuid = jest.fn().mockReturnValue(null) - - const { session } = await createService().getSessionFromToken('1:2:3') - - expect(session).toBeUndefined() - }) - - it('should not retrieve a session from a session token that has invalid access token', async () => { - sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { - if (uuid === '2') { - return existingSession - } - - return null - }) - - const { session } = await createService().getSessionFromToken('1:2:4') - - expect(session).toBeUndefined() - }) - it('should revoked a session', async () => { await createService().createRevokedSession(existingSession) @@ -714,4 +805,26 @@ describe('SessionService', () => { expect(result).toBeNull() }) + + it('should retrieve a revoked cookie session from a session token', async () => { + revokedSessionRepository.findOneByPrivateIdentifier = jest.fn().mockReturnValue(revokedSession) + + const result = await createService().getRevokedSessionFromToken('2:3') + + expect(result).toEqual(revokedSession) + }) + + it('should not retrieve a revoked session if session id is missing from token', async () => { + revokedSessionRepository.findOneByPrivateIdentifier = jest.fn().mockReturnValue(null) + + const result = await createService().getRevokedSessionFromToken('2') + + expect(result).toBeNull() + }) + + it('should not retrieve a revoked session if session token has unrecognizable version', async () => { + const result = await createService().getRevokedSessionFromToken('3:2') + + expect(result).toBeNull() + }) }) diff --git a/packages/auth/src/Domain/Session/SessionService.ts b/packages/auth/src/Domain/Session/SessionService.ts index 5c2c10a99..336dfb0c3 100644 --- a/packages/auth/src/Domain/Session/SessionService.ts +++ b/packages/auth/src/Domain/Session/SessionService.ts @@ -20,9 +20,14 @@ import { RevokedSessionRepositoryInterface } from './RevokedSessionRepositoryInt import { TraceSession } from '../UseCase/TraceSession/TraceSession' import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface' import { GetSetting } from '../UseCase/GetSetting/GetSetting' +import { SessionCreationResult } from './SessionCreationResult' +import { ApiVersion } from '../Api/ApiVersion' export class SessionService implements SessionServiceInterface { static readonly SESSION_TOKEN_VERSION = 1 + static readonly COOKIE_SESSION_TOKEN_VERSION = 2 + static readonly HEADER_BASED_SESSION_VERSION = 1 + static readonly COOKIE_BASED_SESSION_VERSION = 2 constructor( private sessionRepository: SessionRepositoryInterface, @@ -38,20 +43,23 @@ export class SessionService implements SessionServiceInterface { private userSubscriptionRepository: UserSubscriptionRepositoryInterface, private readonlyUsers: string[], private getSetting: GetSetting, + private forceLegacySessions: boolean, ) {} async createNewSessionForUser(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string readonlyAccess: boolean - }): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> { + snjs?: string + application?: string + }): Promise { const session = await this.createSession({ ephemeral: false, ...dto, }) - const sessionPayload = await this.createTokens(session) + const sessionPayload = await this.createTokens(session, dto.apiVersion) await this.sessionRepository.insert(session) @@ -70,34 +78,49 @@ export class SessionService implements SessionServiceInterface { } return { - sessionHttpRepresentation: sessionPayload, + ...sessionPayload, session, } } async createNewEphemeralSessionForUser(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string readonlyAccess: boolean - }): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> { + snjs?: string + application?: string + }): Promise { const ephemeralSession = await this.createSession({ ephemeral: true, ...dto, }) - const sessionPayload = await this.createTokens(ephemeralSession) + const sessionPayload = await this.createTokens(ephemeralSession, dto.apiVersion) await this.ephemeralSessionRepository.insert(ephemeralSession) return { - sessionHttpRepresentation: sessionPayload, + ...sessionPayload, session: ephemeralSession, } } - async refreshTokens(dto: { session: Session; isEphemeral: boolean }): Promise { - const sessionPayload = await this.createTokens(dto.session) + async refreshTokens(dto: { + session: Session + isEphemeral: boolean + apiVersion: ApiVersion + snjs?: string + application?: string + }): Promise { + const sessionPayload = await this.createTokens(dto.session, dto.apiVersion) + + dto.session.apiVersion = dto.apiVersion.value + dto.session.version = this.shouldOperateOnCookieBasedSessions(dto.apiVersion) + ? SessionService.COOKIE_BASED_SESSION_VERSION + : SessionService.HEADER_BASED_SESSION_VERSION + dto.session.snjs = dto.snjs ?? null + dto.session.application = dto.application ?? null if (dto.isEphemeral) { await this.ephemeralSessionRepository.update(dto.session) @@ -105,19 +128,10 @@ export class SessionService implements SessionServiceInterface { await this.sessionRepository.update(dto.session) } - return sessionPayload - } - - isRefreshTokenMatchingHashedSessionToken(session: Session, token: string): boolean { - const tokenParts = token.split(':') - const refreshToken = tokenParts[2] - if (!refreshToken) { - return false + return { + ...sessionPayload, + session: dto.session, } - - const hashedRefreshToken = crypto.createHash('sha256').update(refreshToken).digest('hex') - - return crypto.timingSafeEqual(Buffer.from(hashedRefreshToken), Buffer.from(session.hashedRefreshToken)) } getOperatingSystemInfoFromUserAgent(userAgent: string): string { @@ -182,35 +196,30 @@ export class SessionService implements SessionServiceInterface { return `${browserInfo} on ${osInfo}` } - async getSessionFromToken(token: string): Promise<{ session: Session | undefined; isEphemeral: boolean }> { - const tokenParts = token.split(':') - const sessionUuid = tokenParts[1] - const accessToken = tokenParts[2] - if (!accessToken) { - return { session: undefined, isEphemeral: false } - } - - const { session, isEphemeral } = await this.getSession(sessionUuid) - if (!session) { - return { session: undefined, isEphemeral: false } - } - - const hashedAccessToken = crypto.createHash('sha256').update(accessToken).digest('hex') - if (crypto.timingSafeEqual(Buffer.from(session.hashedAccessToken), Buffer.from(hashedAccessToken))) { - return { session, isEphemeral } - } - - return { session: undefined, isEphemeral: false } - } - async getRevokedSessionFromToken(token: string): Promise { const tokenParts = token.split(':') - const sessionUuid = tokenParts[1] - if (!sessionUuid) { - return null + const tokenVersion = parseInt(tokenParts[0]) + + switch (tokenVersion) { + case SessionService.SESSION_TOKEN_VERSION: { + const sessionUuid = tokenParts[1] + if (!sessionUuid) { + return null + } + + return this.revokedSessionRepository.findOneByUuid(sessionUuid) + } + case SessionService.COOKIE_SESSION_TOKEN_VERSION: { + const privateIdentifier = tokenParts[1] + if (!privateIdentifier) { + return null + } + + return this.revokedSessionRepository.findOneByPrivateIdentifier(privateIdentifier) + } } - return this.revokedSessionRepository.findOneByUuid(sessionUuid) + return null } async markRevokedSessionAsReceived(revokedSession: RevokedSession): Promise { @@ -222,22 +231,6 @@ export class SessionService implements SessionServiceInterface { return revokedSession } - async deleteSessionByToken(token: string): Promise { - const { session, isEphemeral } = await this.getSessionFromToken(token) - - if (session) { - if (isEphemeral) { - await this.ephemeralSessionRepository.deleteOne(session.uuid, session.userUuid) - } else { - await this.sessionRepository.deleteOneByUuid(session.uuid) - } - - return session.userUuid - } - - return null - } - async createRevokedSession(session: Session): Promise { const revokedSession = new RevokedSession() revokedSession.uuid = session.uuid @@ -245,6 +238,7 @@ export class SessionService implements SessionServiceInterface { revokedSession.createdAt = this.timer.getUTCDate() revokedSession.apiVersion = session.apiVersion revokedSession.userAgent = session.userAgent + revokedSession.privateIdentifier = session.privateIdentifier await this.revokedSessionRepository.insert(revokedSession) @@ -253,23 +247,31 @@ export class SessionService implements SessionServiceInterface { private async createSession(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string ephemeral: boolean readonlyAccess: boolean + snjs?: string + application?: string }): Promise { let session = new Session() if (dto.ephemeral) { session = new EphemeralSession() } session.uuid = uuidv4() + session.privateIdentifier = await this.cryptoNode.generateRandomKey(128) if (await this.isLoggingUserAgentEnabledOnSessions(dto.user)) { session.userAgent = dto.userAgent } + session.snjs = dto.snjs ?? null + session.application = dto.application ?? null session.userUuid = dto.user.uuid - session.apiVersion = dto.apiVersion + session.apiVersion = dto.apiVersion.value session.createdAt = this.timer.getUTCDate() session.updatedAt = this.timer.getUTCDate() + session.version = this.shouldOperateOnCookieBasedSessions(dto.apiVersion) + ? SessionService.COOKIE_BASED_SESSION_VERSION + : SessionService.HEADER_BASED_SESSION_VERSION const userIsReadonly = this.readonlyUsers.includes(dto.user.email) session.readonlyAccess = userIsReadonly || dto.readonlyAccess @@ -277,22 +279,16 @@ export class SessionService implements SessionServiceInterface { return session } - private async getSession(uuid: string): Promise<{ - session: Session | null - isEphemeral: boolean - }> { - let session = await this.ephemeralSessionRepository.findOneByUuid(uuid) - let isEphemeral = true - - if (!session) { - session = await this.sessionRepository.findOneByUuid(uuid) - isEphemeral = false + private async createTokens( + session: Session, + apiVersion: ApiVersion, + ): Promise<{ + sessionHttpRepresentation: SessionBody + sessionCookieRepresentation: { + accessToken: string + refreshToken: string } - - return { session, isEphemeral } - } - - private async createTokens(session: Session): Promise { + }> { const accessToken = this.cryptoNode.base64URLEncode(await this.cryptoNode.generateRandomKey(48)) const refreshToken = this.cryptoNode.base64URLEncode(await this.cryptoNode.generateRandomKey(48)) @@ -305,13 +301,29 @@ export class SessionService implements SessionServiceInterface { const refreshTokenExpiration = dayjs.utc().add(this.refreshTokenAge, 'second').toDate() session.accessExpiration = accessTokenExpiration session.refreshExpiration = refreshTokenExpiration + if (!session.privateIdentifier) { + session.privateIdentifier = await this.cryptoNode.generateRandomKey(128) + } + + const accessTokenForHeaderPurposes = this.shouldOperateOnCookieBasedSessions(apiVersion) + ? `${SessionService.COOKIE_SESSION_TOKEN_VERSION}:${session.privateIdentifier}` + : `${SessionService.SESSION_TOKEN_VERSION}:${session.uuid}:${accessToken}` + const refreshTokenForHeaderPurposes = this.shouldOperateOnCookieBasedSessions(apiVersion) + ? `${SessionService.COOKIE_SESSION_TOKEN_VERSION}:${session.privateIdentifier}` + : `${SessionService.SESSION_TOKEN_VERSION}:${session.uuid}:${refreshToken}` return { - access_token: `${SessionService.SESSION_TOKEN_VERSION}:${session.uuid}:${accessToken}`, - refresh_token: `${SessionService.SESSION_TOKEN_VERSION}:${session.uuid}:${refreshToken}`, - access_expiration: this.timer.convertStringDateToMilliseconds(accessTokenExpiration.toString()), - refresh_expiration: this.timer.convertStringDateToMilliseconds(refreshTokenExpiration.toString()), - readonly_access: session.readonlyAccess, + sessionHttpRepresentation: { + access_token: accessTokenForHeaderPurposes, + refresh_token: refreshTokenForHeaderPurposes, + access_expiration: this.timer.convertStringDateToMilliseconds(accessTokenExpiration.toString()), + refresh_expiration: this.timer.convertStringDateToMilliseconds(refreshTokenExpiration.toString()), + readonly_access: session.readonlyAccess, + }, + sessionCookieRepresentation: { + accessToken, + refreshToken, + }, } } @@ -329,4 +341,12 @@ export class SessionService implements SessionServiceInterface { return loggingSetting.decryptedValue === LogSessionUserAgentOption.Enabled } + + private shouldOperateOnCookieBasedSessions(apiVersion: ApiVersion): boolean { + if (this.forceLegacySessions) { + return false + } + + return ApiVersion.VERSIONS.v20240226 === apiVersion.value + } } diff --git a/packages/auth/src/Domain/Session/SessionServiceInterface.ts b/packages/auth/src/Domain/Session/SessionServiceInterface.ts index 1b107c0cd..87c0caa2a 100644 --- a/packages/auth/src/Domain/Session/SessionServiceInterface.ts +++ b/packages/auth/src/Domain/Session/SessionServiceInterface.ts @@ -1,27 +1,35 @@ -import { SessionBody } from '@standardnotes/responses' import { User } from '../User/User' import { RevokedSession } from './RevokedSession' import { Session } from './Session' +import { SessionCreationResult } from './SessionCreationResult' +import { ApiVersion } from '../Api/ApiVersion' export interface SessionServiceInterface { createNewSessionForUser(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string readonlyAccess: boolean - }): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> + snjs?: string + application?: string + }): Promise createNewEphemeralSessionForUser(dto: { user: User - apiVersion: string + apiVersion: ApiVersion userAgent: string readonlyAccess: boolean - }): Promise<{ sessionHttpRepresentation: SessionBody; session: Session }> - refreshTokens(dto: { session: Session; isEphemeral: boolean }): Promise - getSessionFromToken(token: string): Promise<{ session: Session | undefined; isEphemeral: boolean }> + snjs?: string + application?: string + }): Promise + refreshTokens(dto: { + session: Session + isEphemeral: boolean + apiVersion: ApiVersion + snjs?: string + application?: string + }): Promise getRevokedSessionFromToken(token: string): Promise markRevokedSessionAsReceived(revokedSession: RevokedSession): Promise - deleteSessionByToken(token: string): Promise - isRefreshTokenMatchingHashedSessionToken(session: Session, token: string): boolean getDeviceInfo(session: Session): string getOperatingSystemInfoFromUserAgent(userAgent: string): string getBrowserInfoFromUserAgent(userAgent: string): string diff --git a/packages/auth/src/Domain/Session/SessionTokensCooldownRepositoryInterface.ts b/packages/auth/src/Domain/Session/SessionTokensCooldownRepositoryInterface.ts new file mode 100644 index 000000000..1ae0f62ba --- /dev/null +++ b/packages/auth/src/Domain/Session/SessionTokensCooldownRepositoryInterface.ts @@ -0,0 +1,14 @@ +import { Uuid } from '@standardnotes/domain-core' + +export interface SessionTokensCooldownRepositoryInterface { + setCooldown(dto: { + sessionUuid: Uuid + hashedAccessToken: string + hashedRefreshToken: string + cooldownPeriodInSeconds: number + }): Promise + getHashedTokens(sessionUuid: Uuid): Promise<{ + hashedAccessToken: string + hashedRefreshToken: string + } | null> +} diff --git a/packages/auth/src/Domain/Setting/SettingsAssociationService.ts b/packages/auth/src/Domain/Setting/SettingsAssociationService.ts index c1215aa03..8262120b8 100644 --- a/packages/auth/src/Domain/Setting/SettingsAssociationService.ts +++ b/packages/auth/src/Domain/Setting/SettingsAssociationService.ts @@ -12,8 +12,6 @@ import { SettingsAssociationServiceInterface } from './SettingsAssociationServic export class SettingsAssociationService implements SettingsAssociationServiceInterface { private readonly UNENCRYPTED_SETTINGS = [ SettingName.NAMES.EmailBackupFrequency, - SettingName.NAMES.MuteFailedBackupsEmails, - SettingName.NAMES.MuteFailedCloudBackupsEmails, SettingName.NAMES.MuteSignInEmails, SettingName.NAMES.MuteMarketingEmails, SettingName.NAMES.DropboxBackupFrequency, @@ -27,8 +25,6 @@ export class SettingsAssociationService implements SettingsAssociationServiceInt SettingName.NAMES.GoogleDriveBackupFrequency, SettingName.NAMES.OneDriveBackupFrequency, SettingName.NAMES.EmailBackupFrequency, - SettingName.NAMES.MuteFailedBackupsEmails, - SettingName.NAMES.MuteFailedCloudBackupsEmails, SettingName.NAMES.MuteSignInEmails, SettingName.NAMES.MuteMarketingEmails, SettingName.NAMES.ListedAuthorSecrets, diff --git a/packages/auth/src/Domain/UseCase/ApplyDefaultSubscriptionSettings/ApplyDefaultSubscriptionSettings.spec.ts b/packages/auth/src/Domain/UseCase/ApplyDefaultSubscriptionSettings/ApplyDefaultSubscriptionSettings.spec.ts index 3f228f181..742bbb606 100644 --- a/packages/auth/src/Domain/UseCase/ApplyDefaultSubscriptionSettings/ApplyDefaultSubscriptionSettings.spec.ts +++ b/packages/auth/src/Domain/UseCase/ApplyDefaultSubscriptionSettings/ApplyDefaultSubscriptionSettings.spec.ts @@ -136,10 +136,7 @@ describe('ApplyDefaultSubscriptionSettings', () => { .fn() .mockReturnValue( new Map([ - [ - SettingName.NAMES.MuteFailedCloudBackupsEmails, - { value: 'value1', sensitive: false, serverEncryptionVersion: 0 }, - ], + [SettingName.NAMES.LogSessionUserAgent, { value: 'value1', sensitive: false, serverEncryptionVersion: 0 }], ]), ) diff --git a/packages/auth/src/Domain/UseCase/AuthenticateRequest.spec.ts b/packages/auth/src/Domain/UseCase/AuthenticateRequest.spec.ts index a05c48c73..74dac1097 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateRequest.spec.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateRequest.spec.ts @@ -34,7 +34,10 @@ describe('AuthenticateRequest', () => { session, }) - const response = await createUseCase().execute({ authorizationHeader: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeTruthy() expect(response.responseCode).toEqual(200) @@ -43,7 +46,9 @@ describe('AuthenticateRequest', () => { }) it('should not authorize if authorization header is missing', async () => { - const response = await createUseCase().execute({}) + const response = await createUseCase().execute({ + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() expect(response.responseCode).toEqual(401) @@ -55,7 +60,10 @@ describe('AuthenticateRequest', () => { throw new Error('something bad happened') }) - const response = await createUseCase().execute({ authorizationHeader: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() expect(response.responseCode).toEqual(401) @@ -68,7 +76,10 @@ describe('AuthenticateRequest', () => { failureType: 'INVALID_AUTH', }) - const response = await createUseCase().execute({ authorizationHeader: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() expect(response.responseCode).toEqual(401) @@ -81,7 +92,26 @@ describe('AuthenticateRequest', () => { failureType: 'EXPIRED_TOKEN', }) - const response = await createUseCase().execute({ authorizationHeader: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + + expect(response.success).toBeFalsy() + expect(response.responseCode).toEqual(498) + expect(response.errorTag).toEqual('expired-access-token') + }) + + it('should not authorize user if the token is cooled down', async () => { + authenticateUser.execute = jest.fn().mockReturnValue({ + success: false, + failureType: 'COOLEDDOWN_TOKEN', + }) + + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() expect(response.responseCode).toEqual(498) @@ -94,7 +124,10 @@ describe('AuthenticateRequest', () => { failureType: 'REVOKED_SESSION', }) - const response = await createUseCase().execute({ authorizationHeader: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() expect(response.responseCode).toEqual(401) diff --git a/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts b/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts index b6edac68e..98e38fe9e 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateRequest.ts @@ -15,8 +15,8 @@ export class AuthenticateRequest implements UseCaseInterface { ) {} async execute(dto: AuthenticateRequestDTO): Promise { - if (!dto.authorizationHeader) { - this.logger.debug('[authenticate-request] Authorization header not provided.') + if (!dto.authTokenFromHeaders) { + this.logger.debug('[authenticate-request] Authorization not provided.') return { success: false, @@ -29,7 +29,9 @@ export class AuthenticateRequest implements UseCaseInterface { let authenticateResponse: AuthenticateUserResponse try { authenticateResponse = await this.authenticateUser.execute({ - token: dto.authorizationHeader.replace('Bearer ', ''), + authTokenFromHeaders: dto.authTokenFromHeaders, + authCookies: dto.authCookies, + requestMetadata: dto.requestMetadata, }) } catch (error) { this.logger.error( @@ -47,6 +49,7 @@ export class AuthenticateRequest implements UseCaseInterface { if (!authenticateResponse.success) { switch (authenticateResponse.failureType) { case 'EXPIRED_TOKEN': + case 'COOLEDDOWN_TOKEN': return { success: false, responseCode: 498, diff --git a/packages/auth/src/Domain/UseCase/AuthenticateRequestDTO.ts b/packages/auth/src/Domain/UseCase/AuthenticateRequestDTO.ts index b8e7e8211..1375c7cb8 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateRequestDTO.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateRequestDTO.ts @@ -1,3 +1,12 @@ export type AuthenticateRequestDTO = { - authorizationHeader?: string + authTokenFromHeaders?: string + authCookies?: Map + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } } diff --git a/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts b/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts index 2df8ef75d..58d2a9ea1 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateUser.spec.ts @@ -55,7 +55,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeTruthy() }) @@ -71,7 +74,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -84,7 +90,10 @@ describe('AuthenticateUser', () => { }, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -100,7 +109,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -114,11 +126,33 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeTruthy() }) + it('should not authenticate a user from a session token that is in cooldown', async () => { + user.supportsSessions = jest.fn().mockReturnValue(true) + + authenticationMethodResolver.resolve = jest.fn().mockReturnValue({ + type: 'session_token', + session, + user, + givenTokensWereInCooldown: true, + }) + + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + + expect(response.success).toBeFalsy() + expect(response.failureType).toEqual('COOLEDDOWN_TOKEN') + }) + it('should not authenticate a user from a session token if session is expired', async () => { timer.getUTCDate = jest.fn().mockReturnValue(new Date(200)) user.supportsSessions = jest.fn().mockReturnValue(true) @@ -129,7 +163,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -144,7 +181,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -159,7 +199,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -172,7 +215,10 @@ describe('AuthenticateUser', () => { user, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -183,7 +229,10 @@ describe('AuthenticateUser', () => { revokedSession, }) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) @@ -191,7 +240,10 @@ describe('AuthenticateUser', () => { it('should not authenticate a user if authentication method could not be determined', async () => { authenticationMethodResolver.resolve = jest.fn().mockReturnValue(undefined) - const response = await createUseCase().execute({ token: 'test' }) + const response = await createUseCase().execute({ + authTokenFromHeaders: 'test', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) expect(response.success).toBeFalsy() }) diff --git a/packages/auth/src/Domain/UseCase/AuthenticateUser.ts b/packages/auth/src/Domain/UseCase/AuthenticateUser.ts index cab0e4019..2014b23e1 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateUser.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateUser.ts @@ -22,9 +22,9 @@ export class AuthenticateUser implements UseCaseInterface { ) {} async execute(dto: AuthenticateUserDTO): Promise { - const authenticationMethod = await this.authenticationMethodResolver.resolve(dto.token) + const authenticationMethod = await this.authenticationMethodResolver.resolve(dto) if (!authenticationMethod) { - this.logger.debug(`[authenticate-user] No authentication method found for token: ${dto.token}`) + this.logger.debug(`[authenticate-user] No authentication method found for tokens: ${JSON.stringify(dto)}`) return { success: false, @@ -33,7 +33,7 @@ export class AuthenticateUser implements UseCaseInterface { } if (authenticationMethod.type === 'revoked') { - this.logger.debug(`[authenticate-user] Session has been revoked: ${dto.token}`) + this.logger.debug(`[authenticate-user] Session has been revoked: ${dto.authTokenFromHeaders}`) return { success: false, @@ -43,7 +43,7 @@ export class AuthenticateUser implements UseCaseInterface { const user = authenticationMethod.user if (!user) { - this.logger.debug(`[authenticate-user] No user found for authentication method. Token: ${dto.token}`) + this.logger.debug(`[authenticate-user] No user found for authentication method. Token: ${JSON.stringify(dto)}`) return { success: false, @@ -106,6 +106,25 @@ export class AuthenticateUser implements UseCaseInterface { } } + if (authenticationMethod.givenTokensWereInCooldown) { + /* istanbul ignore next */ + this.logger.warn('Request was authenticated with tokens that were in cooldown.', { + userId: user.uuid, + sessionUuid: session.uuid, + snjs: dto.requestMetadata.snjs, + application: dto.requestMetadata.application, + url: dto.requestMetadata.url, + method: dto.requestMetadata.method, + userAgent: session.userAgent, + secChUa: session.userAgent ? dto.requestMetadata.secChUa : undefined, + }) + + return { + success: false, + failureType: 'COOLEDDOWN_TOKEN', + } + } + break } } diff --git a/packages/auth/src/Domain/UseCase/AuthenticateUserDTO.ts b/packages/auth/src/Domain/UseCase/AuthenticateUserDTO.ts index 5b9846a33..618559d73 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateUserDTO.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateUserDTO.ts @@ -1,3 +1,12 @@ export type AuthenticateUserDTO = { - token: string + authTokenFromHeaders: string + authCookies?: Map + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } } diff --git a/packages/auth/src/Domain/UseCase/AuthenticateUserResponse.ts b/packages/auth/src/Domain/UseCase/AuthenticateUserResponse.ts index e9057afcd..047ba7a63 100644 --- a/packages/auth/src/Domain/UseCase/AuthenticateUserResponse.ts +++ b/packages/auth/src/Domain/UseCase/AuthenticateUserResponse.ts @@ -3,7 +3,7 @@ import { User } from '../User/User' export type AuthenticateUserResponse = { success: boolean - failureType?: 'INVALID_AUTH' | 'EXPIRED_TOKEN' | 'REVOKED_SESSION' + failureType?: 'INVALID_AUTH' | 'EXPIRED_TOKEN' | 'REVOKED_SESSION' | 'COOLEDDOWN_TOKEN' user?: User session?: Session } diff --git a/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.spec.ts b/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.spec.ts index 3bfa481f8..9d64145b3 100644 --- a/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.spec.ts +++ b/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.spec.ts @@ -76,7 +76,56 @@ describe('ChangeCredentials', () => { it('should change password', async () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, + currentPassword: 'qweqwe123123', + newPassword: 'test234', + pwNonce: 'asdzxc', + updatedWithUserAgent: 'Google Chrome', + kpCreated: '123', + kpOrigination: 'password-change', + }) + + expect(result.isFailed()).toBeFalsy() + + expect(userRepository.save).toHaveBeenCalledWith({ + encryptedPassword: expect.any(String), + pwNonce: 'asdzxc', + kpCreated: '123', + email: 'test@test.te', + uuid: '1-2-3', + kpOrigination: 'password-change', + updatedAt: new Date(1), + }) + expect(domainEventPublisher.publish).not.toHaveBeenCalled() + expect(domainEventFactory.createUserEmailChangedEvent).not.toHaveBeenCalled() + expect(deleteOtherSessionsForUser.execute).toHaveBeenCalled() + }) + + it('should not change password if api version is invalid', async () => { + const result = await createUseCase().execute({ + username: Username.create('test@test.te').getValue(), + apiVersion: 'invalid', + currentPassword: 'qweqwe123123', + newPassword: 'test234', + pwNonce: 'asdzxc', + updatedWithUserAgent: 'Google Chrome', + kpCreated: '123', + kpOrigination: 'password-change', + }) + + expect(result.isFailed()).toBeTruthy() + }) + + it('should change password on legacy users', async () => { + authResponseFactory.createResponse = jest + .fn() + .mockReturnValue({ legacyResponse: { foo: 'bar' }, session: { uuid: '1-2-3' } as jest.Mocked }) + + authResponseFactoryResolver.resolveAuthResponseFactoryVersion = jest.fn().mockReturnValue(authResponseFactory) + + const result = await createUseCase().execute({ + username: Username.create('test@test.te').getValue(), + apiVersion: ApiVersion.VERSIONS.v20161215, currentPassword: 'qweqwe123123', newPassword: 'test234', pwNonce: 'asdzxc', @@ -106,7 +155,7 @@ describe('ChangeCredentials', () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'test234', newEmail: 'new@test.te', @@ -139,7 +188,7 @@ describe('ChangeCredentials', () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'test234', newEmail: 'new@test.te', @@ -159,7 +208,7 @@ describe('ChangeCredentials', () => { it('should not change email if the new email is invalid', async () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'test234', newEmail: '', @@ -181,7 +230,7 @@ describe('ChangeCredentials', () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'test234', newEmail: '', @@ -202,7 +251,7 @@ describe('ChangeCredentials', () => { it('should not change password if current password is incorrect', async () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'test123', newPassword: 'test234', pwNonce: 'asdzxc', @@ -217,7 +266,7 @@ describe('ChangeCredentials', () => { it('should update protocol version while changing password', async () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'test234', pwNonce: 'asdzxc', @@ -241,7 +290,7 @@ describe('ChangeCredentials', () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'qweqwe123123', newEmail: undefined, @@ -271,7 +320,7 @@ describe('ChangeCredentials', () => { const result = await createUseCase().execute({ username: Username.create('test@test.te').getValue(), - apiVersion: ApiVersion.v20200115, + apiVersion: ApiVersion.VERSIONS.v20200115, currentPassword: 'qweqwe123123', newPassword: 'test234', pwNonce: 'asdzxc', diff --git a/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.ts b/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.ts index bd0dc5c09..3c22b2471 100644 --- a/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.ts +++ b/packages/auth/src/Domain/UseCase/ChangeCredentials/ChangeCredentials.ts @@ -9,13 +9,13 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface' import { ChangeCredentialsDTO } from './ChangeCredentialsDTO' import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface' import { DeleteOtherSessionsForUser } from '../DeleteOtherSessionsForUser' -import { AuthResponse20161215 } from '../../Auth/AuthResponse20161215' -import { AuthResponse20200115 } from '../../Auth/AuthResponse20200115' import { Session } from '../../Session/Session' import { getBody, getSubject } from '../../Email/UserEmailChanged' import { Logger } from 'winston' +import { AuthResponseCreationResult } from '../../Auth/AuthResponseCreationResult' +import { ApiVersion } from '../../Api/ApiVersion' -export class ChangeCredentials implements UseCaseInterface { +export class ChangeCredentials implements UseCaseInterface { constructor( private userRepository: UserRepositoryInterface, private authResponseFactoryResolver: AuthResponseFactoryResolverInterface, @@ -26,7 +26,13 @@ export class ChangeCredentials implements UseCaseInterface> { + async execute(dto: ChangeCredentialsDTO): Promise> { + const apiVersionOrError = ApiVersion.create(dto.apiVersion) + if (apiVersionOrError.isFailed()) { + return Result.fail(apiVersionOrError.getError()) + } + const apiVersion = apiVersionOrError.getValue() + const user = await this.userRepository.findOneByUsernameOrEmail(dto.username) if (!user) { return Result.fail('User not found.') @@ -81,21 +87,23 @@ export class ChangeCredentials implements UseCaseInterface { }) it('should do nothing if a user identifier is invalid', async () => { - expect(await createUseCase().execute({ email: ' ' })).toEqual({ success: false }) + const result = await createUseCase().execute({ email: ' ' }) + + expect(result.isFailed()).toEqual(true) expect(lockRepository.resetLockCounter).toHaveBeenCalledTimes(0) }) it('should unlock an user by email and uuid', async () => { - expect(await createUseCase().execute({ email: 'test@test.te' })).toEqual({ success: true }) + const result = await createUseCase().execute({ email: 'test@test.te' }) + expect(result.isFailed()).toEqual(false) expect(lockRepository.resetLockCounter).toHaveBeenCalledTimes(2) expect(lockRepository.resetLockCounter).toHaveBeenNthCalledWith(1, 'test@test.te') @@ -45,7 +48,8 @@ describe('ClearLoginAttempts', () => { it('should unlock an user by email and uuid if user does not exist', async () => { userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null) - expect(await createUseCase().execute({ email: 'test@test.te' })).toEqual({ success: true }) + const result = await createUseCase().execute({ email: 'test@test.te' }) + expect(result.isFailed()).toEqual(false) expect(lockRepository.resetLockCounter).toHaveBeenCalledTimes(1) expect(lockRepository.resetLockCounter).toHaveBeenCalledWith('test@test.te') diff --git a/packages/auth/src/Domain/UseCase/ClearLoginAttempts.ts b/packages/auth/src/Domain/UseCase/ClearLoginAttempts.ts index e2af712fa..956259264 100644 --- a/packages/auth/src/Domain/UseCase/ClearLoginAttempts.ts +++ b/packages/auth/src/Domain/UseCase/ClearLoginAttempts.ts @@ -1,25 +1,21 @@ -import { Username } from '@standardnotes/domain-core' -import { inject, injectable } from 'inversify' +import { Result, UseCaseInterface, Username } from '@standardnotes/domain-core' import { Logger } from 'winston' -import TYPES from '../../Bootstrap/Types' + import { LockRepositoryInterface } from '../User/LockRepositoryInterface' import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { ClearLoginAttemptsDTO } from './ClearLoginAttemptsDTO' -import { ClearLoginAttemptsResponse } from './ClearLoginAttemptsResponse' -import { UseCaseInterface } from './UseCaseInterface' -@injectable() -export class ClearLoginAttempts implements UseCaseInterface { +export class ClearLoginAttempts implements UseCaseInterface { constructor( - @inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface, - @inject(TYPES.Auth_LockRepository) private lockRepository: LockRepositoryInterface, - @inject(TYPES.Auth_Logger) private logger: Logger, + private userRepository: UserRepositoryInterface, + private lockRepository: LockRepositoryInterface, + private logger: Logger, ) {} - async execute(dto: ClearLoginAttemptsDTO): Promise { + async execute(dto: ClearLoginAttemptsDTO): Promise> { const usernameOrError = Username.create(dto.email) if (usernameOrError.isFailed()) { - return { success: false } + return Result.fail(usernameOrError.getError()) } const username = usernameOrError.getValue() @@ -28,13 +24,15 @@ export class ClearLoginAttempts implements UseCaseInterface { const user = await this.userRepository.findOneByUsernameOrEmail(username) if (!user) { - return { success: true } + return Result.ok() } - this.logger.debug(`Resetting lock counter for user ${user.uuid}`) + this.logger.debug('Resetting lock counter for user', { + userId: user.uuid, + }) await this.lockRepository.resetLockCounter(user.uuid) - return { success: true } + return Result.ok() } } diff --git a/packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokens.ts b/packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokens.ts new file mode 100644 index 000000000..bcbfdb231 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokens.ts @@ -0,0 +1,28 @@ +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' + +import { CooldownSessionTokensDTO } from './CooldownSessionTokensDTO' +import { SessionTokensCooldownRepositoryInterface } from '../../Session/SessionTokensCooldownRepositoryInterface' + +export class CooldownSessionTokens implements UseCaseInterface { + constructor( + private cooldownPeriodInSeconds: number, + private sessionTokensCooldownRepository: SessionTokensCooldownRepositoryInterface, + ) {} + + async execute(dto: CooldownSessionTokensDTO): Promise> { + const sessionUuidOrError = Uuid.create(dto.sessionUuid) + if (sessionUuidOrError.isFailed()) { + return Result.fail(sessionUuidOrError.getError()) + } + const sessionUuid = sessionUuidOrError.getValue() + + await this.sessionTokensCooldownRepository.setCooldown({ + sessionUuid, + hashedAccessToken: dto.hashedAccessToken, + hashedRefreshToken: dto.hashedRefreshToken, + cooldownPeriodInSeconds: this.cooldownPeriodInSeconds, + }) + + return Result.ok() + } +} diff --git a/packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokensDTO.ts b/packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokensDTO.ts new file mode 100644 index 000000000..bd2bb92ab --- /dev/null +++ b/packages/auth/src/Domain/UseCase/CooldownSessionTokens/CooldownSessionTokensDTO.ts @@ -0,0 +1,5 @@ +export interface CooldownSessionTokensDTO { + sessionUuid: string + hashedAccessToken: string + hashedRefreshToken: string +} diff --git a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts index 2228f9848..8b6a2f176 100644 --- a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts +++ b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.spec.ts @@ -10,6 +10,7 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface' import { CreateCrossServiceToken } from './CreateCrossServiceToken' import { Result, + RoleName, SettingName, SharedVaultUser, SharedVaultUserPermission, @@ -23,6 +24,7 @@ import { UserSubscription } from '../../Subscription/UserSubscription' import { SubscriptionSetting } from '../../Setting/SubscriptionSetting' import { EncryptionVersion } from '../../Encryption/EncryptionVersion' import { GetActiveSessionsForUser } from '../GetActiveSessionsForUser' +import { Permission } from '../../Permission/Permission' describe('CreateCrossServiceToken', () => { let userProjector: ProjectorInterface @@ -39,6 +41,7 @@ describe('CreateCrossServiceToken', () => { let session: Session let user: User let role: Role + let permission: Permission const createUseCase = () => new CreateCrossServiceToken( @@ -55,11 +58,20 @@ describe('CreateCrossServiceToken', () => { ) beforeEach(() => { + permission = { + name: 'server:content-limit', + } as jest.Mocked + session = {} as jest.Mocked getActiveSessionsForUser = {} as jest.Mocked getActiveSessionsForUser.execute = jest.fn().mockReturnValue({ sessions: [session] }) + role = { + name: 'test', + } as jest.Mocked + role.permissions = Promise.resolve([]) + user = { uuid: '00000000-0000-0000-0000-000000000000', email: 'test@test.te', @@ -140,6 +152,47 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, + hasContentLimit: false, + }, + 60, + ) + }) + + it('should create a cross service token for user with content limitation', async () => { + role.name = RoleName.NAMES.CoreUser + role.permissions = Promise.resolve([permission]) + + user.roles = Promise.resolve([role]) + + userRepository.findOneByUuid = jest.fn().mockReturnValue(user) + + await createUseCase().execute({ + user, + session, + }) + + expect(tokenEncoder.encodeExpirableToken).toHaveBeenCalledWith( + { + roles: [ + { + name: 'role1', + uuid: '1-3-4', + }, + ], + belongs_to_shared_vaults: [ + { + shared_vault_uuid: '00000000-0000-0000-0000-000000000000', + permission: 'read', + }, + ], + session: { + test: 'test', + }, + user: { + email: 'test@test.te', + uuid: '00000000-0000-0000-0000-000000000000', + }, + hasContentLimit: true, }, 60, ) @@ -168,6 +221,7 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, + hasContentLimit: false, }, 60, ) @@ -196,6 +250,7 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, + hasContentLimit: false, }, 60, ) @@ -228,6 +283,7 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, + hasContentLimit: false, }, 60, ) @@ -259,6 +315,7 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, + hasContentLimit: false, }, 60, ) @@ -317,6 +374,7 @@ describe('CreateCrossServiceToken', () => { email: 'test@test.te', uuid: '00000000-0000-0000-0000-000000000000', }, + hasContentLimit: false, }, 60, ) diff --git a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts index 7b3dcafed..1955e31cc 100644 --- a/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts +++ b/packages/auth/src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken.ts @@ -1,5 +1,5 @@ -import { TokenEncoderInterface, CrossServiceTokenData } from '@standardnotes/security' -import { Result, SettingName, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { CrossServiceTokenData, TokenEncoderInterface } from '@standardnotes/security' +import { Result, RoleName, SettingName, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { ProjectorInterface } from '../../../Projection/ProjectorInterface' import { Role } from '../../Role/Role' @@ -44,6 +44,13 @@ export class CreateCrossServiceToken implements UseCaseInterface { } const roles = await user.roles + const coreUserRole = roles.find((role) => role.name === RoleName.NAMES.CoreUser) + let hasContentLimit = false + + if (coreUserRole) { + const permissions = await coreUserRole.permissions + hasContentLimit = permissions.find((permission) => permission.name === 'server:content-limit') !== undefined + } const sharedVaultAssociations = await this.sharedVaultUserRepository.findByUserUuid( Uuid.create(user.uuid).getValue(), @@ -57,6 +64,7 @@ export class CreateCrossServiceToken implements UseCaseInterface { shared_vault_uuid: association.props.sharedVaultUuid.value, permission: association.props.permission.value, })), + hasContentLimit: hasContentLimit, } if (dto.sharedVaultOwnerContext !== undefined) { diff --git a/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.spec.ts b/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.spec.ts new file mode 100644 index 000000000..64117c541 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.spec.ts @@ -0,0 +1,90 @@ +import { Result } from '@standardnotes/domain-core' +import { EphemeralSessionRepositoryInterface } from '../../Session/EphemeralSessionRepositoryInterface' +import { SessionRepositoryInterface } from '../../Session/SessionRepositoryInterface' +import { GetSessionFromToken } from '../GetSessionFromToken/GetSessionFromToken' +import { DeleteSessionByToken } from './DeleteSessionByToken' +import { Session } from '../../Session/Session' +import { ApiVersion } from '../../Api/ApiVersion' +import { SessionService } from '../../Session/SessionService' +import { EphemeralSession } from '../../Session/EphemeralSession' + +describe('DeleteSessionByToken', () => { + let getSessionFromToken: GetSessionFromToken + let sessionRepository: SessionRepositoryInterface + let ephemeralSessionRepository: EphemeralSessionRepositoryInterface + let existingSession: Session + let existingEphemeralSession: EphemeralSession + + const createUseCase = () => + new DeleteSessionByToken(getSessionFromToken, sessionRepository, ephemeralSessionRepository) + + beforeEach(() => { + existingSession = {} as jest.Mocked + existingSession.uuid = '2e1e43' + existingSession.userUuid = '1-2-3' + existingSession.userAgent = 'Chrome' + existingSession.apiVersion = ApiVersion.VERSIONS.v20200115 + existingSession.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingSession.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingSession.readonlyAccess = false + existingSession.version = SessionService.HEADER_BASED_SESSION_VERSION + + existingEphemeralSession = {} as jest.Mocked + existingEphemeralSession.uuid = '2-3-4' + existingEphemeralSession.userUuid = '1-2-3' + existingEphemeralSession.userAgent = 'Mozilla Firefox' + existingEphemeralSession.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingEphemeralSession.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingEphemeralSession.readonlyAccess = false + + ephemeralSessionRepository = {} as jest.Mocked + ephemeralSessionRepository.deleteOne = jest.fn() + + getSessionFromToken = {} as jest.Mocked + getSessionFromToken.execute = jest.fn().mockResolvedValue(Result.ok({ session: existingSession })) + + sessionRepository = {} as jest.Mocked + sessionRepository.deleteOneByUuid = jest.fn() + }) + + it('should delete a session by token', async () => { + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + + expect(result.isFailed()).toBeFalsy() + + expect(sessionRepository.deleteOneByUuid).toHaveBeenCalledWith('2e1e43') + expect(ephemeralSessionRepository.deleteOne).not.toHaveBeenCalled() + }) + + it('should delete an ephemeral session by token', async () => { + getSessionFromToken.execute = jest + .fn() + .mockResolvedValue(Result.ok({ session: existingEphemeralSession, isEphemeral: true })) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + + expect(result.isFailed()).toBeFalsy() + + expect(sessionRepository.deleteOneByUuid).not.toHaveBeenCalled() + expect(ephemeralSessionRepository.deleteOne).toHaveBeenCalledWith('2-3-4', '1-2-3') + }) + + it('should not delete a session by token if session is not found', async () => { + getSessionFromToken.execute = jest.fn().mockResolvedValue(Result.fail('Session not found')) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:4:3', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + + expect(sessionRepository.deleteOneByUuid).not.toHaveBeenCalled() + expect(ephemeralSessionRepository.deleteOne).not.toHaveBeenCalled() + }) +}) diff --git a/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.ts b/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.ts new file mode 100644 index 000000000..c3362bb50 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken.ts @@ -0,0 +1,30 @@ +import { Result, UseCaseInterface } from '@standardnotes/domain-core' +import { DeleteSessionByTokenDTO } from './DeleteSessionByTokenDTO' +import { GetSessionFromToken } from '../GetSessionFromToken/GetSessionFromToken' +import { SessionRepositoryInterface } from '../../Session/SessionRepositoryInterface' +import { EphemeralSessionRepositoryInterface } from '../../Session/EphemeralSessionRepositoryInterface' +import { Session } from '../../Session/Session' + +export class DeleteSessionByToken implements UseCaseInterface { + constructor( + private getSessionFromToken: GetSessionFromToken, + private sessionRepository: SessionRepositoryInterface, + private ephemeralSessionRepository: EphemeralSessionRepositoryInterface, + ) {} + + async execute(dto: DeleteSessionByTokenDTO): Promise> { + const resultOrError = await this.getSessionFromToken.execute(dto) + if (resultOrError.isFailed()) { + return Result.fail(resultOrError.getError()) + } + const result = resultOrError.getValue() + + if (result.isEphemeral) { + await this.ephemeralSessionRepository.deleteOne(result.session.uuid, result.session.userUuid) + } else { + await this.sessionRepository.deleteOneByUuid(result.session.uuid) + } + + return Result.ok(result.session) + } +} diff --git a/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByTokenDTO.ts b/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByTokenDTO.ts new file mode 100644 index 000000000..87f445f8e --- /dev/null +++ b/packages/auth/src/Domain/UseCase/DeleteSessionByToken/DeleteSessionByTokenDTO.ts @@ -0,0 +1,12 @@ +export interface DeleteSessionByTokenDTO { + authTokenFromHeaders: string + authCookies?: Map + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } +} diff --git a/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.spec.ts b/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.spec.ts index 5fb2cf0f8..fbec272bc 100644 --- a/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.spec.ts +++ b/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.spec.ts @@ -44,6 +44,22 @@ describe('DeleteSetting', () => { expect(settingRepository.deleteByUserUuid).toHaveBeenCalledWith({ settingName: 'test', userUuid: '1-2-3' }) }) + it('should delete recovery codes setting if MFA secret is deleted', async () => { + await createUseCase().execute({ + settingName: SettingName.NAMES.MfaSecret, + userUuid: '1-2-3', + }) + + expect(settingRepository.deleteByUserUuid).toHaveBeenNthCalledWith(1, { + settingName: SettingName.NAMES.MfaSecret, + userUuid: '1-2-3', + }) + expect(settingRepository.deleteByUserUuid).toHaveBeenNthCalledWith(2, { + settingName: SettingName.NAMES.RecoveryCodes, + userUuid: '1-2-3', + }) + }) + it('should delete a setting by uuid', async () => { await createUseCase().execute({ settingName: 'test', diff --git a/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.ts b/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.ts index 8a0ae9a53..ad9c0bbe0 100644 --- a/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.ts +++ b/packages/auth/src/Domain/UseCase/DeleteSetting/DeleteSetting.ts @@ -1,12 +1,13 @@ import { inject, injectable } from 'inversify' +import { SettingName, Timestamps } from '@standardnotes/domain-core' +import { TimerInterface } from '@standardnotes/time' + import { DeleteSettingDto } from './DeleteSettingDto' import { DeleteSettingResponse } from './DeleteSettingResponse' import { UseCaseInterface } from '../UseCaseInterface' import TYPES from '../../../Bootstrap/Types' import { SettingRepositoryInterface } from '../../Setting/SettingRepositoryInterface' -import { TimerInterface } from '@standardnotes/time' import { Setting } from '../../Setting/Setting' -import { Timestamps } from '@standardnotes/domain-core' @injectable() export class DeleteSetting implements UseCaseInterface { @@ -44,6 +45,13 @@ export class DeleteSetting implements UseCaseInterface { }) } + if (settingName === SettingName.NAMES.MfaSecret) { + await this.settingRepository.deleteByUserUuid({ + userUuid: dto.userUuid, + settingName: SettingName.NAMES.RecoveryCodes, + }) + } + return { success: true, settingName, diff --git a/packages/auth/src/Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription.ts b/packages/auth/src/Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription.ts index 08654fc07..851d2ca66 100644 --- a/packages/auth/src/Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription.ts +++ b/packages/auth/src/Domain/UseCase/DisableEmailSettingBasedOnEmailSubscription/DisableEmailSettingBasedOnEmailSubscription.ts @@ -58,10 +58,6 @@ export class DisableEmailSettingBasedOnEmailSubscription implements UseCaseInter private getSettingNameFromLevel(level: string): Result { /* istanbul ignore next */ switch (level) { - case EmailLevel.LEVELS.FailedCloudBackup: - return Result.ok(SettingName.create(SettingName.NAMES.MuteFailedCloudBackupsEmails).getValue()) - case EmailLevel.LEVELS.FailedEmailBackup: - return Result.ok(SettingName.create(SettingName.NAMES.MuteFailedBackupsEmails).getValue()) case EmailLevel.LEVELS.Marketing: return Result.ok(SettingName.create(SettingName.NAMES.MuteMarketingEmails).getValue()) case EmailLevel.LEVELS.SignIn: diff --git a/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.spec.ts b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.spec.ts new file mode 100644 index 000000000..63f5fa057 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.spec.ts @@ -0,0 +1,47 @@ +import { SessionTokensCooldownRepositoryInterface } from '../../Session/SessionTokensCooldownRepositoryInterface' +import { GetCooldownSessionTokens } from './GetCooldownSessionTokens' + +describe('GetCooldownSessionTokens', () => { + let sessionTokensCooldownRepository: SessionTokensCooldownRepositoryInterface + + const createUseCase = () => new GetCooldownSessionTokens(sessionTokensCooldownRepository) + + beforeEach(() => { + sessionTokensCooldownRepository = {} as jest.Mocked + sessionTokensCooldownRepository.getHashedTokens = jest.fn().mockReturnValue(null) + }) + + it('should return an error if the sessionUuid is invalid', async () => { + const useCase = createUseCase() + + const result = await useCase.execute({ sessionUuid: 'invalidUuid' }) + + expect(result.isFailed()).toBe(true) + }) + + it('should return an error if no tokens are found', async () => { + const useCase = createUseCase() + + const result = await useCase.execute({ sessionUuid: '00000000-0000-0000-0000-000000000000' }) + + expect(result.isFailed()).toBe(true) + }) + + it('should return the hashed tokens', async () => { + sessionTokensCooldownRepository.getHashedTokens = jest.fn().mockReturnValue({ + hashedAccessToken: 'hashedAccessToken', + hashedRefreshToken: 'hashedRefreshToken', + }) + + const useCase = createUseCase() + + const result = await useCase.execute({ sessionUuid: '00000000-0000-0000-0000-000000000000' }) + + expect(result.isFailed()).toBeFalsy() + + const value = result.getValue() + + expect(value.hashedAccessToken).toBe('hashedAccessToken') + expect(value.hashedRefreshToken).toBe('hashedRefreshToken') + }) +}) diff --git a/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.ts b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.ts new file mode 100644 index 000000000..f988e51e5 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokens.ts @@ -0,0 +1,27 @@ +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' + +import { GetCooldownSessionTokensResponse } from './GetCooldownSessionTokensResponse' +import { GetCooldownSessionTokensDTO } from './GetCooldownSessionTokensDTO' +import { SessionTokensCooldownRepositoryInterface } from '../../Session/SessionTokensCooldownRepositoryInterface' + +export class GetCooldownSessionTokens implements UseCaseInterface { + constructor(private sessionTokensCooldownRepository: SessionTokensCooldownRepositoryInterface) {} + + async execute(dto: GetCooldownSessionTokensDTO): Promise> { + const sessionUuidOrError = Uuid.create(dto.sessionUuid) + if (sessionUuidOrError.isFailed()) { + return Result.fail(sessionUuidOrError.getError()) + } + const sessionUuid = sessionUuidOrError.getValue() + + const hashedTokens = await this.sessionTokensCooldownRepository.getHashedTokens(sessionUuid) + if (!hashedTokens) { + return Result.fail('No tokens found') + } + + return Result.ok({ + hashedAccessToken: hashedTokens.hashedAccessToken, + hashedRefreshToken: hashedTokens.hashedRefreshToken, + }) + } +} diff --git a/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensDTO.ts b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensDTO.ts new file mode 100644 index 000000000..9604425f6 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensDTO.ts @@ -0,0 +1,3 @@ +export interface GetCooldownSessionTokensDTO { + sessionUuid: string +} diff --git a/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensResponse.ts b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensResponse.ts new file mode 100644 index 000000000..ee5af18b9 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetCooldownSessionTokens/GetCooldownSessionTokensResponse.ts @@ -0,0 +1,4 @@ +export interface GetCooldownSessionTokensResponse { + hashedAccessToken: string + hashedRefreshToken: string +} diff --git a/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.spec.ts b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.spec.ts new file mode 100644 index 000000000..f4108c65a --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.spec.ts @@ -0,0 +1,272 @@ +import { Logger } from 'winston' +import { EphemeralSession } from '../../Session/EphemeralSession' +import { EphemeralSessionRepositoryInterface } from '../../Session/EphemeralSessionRepositoryInterface' +import { Session } from '../../Session/Session' +import { SessionRepositoryInterface } from '../../Session/SessionRepositoryInterface' +import { SessionService } from '../../Session/SessionService' +import { GetSessionFromToken } from './GetSessionFromToken' +import { ApiVersion } from '../../Api/ApiVersion' +import { GetCooldownSessionTokens } from '../GetCooldownSessionTokens/GetCooldownSessionTokens' +import { Result } from '@standardnotes/domain-core' + +describe('GetSessionFromToken', () => { + let sessionRepository: SessionRepositoryInterface + let ephemeralSessionRepository: EphemeralSessionRepositoryInterface + let existingSession: Session + let existingEphemeralSession: EphemeralSession + let getCooldownSessionTokens: GetCooldownSessionTokens + let logger: Logger + + const createUseCase = () => + new GetSessionFromToken(sessionRepository, ephemeralSessionRepository, getCooldownSessionTokens, logger) + + beforeEach(() => { + logger = {} as jest.Mocked + logger.error = jest.fn() + + existingSession = {} as jest.Mocked + existingSession.uuid = '2e1e43' + existingSession.userUuid = '1-2-3' + existingSession.userAgent = 'Chrome' + existingSession.apiVersion = ApiVersion.VERSIONS.v20200115 + existingSession.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingSession.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingSession.readonlyAccess = false + existingSession.version = SessionService.HEADER_BASED_SESSION_VERSION + + sessionRepository = {} as jest.Mocked + sessionRepository.findOneByUuid = jest.fn().mockReturnValue(null) + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockReturnValue(null) + + ephemeralSessionRepository = {} as jest.Mocked + ephemeralSessionRepository.findOneByUuid = jest.fn() + ephemeralSessionRepository.findOneByPrivateIdentifier = jest.fn() + + existingEphemeralSession = {} as jest.Mocked + existingEphemeralSession.uuid = '2-3-4' + existingEphemeralSession.userUuid = '1-2-3' + existingEphemeralSession.userAgent = 'Mozilla Firefox' + existingEphemeralSession.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingEphemeralSession.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + existingEphemeralSession.readonlyAccess = false + + getCooldownSessionTokens = {} as jest.Mocked + getCooldownSessionTokens.execute = jest.fn().mockReturnValue(Result.fail('No tokens found')) + }) + + it('should retrieve a session from a session token', async () => { + sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { + if (uuid === '2') { + return existingSession + } + + return null + }) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeFalsy() + + const { session, isEphemeral } = result.getValue() + + expect(session).toEqual(session) + expect(isEphemeral).toBeFalsy() + }) + + it('should retrieve a cookie session from a cookie session token', async () => { + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockImplementation((privateIdentifier: string) => { + if (privateIdentifier === '00000000-0000-0000-0000-000000000000') { + existingSession.privateIdentifier = '00000000-0000-0000-0000-000000000000' + existingSession.uuid = '00000000-0000-0000-0000-000000000001' + existingSession.version = SessionService.COOKIE_BASED_SESSION_VERSION + + return existingSession + } + + return null + }) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '2:00000000-0000-0000-0000-000000000000', + authCookies: new Map([['access_token_00000000-0000-0000-0000-000000000001', ['3']]]), + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeFalsy() + + const { session, isEphemeral } = result.getValue() + + expect(session).toEqual(session) + expect(isEphemeral).toBeFalsy() + }) + + it('should retrieve a session by a cooldown access token', async () => { + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockImplementation((privateIdentifier: string) => { + if (privateIdentifier === '00000000-0000-0000-0000-000000000000') { + existingSession.privateIdentifier = '00000000-0000-0000-0000-000000000000' + existingSession.uuid = '00000000-0000-0000-0000-000000000001' + existingSession.version = SessionService.COOKIE_BASED_SESSION_VERSION + + return existingSession + } + + return null + }) + + getCooldownSessionTokens.execute = jest.fn().mockReturnValue( + Result.ok({ + hashedAccessToken: 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35', + hashedRefreshToken: 'd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35', + }), + ) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '2:00000000-0000-0000-0000-000000000000', + authCookies: new Map([['access_token_00000000-0000-0000-0000-000000000001', ['2']]]), + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeFalsy() + + const { session, isEphemeral } = result.getValue() + + expect(session).toEqual(session) + expect(isEphemeral).toBeFalsy() + }) + + it('should not retrieve a header session from a cookie session token', async () => { + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockImplementation((privateIdentifier: string) => { + if (privateIdentifier === '00000000-0000-0000-0000-000000000000') { + existingSession.privateIdentifier = '00000000-0000-0000-0000-000000000000' + existingSession.uuid = '00000000-0000-0000-0000-000000000001' + existingSession.version = SessionService.HEADER_BASED_SESSION_VERSION + + return existingSession + } + + return null + }) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '2:00000000-0000-0000-0000-000000000000', + authCookies: new Map([['access_token_00000000-0000-0000-0000-000000000001', ['3']]]), + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + }) + + it('should not retrieve a cookie session from a cookie session token that has invalid private identifier', async () => { + const result = await createUseCase().execute({ + authTokenFromHeaders: '2', + authCookies: new Map([['access_token_4', ['3']]]), + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + }) + + it('should not retrieve a cookie session from a cookie session token that has an invalid uuid', async () => { + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockImplementation((privateIdentifier: string) => { + if (privateIdentifier === '00000000-0000-0000-0000-000000000000') { + existingSession.privateIdentifier = '00000000-0000-0000-0000-000000000000' + existingSession.uuid = '00000000-0000-0000-0000-000000000002' + existingSession.version = SessionService.COOKIE_BASED_SESSION_VERSION + + return existingSession + } + + return null + }) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '2:00000000-0000-0000-0000-000000000000', + authCookies: new Map([['access_token_00000000-0000-0000-0000-000000000001', ['3']]]), + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + }) + + it('should not retrieve a cookie session if cookies are missing', async () => { + sessionRepository.findOneByPrivateIdentifier = jest.fn().mockImplementation((privateIdentifier: string) => { + if (privateIdentifier === '00000000-0000-0000-0000-000000000000') { + existingSession.privateIdentifier = '00000000-0000-0000-0000-000000000000' + existingSession.uuid = '00000000-0000-0000-0000-000000000001' + existingSession.version = SessionService.COOKIE_BASED_SESSION_VERSION + + return existingSession + } + + return null + }) + + const result1 = await createUseCase().execute({ + authTokenFromHeaders: '2:00000000-0000-0000-0000-000000000000', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result1.isFailed()).toBeTruthy() + + const result2 = await createUseCase().execute({ + authTokenFromHeaders: '2:00000000-0000-0000-0000-000000000000', + authCookies: new Map([]), + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result2.isFailed()).toBeTruthy() + }) + + it('should retrieve an ephemeral session from a session token', async () => { + ephemeralSessionRepository.findOneByUuid = jest.fn().mockReturnValue(existingEphemeralSession) + sessionRepository.findOneByUuid = jest.fn().mockReturnValue(null) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeFalsy() + + const { session, isEphemeral } = result.getValue() + + expect(session).toEqual(existingEphemeralSession) + expect(isEphemeral).toBeTruthy() + }) + + it('should not retrieve a session from a session token that has access token missing', async () => { + sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { + if (uuid === '2') { + return existingSession + } + + return null + }) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + }) + + it('should not retrieve a session that is missing', async () => { + sessionRepository.findOneByUuid = jest.fn().mockReturnValue(null) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + }) + + it('should not retrieve a session from a session token that has invalid access token', async () => { + sessionRepository.findOneByUuid = jest.fn().mockImplementation((uuid) => { + if (uuid === '2') { + return existingSession + } + + return null + }) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '1:2:4', + requestMetadata: { url: '/foobar', method: 'GET' }, + }) + expect(result.isFailed()).toBeTruthy() + }) +}) diff --git a/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.ts b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.ts new file mode 100644 index 000000000..cff636127 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromToken.ts @@ -0,0 +1,160 @@ +import * as crypto from 'crypto' +import { Result, UseCaseInterface } from '@standardnotes/domain-core' + +import { Session } from '../../Session/Session' +import { GetSessionFromTokenDTO } from './GetSessionFromTokenDTO' +import { SessionService } from '../../Session/SessionService' +import { SessionRepositoryInterface } from '../../Session/SessionRepositoryInterface' +import { EphemeralSessionRepositoryInterface } from '../../Session/EphemeralSessionRepositoryInterface' +import { Logger } from 'winston' +import { GetSessionFromTokenResult } from './GetSessionFromTokenResult' +import { GetCooldownSessionTokens } from '../GetCooldownSessionTokens/GetCooldownSessionTokens' + +export class GetSessionFromToken implements UseCaseInterface { + constructor( + private sessionRepository: SessionRepositoryInterface, + private ephemeralSessionRepository: EphemeralSessionRepositoryInterface, + private getCooldownSessionTokens: GetCooldownSessionTokens, + private logger: Logger, + ) {} + + async execute(dto: GetSessionFromTokenDTO): Promise> { + const tokenParts = dto.authTokenFromHeaders.split(':') + const tokenVersion = parseInt(tokenParts[0]) + + let accessTokens: string[] = [] + let isSessionEphemeral = false + let retrievedSession = undefined + switch (tokenVersion) { + case SessionService.SESSION_TOKEN_VERSION: { + if (!tokenParts[2]) { + return Result.fail('Invalid token') + } + + accessTokens = [tokenParts[2]] + + const sessionUuid = tokenParts[1] + + const { session, isEphemeral } = await this.getSession(sessionUuid) + isSessionEphemeral = isEphemeral + + if (!session || session.version === SessionService.COOKIE_BASED_SESSION_VERSION) { + return Result.fail('Invalid token') + } + + retrievedSession = session + + break + } + case SessionService.COOKIE_SESSION_TOKEN_VERSION: { + const privateIdentifier = tokenParts[1] + if (!privateIdentifier) { + return Result.fail('Invalid token') + } + + const { session, isEphemeral } = await this.getSessionByPrivateIdentifier(privateIdentifier) + isSessionEphemeral = isEphemeral + + if (!session || session.version === SessionService.HEADER_BASED_SESSION_VERSION) { + return Result.fail('Invalid token') + } + + retrievedSession = session + + if (!dto.authCookies || dto.authCookies.size === 0) { + /* istanbul ignore next */ + this.logger.error('No cookies provided for cookie-based session token.', { + userId: session.userUuid, + sessionUuid: session.uuid, + snjs: dto.requestMetadata.snjs, + application: dto.requestMetadata.application, + url: dto.requestMetadata.url, + method: dto.requestMetadata.method, + userAgent: session.userAgent, + secChUa: session.userAgent ? dto.requestMetadata.secChUa : undefined, + }) + + return Result.fail('Invalid token') + } + + const accessTokensFromAuthCookies = dto.authCookies?.get(`access_token_${session.uuid}`) + if (accessTokensFromAuthCookies === undefined) { + return Result.fail('Invalid token') + } + + accessTokens = accessTokensFromAuthCookies + + break + } + } + + /* istanbul ignore next */ + if (accessTokens.length === 0 || !retrievedSession) { + return Result.fail('Invalid token') + } + + const currentSessionTokensMatching = this.areTokensMatching(accessTokens, retrievedSession.hashedAccessToken) + if (currentSessionTokensMatching) { + return Result.ok({ session: retrievedSession, isEphemeral: isSessionEphemeral, givenTokensWereInCooldown: false }) + } + + const cooldownTokensResult = await this.getCooldownSessionTokens.execute({ sessionUuid: retrievedSession.uuid }) + if (!cooldownTokensResult.isFailed()) { + const cooldownTokens = cooldownTokensResult.getValue() + if (this.areTokensMatching(accessTokens, cooldownTokens.hashedAccessToken)) { + return Result.ok({ + session: retrievedSession, + isEphemeral: isSessionEphemeral, + givenTokensWereInCooldown: true, + cooldownHashedRefreshToken: cooldownTokens.hashedRefreshToken, + }) + } + } + + return Result.fail('Session not found') + } + + private areTokensMatching(inputTokens: string[], hashedToken: string): boolean { + for (const inputToken of inputTokens) { + const hashedInputToken = crypto.createHash('sha256').update(inputToken).digest('hex') + + const areMatching = crypto.timingSafeEqual(Buffer.from(hashedToken), Buffer.from(hashedInputToken)) + + if (areMatching) { + return true + } + } + + return false + } + + private async getSession(uuid: string): Promise<{ + session: Session | null + isEphemeral: boolean + }> { + let session = await this.ephemeralSessionRepository.findOneByUuid(uuid) + let isEphemeral = true + + if (!session) { + session = await this.sessionRepository.findOneByUuid(uuid) + isEphemeral = false + } + + return { session, isEphemeral } + } + + private async getSessionByPrivateIdentifier(privateIdentifier: string): Promise<{ + session: Session | null + isEphemeral: boolean + }> { + let session = await this.ephemeralSessionRepository.findOneByPrivateIdentifier(privateIdentifier) + let isEphemeral = true + + if (!session) { + session = await this.sessionRepository.findOneByPrivateIdentifier(privateIdentifier) + isEphemeral = false + } + + return { session, isEphemeral } + } +} diff --git a/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenDTO.ts b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenDTO.ts new file mode 100644 index 000000000..5368d4f06 --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenDTO.ts @@ -0,0 +1,12 @@ +export interface GetSessionFromTokenDTO { + authTokenFromHeaders: string + authCookies?: Map + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } +} diff --git a/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenResult.ts b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenResult.ts new file mode 100644 index 000000000..9c78eadef --- /dev/null +++ b/packages/auth/src/Domain/UseCase/GetSessionFromToken/GetSessionFromTokenResult.ts @@ -0,0 +1,8 @@ +import { Session } from '../../Session/Session' + +export interface GetSessionFromTokenResult { + session: Session + isEphemeral: boolean + givenTokensWereInCooldown: boolean + cooldownHashedRefreshToken?: string +} diff --git a/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParams.spec.ts b/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParams.spec.ts index d7fc24eec..ba887f5dc 100644 --- a/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParams.spec.ts +++ b/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParams.spec.ts @@ -6,6 +6,7 @@ import { User } from '../../User/User' import { UserRepositoryInterface } from '../../User/UserRepositoryInterface' import { GetSetting } from '../GetSetting/GetSetting' import { GetUserKeyParamsRecovery } from './GetUserKeyParamsRecovery' +import { ApiVersion } from '../../Api/ApiVersion' describe('GetUserKeyParamsRecovery', () => { let keyParamsFactory: KeyParamsFactoryInterface @@ -40,6 +41,7 @@ describe('GetUserKeyParamsRecovery', () => { username: 'username', codeChallenge: '', recoveryCodes: '1234 5678', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result.isFailed()).toBe(true) @@ -51,6 +53,7 @@ describe('GetUserKeyParamsRecovery', () => { username: '', codeChallenge: 'code-challenge', recoveryCodes: '1234 5678', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result.isFailed()).toBe(true) @@ -62,6 +65,7 @@ describe('GetUserKeyParamsRecovery', () => { username: 'username', codeChallenge: 'codeChallenge', recoveryCodes: '', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result.isFailed()).toBe(true) @@ -75,6 +79,7 @@ describe('GetUserKeyParamsRecovery', () => { username: 'username', codeChallenge: 'codeChallenge', recoveryCodes: '1234 5678', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(keyParamsFactory.createPseudoParams).toHaveBeenCalled() @@ -88,6 +93,7 @@ describe('GetUserKeyParamsRecovery', () => { username: 'username', codeChallenge: 'codeChallenge', recoveryCodes: '1234 5678', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result.isFailed()).toBe(true) @@ -99,6 +105,7 @@ describe('GetUserKeyParamsRecovery', () => { username: 'username', codeChallenge: 'codeChallenge', recoveryCodes: '1234 5678', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result.isFailed()).toBe(true) @@ -110,9 +117,34 @@ describe('GetUserKeyParamsRecovery', () => { username: 'username', codeChallenge: 'codeChallenge', recoveryCodes: 'foo', + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(keyParamsFactory.create).toHaveBeenCalled() expect(result.isFailed()).toBe(false) }) + + it('should return error if api version is invalid', async () => { + const result = await createUseCase().execute({ + username: 'username', + codeChallenge: 'codeChallenge', + recoveryCodes: 'foo', + apiVersion: 'invalid', + }) + + expect(result.isFailed()).toBe(true) + expect(result.getError()).toBe('Invalid api version: invalid') + }) + + it('should return error if api version does not support recovery sign in', async () => { + const result = await createUseCase().execute({ + username: 'username', + codeChallenge: 'codeChallenge', + recoveryCodes: 'foo', + apiVersion: ApiVersion.VERSIONS.v20190520, + }) + + expect(result.isFailed()).toBe(true) + expect(result.getError()).toBe('Unsupported api version') + }) }) diff --git a/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery.ts b/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery.ts index 63467748b..8df307292 100644 --- a/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery.ts +++ b/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecovery.ts @@ -7,6 +7,7 @@ import { GetUserKeyParamsRecoveryDTO } from './GetUserKeyParamsRecoveryDTO' import { User } from '../../User/User' import { PKCERepositoryInterface } from '../../User/PKCERepositoryInterface' import { GetSetting } from '../GetSetting/GetSetting' +import { ApiVersion } from '../../Api/ApiVersion' export class GetUserKeyParamsRecovery implements UseCaseInterface { constructor( @@ -17,6 +18,16 @@ export class GetUserKeyParamsRecovery implements UseCaseInterface ) {} async execute(dto: GetUserKeyParamsRecoveryDTO): Promise> { + const apiVersionOrError = ApiVersion.create(dto.apiVersion) + if (apiVersionOrError.isFailed()) { + return Result.fail(apiVersionOrError.getError()) + } + const apiVersion = apiVersionOrError.getValue() + + if (!apiVersion.isSupportedForRecoverySignIn()) { + return Result.fail('Unsupported api version') + } + const usernameOrError = Username.create(dto.username) if (usernameOrError.isFailed()) { return Result.fail(`Could not sign in with recovery codes: ${usernameOrError.getError()}`) diff --git a/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecoveryDTO.ts b/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecoveryDTO.ts index b50620948..c000f94b6 100644 --- a/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecoveryDTO.ts +++ b/packages/auth/src/Domain/UseCase/GetUserKeyParamsRecovery/GetUserKeyParamsRecoveryDTO.ts @@ -1,4 +1,5 @@ export interface GetUserKeyParamsRecoveryDTO { + apiVersion: string codeChallenge: string username: string recoveryCodes: string diff --git a/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.spec.ts b/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.spec.ts index 5e0c31c9a..87eac7cb2 100644 --- a/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.spec.ts +++ b/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.spec.ts @@ -1,6 +1,5 @@ import 'reflect-metadata' -import { Logger } from 'winston' import { LockRepositoryInterface } from '../User/LockRepositoryInterface' import { User } from '../User/User' @@ -12,14 +11,10 @@ describe('IncreaseLoginAttempts', () => { let lockRepository: LockRepositoryInterface const maxLoginAttempts = 6 let user: User - let logger: Logger - const createUseCase = () => new IncreaseLoginAttempts(userRepository, lockRepository, maxLoginAttempts, logger) + const createUseCase = () => new IncreaseLoginAttempts(userRepository, lockRepository, maxLoginAttempts) beforeEach(() => { - logger = {} as jest.Mocked - logger.debug = jest.fn() - user = {} as jest.Mocked user.uuid = '123' @@ -28,42 +23,41 @@ describe('IncreaseLoginAttempts', () => { lockRepository = {} as jest.Mocked lockRepository.getLockCounter = jest.fn() - lockRepository.lockUser = jest.fn() lockRepository.updateLockCounter = jest.fn() }) it('should do nothing if a user identifier is invalid', async () => { - expect(await createUseCase().execute({ email: ' ' })).toEqual({ success: false }) + const result = await createUseCase().execute({ email: ' ' }) + expect(result.isFailed()).toEqual(true) expect(lockRepository.updateLockCounter).not.toHaveBeenCalled() - expect(lockRepository.lockUser).not.toHaveBeenCalled() - }) - - it('should lock a user if the number of failed login attempts is breached', async () => { - lockRepository.getLockCounter = jest.fn().mockReturnValue(5) - - expect(await createUseCase().execute({ email: 'test@test.te' })).toEqual({ success: true }) - - expect(lockRepository.updateLockCounter).toHaveBeenCalledWith('123', 6) - expect(lockRepository.lockUser).toHaveBeenCalledWith('123') }) it('should update the lock counter if a user is not exceeding the max failed login attempts', async () => { - lockRepository.getLockCounter = jest.fn().mockReturnValue(4) + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(4).mockReturnValueOnce(0) - expect(await createUseCase().execute({ email: 'test@test.te' })).toEqual({ success: true }) + const result = await createUseCase().execute({ email: 'test@test.te' }) + expect(result.isFailed()).toEqual(false) - expect(lockRepository.lockUser).not.toHaveBeenCalled() - expect(lockRepository.updateLockCounter).toHaveBeenCalledWith('123', 5) + expect(lockRepository.updateLockCounter).toHaveBeenCalledWith('123', 5, 'non-captcha') + }) + + it('should update the captcha lock counter if a user is exceeding the max failed login attempts', async () => { + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(6).mockReturnValueOnce(0) + + const result = await createUseCase().execute({ email: 'test@test.te' }) + expect(result.isFailed()).toEqual(false) + + expect(lockRepository.updateLockCounter).toHaveBeenCalledWith('123', 1, 'captcha') }) it('should should update the lock counter based on email if user is not found', async () => { - lockRepository.getLockCounter = jest.fn().mockReturnValue(4) + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(4).mockReturnValueOnce(0) userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(null) - expect(await createUseCase().execute({ email: 'test@test.te' })).toEqual({ success: true }) + const result = await createUseCase().execute({ email: 'test@test.te' }) + expect(result.isFailed()).toEqual(false) - expect(lockRepository.lockUser).not.toHaveBeenCalled() - expect(lockRepository.updateLockCounter).toHaveBeenCalledWith('test@test.te', 5) + expect(lockRepository.updateLockCounter).toHaveBeenCalledWith('test@test.te', 5, 'non-captcha') }) }) diff --git a/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.ts b/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.ts index 51431b255..b937221c8 100644 --- a/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.ts +++ b/packages/auth/src/Domain/UseCase/IncreaseLoginAttempts.ts @@ -1,28 +1,23 @@ -import { Username } from '@standardnotes/domain-core' -import { inject, injectable } from 'inversify' -import { Logger } from 'winston' -import TYPES from '../../Bootstrap/Types' +import { Result, UseCaseInterface, Username } from '@standardnotes/domain-core' + import { LockRepositoryInterface } from '../User/LockRepositoryInterface' import { UserRepositoryInterface } from '../User/UserRepositoryInterface' import { IncreaseLoginAttemptsDTO } from './IncreaseLoginAttemptsDTO' import { IncreaseLoginAttemptsResponse } from './IncreaseLoginAttemptsResponse' -import { UseCaseInterface } from './UseCaseInterface' -@injectable() -export class IncreaseLoginAttempts implements UseCaseInterface { +export class IncreaseLoginAttempts implements UseCaseInterface { constructor( - @inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface, - @inject(TYPES.Auth_LockRepository) private lockRepository: LockRepositoryInterface, - @inject(TYPES.Auth_MAX_LOGIN_ATTEMPTS) private maxLoginAttempts: number, - @inject(TYPES.Auth_Logger) private logger: Logger, + private userRepository: UserRepositoryInterface, + private lockRepository: LockRepositoryInterface, + private maxNonCaptchaAttempts: number, ) {} - async execute(dto: IncreaseLoginAttemptsDTO): Promise { + async execute(dto: IncreaseLoginAttemptsDTO): Promise> { let identifier = dto.email const usernameOrError = Username.create(dto.email) if (usernameOrError.isFailed()) { - return { success: false } + return Result.fail(usernameOrError.getError()) } const username = usernameOrError.getValue() @@ -31,18 +26,29 @@ export class IncreaseLoginAttempts implements UseCaseInterface { identifier = user.uuid } - let numberOfFailedAttempts = await this.lockRepository.getLockCounter(identifier) + const numberOfFailedAttempts = await this.lockRepository.getLockCounter(identifier, 'non-captcha') + const numberOfFailedAttemptsInCaptchaMode = await this.lockRepository.getLockCounter(identifier, 'captcha') - numberOfFailedAttempts += 1 + const isEligibleForNonCaptchaMode = + numberOfFailedAttemptsInCaptchaMode === 0 && numberOfFailedAttempts < this.maxNonCaptchaAttempts + const isNonCaptchaLimitReached = + numberOfFailedAttempts + 1 >= this.maxNonCaptchaAttempts || numberOfFailedAttemptsInCaptchaMode > 0 - await this.lockRepository.updateLockCounter(identifier, numberOfFailedAttempts) - - if (numberOfFailedAttempts >= this.maxLoginAttempts) { - this.logger.debug(`User ${identifier} breached number of allowed login attempts. Locking user.`) - - await this.lockRepository.lockUser(identifier) + let newCounter: number + if (isEligibleForNonCaptchaMode) { + newCounter = numberOfFailedAttempts + 1 + } else { + newCounter = numberOfFailedAttemptsInCaptchaMode + 1 } - return { success: true } + await this.lockRepository.updateLockCounter( + identifier, + newCounter, + isEligibleForNonCaptchaMode ? 'non-captcha' : 'captcha', + ) + + return Result.ok({ + isNonCaptchaLimitReached, + }) } } diff --git a/packages/auth/src/Domain/UseCase/IncreaseLoginAttemptsResponse.ts b/packages/auth/src/Domain/UseCase/IncreaseLoginAttemptsResponse.ts index 9a58e8e4d..eae9766ab 100644 --- a/packages/auth/src/Domain/UseCase/IncreaseLoginAttemptsResponse.ts +++ b/packages/auth/src/Domain/UseCase/IncreaseLoginAttemptsResponse.ts @@ -1,3 +1,3 @@ -export type IncreaseLoginAttemptsResponse = { - success: boolean +export interface IncreaseLoginAttemptsResponse { + isNonCaptchaLimitReached: boolean } diff --git a/packages/auth/src/Domain/UseCase/RefreshSessionToken.spec.ts b/packages/auth/src/Domain/UseCase/RefreshSessionToken.spec.ts index 6f94de520..1694d8c0d 100644 --- a/packages/auth/src/Domain/UseCase/RefreshSessionToken.spec.ts +++ b/packages/auth/src/Domain/UseCase/RefreshSessionToken.spec.ts @@ -11,6 +11,11 @@ import { GetSetting } from './GetSetting/GetSetting' import { Result } from '@standardnotes/domain-core' import { LogSessionUserAgentOption } from '@standardnotes/settings' import { Setting } from '../Setting/Setting' +import { SessionService } from '../Session/SessionService' +import { SessionCreationResult } from '../Session/SessionCreationResult' +import { ApiVersion } from '../Api/ApiVersion' +import { CooldownSessionTokens } from './CooldownSessionTokens/CooldownSessionTokens' +import { GetSessionFromToken } from './GetSessionFromToken/GetSessionFromToken' describe('RefreshSessionToken', () => { let sessionService: SessionServiceInterface @@ -20,27 +25,43 @@ describe('RefreshSessionToken', () => { let timer: TimerInterface let getSetting: GetSetting let logger: Logger + let sessionCreationResult: SessionCreationResult + let cooldownSessionTokens: CooldownSessionTokens + let getSessionFromToken: GetSessionFromToken const createUseCase = () => - new RefreshSessionToken(sessionService, domainEventFactory, domainEventPublisher, timer, getSetting, logger) + new RefreshSessionToken( + sessionService, + domainEventFactory, + domainEventPublisher, + timer, + getSetting, + cooldownSessionTokens, + getSessionFromToken, + logger, + ) beforeEach(() => { session = {} as jest.Mocked session.uuid = '1-2-3' session.refreshExpiration = new Date(123) + session.version = SessionService.HEADER_BASED_SESSION_VERSION + session.hashedAccessToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + session.hashedRefreshToken = '4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce' + + sessionCreationResult = {} as jest.Mocked getSetting = {} as jest.Mocked getSetting.execute = jest.fn().mockReturnValue(Result.fail('not found')) sessionService = {} as jest.Mocked - sessionService.isRefreshTokenMatchingHashedSessionToken = jest.fn().mockReturnValue(true) - sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session, isEphemeral: false }) - sessionService.refreshTokens = jest.fn().mockReturnValue({ - access_token: 'token1', - refresh_token: 'token2', - access_expiration: 123, - refresh_expiration: 234, - }) + sessionService.refreshTokens = jest.fn().mockReturnValue(sessionCreationResult) + + getSessionFromToken = {} as jest.Mocked + getSessionFromToken.execute = jest.fn().mockReturnValue(Result.ok({ session, isEphemeral: false })) + + cooldownSessionTokens = {} as jest.Mocked + cooldownSessionTokens.execute = jest.fn() domainEventFactory = {} as jest.Mocked domainEventFactory.createSessionRefreshedEvent = jest.fn().mockReturnValue({}) @@ -53,25 +74,52 @@ describe('RefreshSessionToken', () => { logger = {} as jest.Mocked logger.error = jest.fn() + logger.debug = jest.fn() }) it('should refresh session token', async () => { const result = await createUseCase().execute({ - accessToken: '123', - refreshToken: '234', - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, }) - expect(sessionService.refreshTokens).toHaveBeenCalledWith({ session, isEphemeral: false }) + expect(sessionService.refreshTokens).toHaveBeenCalledWith({ + session, + isEphemeral: false, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), + }) expect(result).toEqual({ success: true, - sessionPayload: { - access_token: 'token1', - refresh_token: 'token2', - access_expiration: 123, - refresh_expiration: 234, - }, + result: sessionCreationResult, + }) + + expect(domainEventPublisher.publish).toHaveBeenCalled() + }) + + it('should refresh cookie token', async () => { + session.version = SessionService.COOKIE_BASED_SESSION_VERSION + getSessionFromToken.execute = jest.fn().mockReturnValue(Result.ok({ session, isEphemeral: false })) + + const result = await createUseCase().execute({ + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '2:2:3', + authCookies: new Map([['refresh_token_1-2-3', ['3']]]), + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, + }) + + expect(result).toEqual({ + success: true, + result: sessionCreationResult, + }) + + expect(sessionService.refreshTokens).toHaveBeenCalledWith({ + session, + isEphemeral: false, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), }) expect(domainEventPublisher.publish).toHaveBeenCalled() @@ -86,21 +134,21 @@ describe('RefreshSessionToken', () => { ) const result = await createUseCase().execute({ - accessToken: '123', - refreshToken: '234', - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, }) - expect(sessionService.refreshTokens).toHaveBeenCalledWith({ session, isEphemeral: false }) + expect(sessionService.refreshTokens).toHaveBeenCalledWith({ + session, + isEphemeral: false, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), + }) expect(result).toEqual({ success: true, - sessionPayload: { - access_token: 'token1', - refresh_token: 'token2', - access_expiration: 123, - refresh_expiration: 234, - }, + result: sessionCreationResult, }) expect(domainEventPublisher.publish).toHaveBeenCalled() @@ -110,31 +158,32 @@ describe('RefreshSessionToken', () => { domainEventPublisher.publish = jest.fn().mockRejectedValue(new Error('test')) const result = await createUseCase().execute({ - accessToken: '123', - refreshToken: '234', - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, }) - expect(sessionService.refreshTokens).toHaveBeenCalledWith({ session, isEphemeral: false }) + expect(sessionService.refreshTokens).toHaveBeenCalledWith({ + session, + isEphemeral: false, + apiVersion: ApiVersion.create(ApiVersion.VERSIONS.v20200115).getValue(), + }) expect(result).toEqual({ success: true, - sessionPayload: { - access_token: 'token1', - refresh_token: 'token2', - access_expiration: 123, - refresh_expiration: 234, - }, + result: sessionCreationResult, }) }) it('should not refresh a session token if session is not found', async () => { - sessionService.getSessionFromToken = jest.fn().mockReturnValue({ session: undefined, isEphemeral: false }) + getSessionFromToken.execute = jest.fn().mockReturnValue(Result.fail('No session found.')) const result = await createUseCase().execute({ - accessToken: '123', - refreshToken: '234', - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '234', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result).toEqual({ @@ -145,12 +194,30 @@ describe('RefreshSessionToken', () => { }) it('should not refresh a session token if refresh token is not valid', async () => { - sessionService.isRefreshTokenMatchingHashedSessionToken = jest.fn().mockReturnValue(false) + const result = await createUseCase().execute({ + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '2345', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, + }) + + expect(result).toEqual({ + success: false, + errorTag: 'invalid-refresh-token', + errorMessage: 'The refresh token is not valid.', + }) + }) + + it('should not refresh a session if the session is cookies based and the refresh token is missing from cookies', async () => { + session.version = SessionService.COOKIE_BASED_SESSION_VERSION + getSessionFromToken.execute = jest.fn().mockReturnValue(Result.ok({ session, isEphemeral: false })) const result = await createUseCase().execute({ - accessToken: '123', - refreshToken: '234', - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', + authTokenFromHeaders: '1:2', + refreshTokenFromHeaders: '2:3', + authCookies: new Map([['access_token_2-3-4', ['1:2']]]), + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result).toEqual({ @@ -164,9 +231,10 @@ describe('RefreshSessionToken', () => { timer.getUTCDate = jest.fn().mockReturnValue(new Date(200)) const result = await createUseCase().execute({ - accessToken: '123', - refreshToken: '234', - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)', + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '1:2:3', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: ApiVersion.VERSIONS.v20200115, }) expect(result).toEqual({ @@ -175,4 +243,19 @@ describe('RefreshSessionToken', () => { errorMessage: 'The refresh token has expired.', }) }) + + it('should not refresh a session token if the api version is invalid', async () => { + const result = await createUseCase().execute({ + authTokenFromHeaders: '123', + refreshTokenFromHeaders: '234', + requestMetadata: { url: '/foobar', method: 'GET', userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)' }, + apiVersion: '', + }) + + expect(result).toEqual({ + success: false, + errorTag: 'invalid-parameters', + errorMessage: 'The provided parameters are not valid.', + }) + }) }) diff --git a/packages/auth/src/Domain/UseCase/RefreshSessionToken.ts b/packages/auth/src/Domain/UseCase/RefreshSessionToken.ts index 846f81e22..fe959b456 100644 --- a/packages/auth/src/Domain/UseCase/RefreshSessionToken.ts +++ b/packages/auth/src/Domain/UseCase/RefreshSessionToken.ts @@ -1,3 +1,4 @@ +import * as crypto from 'crypto' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { TimerInterface } from '@standardnotes/time' import { SettingName } from '@standardnotes/domain-core' @@ -10,6 +11,10 @@ import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterfac import { RefreshSessionTokenResponse } from './RefreshSessionTokenResponse' import { RefreshSessionTokenDTO } from './RefreshSessionTokenDTO' import { GetSetting } from './GetSetting/GetSetting' +import { SessionService } from '../Session/SessionService' +import { ApiVersion } from '../Api/ApiVersion' +import { CooldownSessionTokens } from './CooldownSessionTokens/CooldownSessionTokens' +import { GetSessionFromToken } from './GetSessionFromToken/GetSessionFromToken' export class RefreshSessionToken { constructor( @@ -18,20 +23,87 @@ export class RefreshSessionToken { private domainEventPublisher: DomainEventPublisherInterface, private timer: TimerInterface, private getSetting: GetSetting, + private cooldownSessionTokens: CooldownSessionTokens, + private getSessionFromToken: GetSessionFromToken, private logger: Logger, ) {} async execute(dto: RefreshSessionTokenDTO): Promise { - const { session, isEphemeral } = await this.sessionService.getSessionFromToken(dto.accessToken) - if (!session) { + const apiVersionOrError = ApiVersion.create(dto.apiVersion) + if (apiVersionOrError.isFailed()) { + this.logger.debug(`Invalid API version: ${dto.apiVersion}`, { + codeTag: 'RefreshSessionToken', + }) + return { success: false, errorTag: 'invalid-parameters', errorMessage: 'The provided parameters are not valid.', } } + const apiVersion = apiVersionOrError.getValue() + + const resultOrError = await this.getSessionFromToken.execute({ + authCookies: dto.authCookies, + authTokenFromHeaders: dto.authTokenFromHeaders, + requestMetadata: dto.requestMetadata, + }) + if (resultOrError.isFailed()) { + this.logger.debug('No session found for auth token from headers and cookies', { + codeTag: 'RefreshSessionToken', + }) + + return { + success: false, + errorTag: 'invalid-parameters', + errorMessage: 'The provided parameters are not valid.', + } + } + const { session, isEphemeral, givenTokensWereInCooldown, cooldownHashedRefreshToken } = resultOrError.getValue() + + let hashedRefreshToken = session.hashedRefreshToken + /* istanbul ignore next */ + if (givenTokensWereInCooldown) { + this.logger.warn('Given tokens were in cooldown', { + codeTag: 'RefreshSessionToken', + userId: session?.userUuid, + sessionUuid: session?.uuid, + snjs: dto.requestMetadata.snjs, + application: dto.requestMetadata.application, + url: dto.requestMetadata.url, + method: dto.requestMetadata.method, + userAgent: session.userAgent, + secChUa: session.userAgent ? dto.requestMetadata.secChUa : undefined, + }) + + hashedRefreshToken = cooldownHashedRefreshToken as string + } + + const refreshTokens = + session.version === SessionService.COOKIE_BASED_SESSION_VERSION + ? dto.authCookies?.get(`refresh_token_${session.uuid}`) + : [dto.refreshTokenFromHeaders] + if (!refreshTokens || refreshTokens.length === 0) { + this.logger.debug('No refresh token found for session', { + codeTag: 'RefreshSessionToken', + }) + + return { + success: false, + errorTag: 'invalid-refresh-token', + errorMessage: 'The refresh token is not valid.', + } + } + + const anyRefreshTokenMatchingHashedSessionToken = refreshTokens.some((refreshToken) => + this.isRefreshTokenMatchingHashedSessionToken(session.version, hashedRefreshToken, refreshToken), + ) + + if (!anyRefreshTokenMatchingHashedSessionToken) { + this.logger.debug('Refresh token does not match session', { + codeTag: 'RefreshSessionToken', + }) - if (!this.sessionService.isRefreshTokenMatchingHashedSessionToken(session, dto.refreshToken)) { return { success: false, errorTag: 'invalid-refresh-token', @@ -40,6 +112,10 @@ export class RefreshSessionToken { } if (session.refreshExpiration < this.timer.getUTCDate()) { + this.logger.debug('Refresh token has expired', { + codeTag: 'RefreshSessionToken', + }) + return { success: false, errorTag: 'expired-refresh-token', @@ -48,10 +124,25 @@ export class RefreshSessionToken { } if (await this.isLoggingUserAgentEnabledOnSessions(session.userUuid)) { - session.userAgent = dto.userAgent + session.userAgent = dto.requestMetadata.userAgent as string } - const sessionPayload = await this.sessionService.refreshTokens({ session, isEphemeral }) + const hashedAccessTokenBeforeCooldown = session.hashedAccessToken + const hashedRefreshTokenBeforeCooldown = session.hashedRefreshToken + + const sessionCreationResult = await this.sessionService.refreshTokens({ + session, + isEphemeral, + apiVersion, + snjs: dto.requestMetadata.snjs, + application: dto.requestMetadata.application, + }) + + await this.cooldownSessionTokens.execute({ + sessionUuid: session.uuid, + hashedAccessToken: hashedAccessTokenBeforeCooldown, + hashedRefreshToken: hashedRefreshTokenBeforeCooldown, + }) try { await this.domainEventPublisher.publish( @@ -63,7 +154,7 @@ export class RefreshSessionToken { return { success: true, - sessionPayload, + result: sessionCreationResult, userUuid: session.userUuid, } } @@ -82,4 +173,30 @@ export class RefreshSessionToken { return loggingSetting.decryptedValue === LogSessionUserAgentOption.Enabled } + + private isRefreshTokenMatchingHashedSessionToken( + sessionVersion: number | null, + sessionHashedRefreshToken: string, + token: string, + ): boolean { + let refreshToken = null + switch (sessionVersion) { + case SessionService.COOKIE_BASED_SESSION_VERSION: + refreshToken = token + break + case SessionService.HEADER_BASED_SESSION_VERSION: { + const tokenParts = token.split(':') + refreshToken = tokenParts[2] + break + } + } + + if (!refreshToken) { + return false + } + + const hashedRefreshToken = crypto.createHash('sha256').update(refreshToken).digest('hex') + + return crypto.timingSafeEqual(Buffer.from(hashedRefreshToken), Buffer.from(sessionHashedRefreshToken)) + } } diff --git a/packages/auth/src/Domain/UseCase/RefreshSessionTokenDTO.ts b/packages/auth/src/Domain/UseCase/RefreshSessionTokenDTO.ts index 2a10a6d43..46c93dd64 100644 --- a/packages/auth/src/Domain/UseCase/RefreshSessionTokenDTO.ts +++ b/packages/auth/src/Domain/UseCase/RefreshSessionTokenDTO.ts @@ -1,5 +1,14 @@ export type RefreshSessionTokenDTO = { - accessToken: string - refreshToken: string - userAgent: string + authTokenFromHeaders: string + refreshTokenFromHeaders: string + apiVersion: string + requestMetadata: { + url: string + method: string + snjs?: string + application?: string + userAgent?: string + secChUa?: string + } + authCookies?: Map } diff --git a/packages/auth/src/Domain/UseCase/RefreshSessionTokenResponse.ts b/packages/auth/src/Domain/UseCase/RefreshSessionTokenResponse.ts index 1dfcec810..173168c9a 100644 --- a/packages/auth/src/Domain/UseCase/RefreshSessionTokenResponse.ts +++ b/packages/auth/src/Domain/UseCase/RefreshSessionTokenResponse.ts @@ -1,9 +1,13 @@ -import { SessionBody } from '@standardnotes/responses' +import { SessionCreationResult } from '../Session/SessionCreationResult' -export type RefreshSessionTokenResponse = { - success: boolean - userUuid?: string - errorTag?: string - errorMessage?: string - sessionPayload?: SessionBody -} +export type RefreshSessionTokenResponse = + | { + success: true + result: SessionCreationResult + userUuid: string + } + | { + success: false + errorTag: string + errorMessage: string + } diff --git a/packages/auth/src/Domain/UseCase/Register.spec.ts b/packages/auth/src/Domain/UseCase/Register.spec.ts index ea4a92826..41baab857 100644 --- a/packages/auth/src/Domain/UseCase/Register.spec.ts +++ b/packages/auth/src/Domain/UseCase/Register.spec.ts @@ -21,6 +21,7 @@ describe('Register', () => { let user: User let crypter: CrypterInterface let timer: TimerInterface + let session: Session const createUseCase = () => new Register(userRepository, roleRepository, authResponseFactory, crypter, false, timer, applyDefaultSettings) @@ -39,10 +40,9 @@ describe('Register', () => { roleRepository = {} as jest.Mocked roleRepository.findOneByName = jest.fn().mockReturnValue(null) + session = {} as jest.Mocked authResponseFactory = {} as jest.Mocked - authResponseFactory.createResponse = jest - .fn() - .mockReturnValue({ response: { foo: 'bar' }, session: {} as jest.Mocked }) + authResponseFactory.createResponse = jest.fn().mockReturnValue({ response: { foo: 'bar' }, session }) crypter = {} as jest.Mocked crypter.generateEncryptedUserServerKey = jest.fn().mockReturnValue('test') @@ -69,7 +69,7 @@ describe('Register', () => { pwSalt: 'qweqwe', pwNonce: undefined, }), - ).toEqual({ success: true, authResponse: { foo: 'bar' } }) + ).toEqual({ success: true, result: { response: { foo: 'bar' }, session } }) expect(userRepository.save).toHaveBeenCalledWith({ email: 'test@test.te', @@ -108,44 +108,7 @@ describe('Register', () => { pwSalt: 'qweqwe', pwNonce: undefined, }), - ).toEqual({ success: true, authResponse: { foo: 'bar' } }) - - expect(userRepository.save).toHaveBeenCalledWith({ - email: 'test@test.te', - encryptedPassword: expect.any(String), - encryptedServerKey: 'test', - serverEncryptionVersion: 1, - pwCost: 11, - pwNonce: undefined, - pwSalt: 'qweqwe', - updatedWithUserAgent: 'Mozilla', - uuid: expect.any(String), - version: '004', - createdAt: new Date(1), - updatedAt: new Date(1), - roles: Promise.resolve([role]), - }) - }) - - it('should register a new user with default set of roles on new api version', async () => { - const role = new Role() - role.name = RoleName.NAMES.CoreUser - - roleRepository.findOneByName = jest.fn().mockReturnValueOnce(role) - - expect( - await createUseCase().execute({ - email: 'test@test.te', - password: 'asdzxc', - updatedWithUserAgent: 'Mozilla', - apiVersion: '20240226', - ephemeralSession: false, - version: '004', - pwCost: 11, - pwSalt: 'qweqwe', - pwNonce: undefined, - }), - ).toEqual({ success: true, authResponse: { foo: 'bar' } }) + ).toEqual({ success: true, result: { response: { foo: 'bar' }, session } }) expect(userRepository.save).toHaveBeenCalledWith({ email: 'test@test.te', @@ -280,4 +243,25 @@ describe('Register', () => { expect(userRepository.save).not.toHaveBeenCalled() }) + + it('should fail to register if api version is invalid', async () => { + expect( + await createUseCase().execute({ + email: 'test@test.te', + password: 'asdzxc', + updatedWithUserAgent: 'Mozilla', + apiVersion: '', + ephemeralSession: false, + version: '004', + pwCost: 11, + pwSalt: 'qweqwe', + pwNonce: undefined, + }), + ).toEqual({ + success: false, + errorMessage: 'Invalid api version: ', + }) + + expect(userRepository.save).not.toHaveBeenCalled() + }) }) diff --git a/packages/auth/src/Domain/UseCase/Register.ts b/packages/auth/src/Domain/UseCase/Register.ts index d7558b832..4754ab930 100644 --- a/packages/auth/src/Domain/UseCase/Register.ts +++ b/packages/auth/src/Domain/UseCase/Register.ts @@ -11,7 +11,6 @@ import { UseCaseInterface } from './UseCaseInterface' import { RoleRepositoryInterface } from '../Role/RoleRepositoryInterface' import { CrypterInterface } from '../Encryption/CrypterInterface' import { AuthResponseFactory20200115 } from '../Auth/AuthResponseFactory20200115' -import { AuthResponse20200115 } from '../Auth/AuthResponse20200115' import { ApiVersion } from '../Api/ApiVersion' import { ApplyDefaultSettings } from './ApplyDefaultSettings/ApplyDefaultSettings' @@ -36,7 +35,16 @@ export class Register implements UseCaseInterface { const { email, password, apiVersion, ephemeralSession, ...registrationFields } = dto - if (![ApiVersion.v20200115, ApiVersion.v20240226].includes(apiVersion as ApiVersion)) { + const apiVersionOrError = ApiVersion.create(apiVersion) + if (apiVersionOrError.isFailed()) { + return { + success: false, + errorMessage: apiVersionOrError.getError(), + } + } + const apiVersionVO = apiVersionOrError.getValue() + + if (!apiVersionVO.isSupportedForRegistration()) { return { success: false, errorMessage: `Unsupported api version: ${apiVersion}`, @@ -93,15 +101,17 @@ export class Register implements UseCaseInterface { const result = await this.authResponseFactory20200115.createResponse({ user, - apiVersion, + apiVersion: apiVersionVO, userAgent: dto.updatedWithUserAgent, ephemeralSession, readonlyAccess: false, + snjs: dto.snjs, + application: dto.application, }) return { success: true, - authResponse: result.response as AuthResponse20200115, + result, } } } diff --git a/packages/auth/src/Domain/UseCase/RegisterDTO.ts b/packages/auth/src/Domain/UseCase/RegisterDTO.ts index 85bc1276e..f254eceb0 100644 --- a/packages/auth/src/Domain/UseCase/RegisterDTO.ts +++ b/packages/auth/src/Domain/UseCase/RegisterDTO.ts @@ -10,4 +10,6 @@ export type RegisterDTO = { kpOrigination?: string kpCreated?: string version?: string + snjs?: string + application?: string } diff --git a/packages/auth/src/Domain/UseCase/RegisterResponse.ts b/packages/auth/src/Domain/UseCase/RegisterResponse.ts index 3c05cd103..1bf1368aa 100644 --- a/packages/auth/src/Domain/UseCase/RegisterResponse.ts +++ b/packages/auth/src/Domain/UseCase/RegisterResponse.ts @@ -1,9 +1,9 @@ -import { AuthResponse20200115 } from '../Auth/AuthResponse20200115' +import { AuthResponseCreationResult } from '../Auth/AuthResponseCreationResult' export type RegisterResponse = | { success: true - authResponse: AuthResponse20200115 + result: AuthResponseCreationResult } | { success: false diff --git a/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.spec.ts b/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.spec.ts index 1ea8240c8..9b2c43c03 100644 --- a/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.spec.ts +++ b/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.spec.ts @@ -5,16 +5,26 @@ import { SetSubscriptionSettingValue } from './SetSubscriptionSettingValue' import { Result, SettingName, Timestamps, Uuid } from '@standardnotes/domain-core' import { EncryptionVersion } from '../../Encryption/EncryptionVersion' import { SubscriptionSetting } from '../../Setting/SubscriptionSetting' +import { SettingsAssociationServiceInterface } from '../../Setting/SettingsAssociationServiceInterface' describe('SetSubscriptionSettingValue', () => { let subscriptionSettingRepository: SubscriptionSettingRepositoryInterface let getSubscriptionSetting: GetSubscriptionSetting + let settingsAssociationService: SettingsAssociationServiceInterface let timer: TimerInterface const createUseCase = () => - new SetSubscriptionSettingValue(subscriptionSettingRepository, getSubscriptionSetting, timer) + new SetSubscriptionSettingValue( + subscriptionSettingRepository, + getSubscriptionSetting, + settingsAssociationService, + timer, + ) beforeEach(() => { + settingsAssociationService = {} as jest.Mocked + settingsAssociationService.isSettingMutableByClient = jest.fn().mockReturnValue(true) + subscriptionSettingRepository = {} as jest.Mocked subscriptionSettingRepository.insert = jest.fn() subscriptionSettingRepository.update = jest.fn() @@ -112,6 +122,21 @@ describe('SetSubscriptionSettingValue', () => { expect(subscriptionSettingRepository.insert).toHaveBeenCalled() }) + it('should return error if subscription setting is not mutable by client and a permission check is in order', async () => { + settingsAssociationService.isSettingMutableByClient = jest.fn().mockReturnValue(false) + + const useCase = createUseCase() + + const result = await useCase.execute({ + userSubscriptionUuid: '00000000-0000-0000-0000-000000000000', + settingName: SettingName.NAMES.MuteSignInEmails, + value: 'encrypted', + checkUserPermissions: true, + }) + + expect(result.isFailed()).toBe(true) + }) + it('should return error if subscription setting could not be created', async () => { const mock = jest.spyOn(SubscriptionSetting, 'create') mock.mockReturnValue(Result.fail('Oops')) diff --git a/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.ts b/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.ts index 9336b4ffd..7ae7941ea 100644 --- a/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.ts +++ b/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue.ts @@ -6,15 +6,17 @@ import { SubscriptionSettingRepositoryInterface } from '../../Setting/Subscripti import { GetSubscriptionSetting } from '../GetSubscriptionSetting/GetSubscriptionSetting' import { SubscriptionSetting } from '../../Setting/SubscriptionSetting' import { EncryptionVersion } from '../../Encryption/EncryptionVersion' +import { SettingsAssociationServiceInterface } from '../../Setting/SettingsAssociationServiceInterface' -export class SetSubscriptionSettingValue implements UseCaseInterface { +export class SetSubscriptionSettingValue implements UseCaseInterface { constructor( private subscriptionSettingRepository: SubscriptionSettingRepositoryInterface, private getSubscriptionSetting: GetSubscriptionSetting, + private settingsAssociationService: SettingsAssociationServiceInterface, private timer: TimerInterface, ) {} - async execute(dto: SetSubscriptionSettingValueDTO): Promise> { + async execute(dto: SetSubscriptionSettingValueDTO): Promise> { const userSubscriptionUuidOrError = Uuid.create(dto.userSubscriptionUuid) if (userSubscriptionUuidOrError.isFailed()) { return Result.fail(userSubscriptionUuidOrError.getError()) @@ -40,6 +42,10 @@ export class SetSubscriptionSettingValue implements UseCaseInterface { return Result.fail(`Setting ${settingName.value} is not a subscription setting!`) } + if (dto.checkUserPermissions && !(await this.userHasPermissionToUpdateSetting(settingName))) { + return Result.fail(`User does not have permission to update setting ${settingName.value}.`) + } + const settingExists = await this.getSubscriptionSetting.execute({ userSubscriptionUuid: userSubscriptionUuid.value, settingName: settingName.value, @@ -81,6 +87,12 @@ export class SetSubscriptionSettingValue implements UseCaseInterface { await this.subscriptionSettingRepository.update(setting) - return Result.ok() + return Result.ok(setting) + } + + private async userHasPermissionToUpdateSetting(settingName: SettingName): Promise { + const settingIsMutableByClient = this.settingsAssociationService.isSettingMutableByClient(settingName) + + return settingIsMutableByClient } } diff --git a/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValueDTO.ts b/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValueDTO.ts index f2995dfdc..fe9a57225 100644 --- a/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValueDTO.ts +++ b/packages/auth/src/Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValueDTO.ts @@ -3,4 +3,5 @@ export interface SetSubscriptionSettingValueDTO { userSubscriptionUuid: string value: string | null newUserSubscriptionUuid?: string + checkUserPermissions?: boolean } diff --git a/packages/auth/src/Domain/UseCase/SignIn.spec.ts b/packages/auth/src/Domain/UseCase/SignIn.spec.ts index cd4f7dc0e..b7519dac4 100644 --- a/packages/auth/src/Domain/UseCase/SignIn.spec.ts +++ b/packages/auth/src/Domain/UseCase/SignIn.spec.ts @@ -14,6 +14,9 @@ import { PKCERepositoryInterface } from '../User/PKCERepositoryInterface' import { CrypterInterface } from '../Encryption/CrypterInterface' import { ProtocolVersion } from '@standardnotes/common' import { Session } from '../Session/Session' +import { LockRepositoryInterface } from '../User/LockRepositoryInterface' +import { VerifyHumanInteraction } from './VerifyHumanInteraction/VerifyHumanInteraction' +import { Result } from '@standardnotes/domain-core' describe('SignIn', () => { let user: User @@ -26,6 +29,10 @@ describe('SignIn', () => { let logger: Logger let pkceRepository: PKCERepositoryInterface let crypter: CrypterInterface + let session: Session + let maxNonCaptchaAttempts: number + let lockRepository: LockRepositoryInterface + let verifyHumanInteractionUseCase: VerifyHumanInteraction const createUseCase = () => new SignIn( @@ -37,6 +44,9 @@ describe('SignIn', () => { pkceRepository, crypter, logger, + maxNonCaptchaAttempts, + lockRepository, + verifyHumanInteractionUseCase, ) beforeEach(() => { @@ -50,10 +60,9 @@ describe('SignIn', () => { userRepository = {} as jest.Mocked userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(user) + session = {} as jest.Mocked authResponseFactory = {} as jest.Mocked - authResponseFactory.createResponse = jest - .fn() - .mockReturnValue({ response: { foo: 'bar' }, session: {} as jest.Mocked }) + authResponseFactory.createResponse = jest.fn().mockReturnValue({ response: { foo: 'bar' }, session }) authResponseFactoryResolver = {} as jest.Mocked authResponseFactoryResolver.resolveAuthResponseFactoryVersion = jest.fn().mockReturnValue(authResponseFactory) @@ -78,9 +87,16 @@ describe('SignIn', () => { logger = {} as jest.Mocked logger.debug = jest.fn() logger.error = jest.fn() + + lockRepository = {} as jest.Mocked + lockRepository.getLockCounter = jest.fn().mockReturnValue(0) + + maxNonCaptchaAttempts = 6 }) - it('should sign in a legacy user without code verifier', async () => { + it('should fail sign in a legacy user without code verifier', async () => { + pkceRepository.removeCodeChallenge = jest.fn().mockReturnValue(false) + user.version = ProtocolVersion.V003 userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(user) @@ -91,17 +107,18 @@ describe('SignIn', () => { userAgent: 'Google Chrome', apiVersion: '20190520', ephemeralSession: false, + codeVerifier: '', }), ).toEqual({ - success: true, - authResponse: { foo: 'bar' }, + success: false, + errorCode: 410, + errorMessage: 'Please update your client application.', }) - - expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled() - expect(domainEventPublisher.publish).toHaveBeenCalled() }) it('should not sign in 004 user without code verifier', async () => { + pkceRepository.removeCodeChallenge = jest.fn().mockReturnValue(false) + expect( await createUseCase().execute({ email: 'test@test.te', @@ -109,6 +126,7 @@ describe('SignIn', () => { userAgent: 'Google Chrome', apiVersion: '20190520', ephemeralSession: false, + codeVerifier: '', }), ).toEqual({ success: false, @@ -118,6 +136,8 @@ describe('SignIn', () => { }) it('should not sign in 005 user without code verifier', async () => { + pkceRepository.removeCodeChallenge = jest.fn().mockReturnValue(false) + user = { uuid: '1-2-3', email: 'test@test.com', @@ -131,6 +151,7 @@ describe('SignIn', () => { userAgent: 'Google Chrome', apiVersion: '20190520', ephemeralSession: false, + codeVerifier: '', }), ).toEqual({ success: false, @@ -158,6 +179,25 @@ describe('SignIn', () => { expect(domainEventPublisher.publish).not.toHaveBeenCalled() }) + it('should not sign in a user with invalid api version', async () => { + expect( + await createUseCase().execute({ + email: 'test@test.te', + password: 'qweqwe123123', + userAgent: 'Google Chrome', + apiVersion: 'invalid', + ephemeralSession: false, + codeVerifier: 'test', + }), + ).toEqual({ + success: false, + errorMessage: 'Invalid api version: invalid', + }) + + expect(domainEventFactory.createEmailRequestedEvent).not.toHaveBeenCalled() + expect(domainEventPublisher.publish).not.toHaveBeenCalled() + }) + it('should sign in a user with valid code verifier', async () => { expect( await createUseCase().execute({ @@ -170,7 +210,10 @@ describe('SignIn', () => { }), ).toEqual({ success: true, - authResponse: { foo: 'bar' }, + result: { + response: { foo: 'bar' }, + session, + }, }) expect(domainEventFactory.createEmailRequestedEvent).toHaveBeenCalled() @@ -193,7 +236,10 @@ describe('SignIn', () => { }), ).toEqual({ success: true, - authResponse: { foo: 'bar' }, + result: { + response: { foo: 'bar' }, + session, + }, }) }) @@ -248,4 +294,75 @@ describe('SignIn', () => { errorMessage: 'Invalid email or password', }) }) + + it('should sign in a user with valid code verifier and invalid hvm token but not requiring human verification', async () => { + verifyHumanInteractionUseCase = {} as jest.Mocked + verifyHumanInteractionUseCase.execute = jest + .fn() + .mockReturnValueOnce(Result.fail('Human verification step failed.')) + + expect( + await createUseCase().execute({ + email: 'test@test.te', + password: 'qweqwe123123', + userAgent: 'Google Chrome', + apiVersion: '20190520', + ephemeralSession: false, + codeVerifier: 'test', + }), + ).toEqual({ + success: true, + result: { + response: { foo: 'bar' }, + session, + }, + }) + }) + + it('should sign in a user with valid code verifier and valid hvm token requiring human verification', async () => { + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(maxNonCaptchaAttempts) + verifyHumanInteractionUseCase = {} as jest.Mocked + verifyHumanInteractionUseCase.execute = jest.fn().mockReturnValueOnce(Result.ok()) + + expect( + await createUseCase().execute({ + email: 'test@test.te', + password: 'qweqwe123123', + userAgent: 'Google Chrome', + apiVersion: '20190520', + ephemeralSession: false, + codeVerifier: 'test', + hvmToken: 'foobar', + }), + ).toEqual({ + success: true, + result: { + response: { foo: 'bar' }, + session, + }, + }) + }) + + it('should not sign in a user with valid code verifier and invalid hvm token requiring human verification', async () => { + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(maxNonCaptchaAttempts) + verifyHumanInteractionUseCase = {} as jest.Mocked + verifyHumanInteractionUseCase.execute = jest + .fn() + .mockReturnValueOnce(Result.fail('Human verification step failed.')) + + expect( + await createUseCase().execute({ + email: 'test@test.te', + password: 'qweqwe123123', + userAgent: 'Google Chrome', + apiVersion: '20190520', + ephemeralSession: false, + codeVerifier: 'test', + hvmToken: 'foobar', + }), + ).toEqual({ + success: false, + errorMessage: 'Human verification step failed.', + }) + }) }) diff --git a/packages/auth/src/Domain/UseCase/SignIn.ts b/packages/auth/src/Domain/UseCase/SignIn.ts index 32d7304c6..80c3f19e2 100644 --- a/packages/auth/src/Domain/UseCase/SignIn.ts +++ b/packages/auth/src/Domain/UseCase/SignIn.ts @@ -1,9 +1,7 @@ import * as bcrypt from 'bcryptjs' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' -import { inject, injectable } from 'inversify' import { Logger } from 'winston' -import TYPES from '../../Bootstrap/Types' import { AuthResponseFactoryResolverInterface } from '../Auth/AuthResponseFactoryResolverInterface' import { DomainEventFactoryInterface } from '../Event/DomainEventFactoryInterface' import { SessionServiceInterface } from '../Session/SessionServiceInterface' @@ -14,40 +12,56 @@ import { SignInResponse } from './SignInResponse' import { UseCaseInterface } from './UseCaseInterface' import { PKCERepositoryInterface } from '../User/PKCERepositoryInterface' import { CrypterInterface } from '../Encryption/CrypterInterface' -import { SignInDTOV2Challenged } from './SignInDTOV2Challenged' -import { leftVersionGreaterThanOrEqualToRight, ProtocolVersion } from '@standardnotes/common' -import { HttpStatusCode } from '@standardnotes/responses' -import { EmailLevel, Username } from '@standardnotes/domain-core' +import { EmailLevel, Result, Username } from '@standardnotes/domain-core' import { getBody, getSubject } from '../Email/UserSignedIn' +import { ApiVersion } from '../Api/ApiVersion' +import { HttpStatusCode } from '@standardnotes/responses' +import { VerifyHumanInteraction } from './VerifyHumanInteraction/VerifyHumanInteraction' +import { LockRepositoryInterface } from '../User/LockRepositoryInterface' -@injectable() export class SignIn implements UseCaseInterface { constructor( - @inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface, - @inject(TYPES.Auth_AuthResponseFactoryResolver) + private userRepository: UserRepositoryInterface, private authResponseFactoryResolver: AuthResponseFactoryResolverInterface, - @inject(TYPES.Auth_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface, - @inject(TYPES.Auth_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface, - @inject(TYPES.Auth_SessionService) private sessionService: SessionServiceInterface, - @inject(TYPES.Auth_PKCERepository) private pkceRepository: PKCERepositoryInterface, - @inject(TYPES.Auth_Crypter) private crypter: CrypterInterface, - @inject(TYPES.Auth_Logger) private logger: Logger, + private domainEventPublisher: DomainEventPublisherInterface, + private domainEventFactory: DomainEventFactoryInterface, + private sessionService: SessionServiceInterface, + private pkceRepository: PKCERepositoryInterface, + private crypter: CrypterInterface, + private logger: Logger, + private maxNonCaptchaAttempts: number, + private lockRepository: LockRepositoryInterface, + private verifyHumanInteractionUseCase: VerifyHumanInteraction, ) {} async execute(dto: SignInDTO): Promise { - const performingCodeChallengedSignIn = this.isCodeChallengedVersion(dto) - if (performingCodeChallengedSignIn) { - const validCodeVerifier = await this.validateCodeVerifier(dto.codeVerifier) - if (!validCodeVerifier) { - this.logger.debug('Code verifier does not match') - - return { - success: false, - errorMessage: 'Invalid email or password', - } + if (!dto.codeVerifier) { + return { + success: false, + errorMessage: 'Please update your client application.', + errorCode: HttpStatusCode.Gone, } } + const validCodeVerifier = await this.validateCodeVerifier(dto.codeVerifier) + if (!validCodeVerifier) { + this.logger.debug('Code verifier does not match') + + return { + success: false, + errorMessage: 'Invalid email or password', + } + } + + const apiVersionOrError = ApiVersion.create(dto.apiVersion) + if (apiVersionOrError.isFailed()) { + return { + success: false, + errorMessage: apiVersionOrError.getError(), + } + } + const apiVersion = apiVersionOrError.getValue() + const usernameOrError = Username.create(dto.email) if (usernameOrError.isFailed()) { return { @@ -58,6 +72,18 @@ export class SignIn implements UseCaseInterface { const username = usernameOrError.getValue() const user = await this.userRepository.findOneByUsernameOrEmail(username) + const userIdentifier = user?.uuid ?? dto.email + + const humanVerificationBeforeCheckingUsernameAndPasswordResult = await this.checkHumanVerificationIfNeeded( + userIdentifier, + dto.hvmToken, + ) + if (humanVerificationBeforeCheckingUsernameAndPasswordResult.isFailed()) { + return { + success: false, + errorMessage: humanVerificationBeforeCheckingUsernameAndPasswordResult.getError(), + } + } if (!user) { this.logger.debug(`User with email ${dto.email} was not found`) @@ -68,19 +94,6 @@ export class SignIn implements UseCaseInterface { } } - const userVersionIs004OrGreater = leftVersionGreaterThanOrEqualToRight( - user.version as ProtocolVersion, - ProtocolVersion.V004, - ) - - if (userVersionIs004OrGreater && !performingCodeChallengedSignIn) { - return { - success: false, - errorMessage: 'Please update your client application.', - errorCode: HttpStatusCode.Gone, - } - } - const passwordMatches = await bcrypt.compare(dto.password, user.encryptedPassword) if (!passwordMatches) { this.logger.debug('Password does not match') @@ -91,21 +104,23 @@ export class SignIn implements UseCaseInterface { } } - const authResponseFactory = this.authResponseFactoryResolver.resolveAuthResponseFactoryVersion(dto.apiVersion) + const authResponseFactory = this.authResponseFactoryResolver.resolveAuthResponseFactoryVersion(apiVersion) await this.sendSignInEmailNotification(user, dto.userAgent) const result = await authResponseFactory.createResponse({ user, - apiVersion: dto.apiVersion, + apiVersion, userAgent: dto.userAgent, ephemeralSession: dto.ephemeralSession, readonlyAccess: false, + snjs: dto.snjs, + application: dto.application, }) return { success: true, - authResponse: result.response, + result, } } @@ -139,7 +154,17 @@ export class SignIn implements UseCaseInterface { } } - private isCodeChallengedVersion(dto: SignInDTO): dto is SignInDTOV2Challenged { - return (dto as SignInDTOV2Challenged).codeVerifier !== undefined + private async checkHumanVerificationIfNeeded(userIdentifier: string, hvmToken?: string): Promise> { + const numberOfFailedAttempts = await this.lockRepository.getLockCounter(userIdentifier, 'non-captcha') + const numberOfFailedAttemptsInCaptchaMode = await this.lockRepository.getLockCounter(userIdentifier, 'captcha') + + const isEligibleForNonCaptchaMode = + numberOfFailedAttemptsInCaptchaMode === 0 && numberOfFailedAttempts < this.maxNonCaptchaAttempts + + if (isEligibleForNonCaptchaMode) { + return Result.ok() + } + + return this.verifyHumanInteractionUseCase.execute(hvmToken) } } diff --git a/packages/auth/src/Domain/UseCase/SignInDTO.ts b/packages/auth/src/Domain/UseCase/SignInDTO.ts index b8e58c1d0..c0c7467c3 100644 --- a/packages/auth/src/Domain/UseCase/SignInDTO.ts +++ b/packages/auth/src/Domain/UseCase/SignInDTO.ts @@ -1,4 +1,11 @@ -import { SignInDTOV1Unchallenged } from './SignInDTOV1Unchallenged' -import { SignInDTOV2Challenged } from './SignInDTOV2Challenged' - -export type SignInDTO = SignInDTOV1Unchallenged | SignInDTOV2Challenged +export type SignInDTO = { + apiVersion: string + userAgent: string + email: string + password: string + ephemeralSession: boolean + codeVerifier: string + hvmToken?: string + snjs?: string + application?: string +} diff --git a/packages/auth/src/Domain/UseCase/SignInResponse.ts b/packages/auth/src/Domain/UseCase/SignInResponse.ts index 91e40cce1..43576493f 100644 --- a/packages/auth/src/Domain/UseCase/SignInResponse.ts +++ b/packages/auth/src/Domain/UseCase/SignInResponse.ts @@ -1,11 +1,14 @@ import { HttpStatusCode } from '@standardnotes/responses' -import { AuthResponse20161215 } from '../Auth/AuthResponse20161215' -import { AuthResponse20200115 } from '../Auth/AuthResponse20200115' +import { AuthResponseCreationResult } from '../Auth/AuthResponseCreationResult' -export type SignInResponse = { - success: boolean - authResponse?: AuthResponse20161215 | AuthResponse20200115 - errorMessage?: string - errorCode?: HttpStatusCode -} +export type SignInResponse = + | { + success: false + errorMessage: string + errorCode?: HttpStatusCode + } + | { + success: true + result: AuthResponseCreationResult + } diff --git a/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.spec.ts b/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.spec.ts index 7d55e5d58..b94396766 100644 --- a/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.spec.ts +++ b/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.spec.ts @@ -14,6 +14,9 @@ import { GenerateRecoveryCodes } from '../GenerateRecoveryCodes/GenerateRecovery import { IncreaseLoginAttempts } from '../IncreaseLoginAttempts' import { SignInWithRecoveryCodes } from './SignInWithRecoveryCodes' import { GetSetting } from '../GetSetting/GetSetting' +import { ApiVersion } from '../../Api/ApiVersion' +import { LockRepositoryInterface } from '../../User/LockRepositoryInterface' +import { VerifyHumanInteraction } from '../VerifyHumanInteraction/VerifyHumanInteraction' describe('SignInWithRecoveryCodes', () => { let userRepository: UserRepositoryInterface @@ -26,6 +29,9 @@ describe('SignInWithRecoveryCodes', () => { let deleteSetting: DeleteSetting let authenticatorRepository: AuthenticatorRepositoryInterface let getSetting: GetSetting + let maxNonCaptchaAttempts: number + let lockRepository: LockRepositoryInterface + let verifyHumanInteractionUseCase: VerifyHumanInteraction const createUseCase = () => new SignInWithRecoveryCodes( @@ -39,6 +45,9 @@ describe('SignInWithRecoveryCodes', () => { clearLoginAttempts, deleteSetting, authenticatorRepository, + maxNonCaptchaAttempts, + lockRepository, + verifyHumanInteractionUseCase, ) beforeEach(() => { @@ -77,10 +86,16 @@ describe('SignInWithRecoveryCodes', () => { authenticatorRepository = {} as jest.Mocked authenticatorRepository.removeByUserUuid = jest.fn() + + lockRepository = {} as jest.Mocked + lockRepository.getLockCounter = jest.fn().mockReturnValue(0) + + maxNonCaptchaAttempts = 6 }) it('should return error if password is not provided', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: '', @@ -94,6 +109,7 @@ describe('SignInWithRecoveryCodes', () => { it('should return error if username is not provided', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: '', password: 'qweqwe123123', @@ -107,6 +123,7 @@ describe('SignInWithRecoveryCodes', () => { it('should return error if code verifier is not provided', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'username', password: 'qweqwe123123', @@ -120,6 +137,7 @@ describe('SignInWithRecoveryCodes', () => { it('should return error if recovery codes are not provided', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'username', password: 'qweqwe123123', @@ -135,6 +153,7 @@ describe('SignInWithRecoveryCodes', () => { pkceRepository.removeCodeChallenge = jest.fn().mockReturnValue(false) const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', @@ -150,6 +169,7 @@ describe('SignInWithRecoveryCodes', () => { userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(undefined) const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', @@ -163,6 +183,7 @@ describe('SignInWithRecoveryCodes', () => { it('should return error if recovery codes are invalid', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', @@ -174,8 +195,35 @@ describe('SignInWithRecoveryCodes', () => { expect(result.getError()).toBe('Invalid recovery codes') }) + it('should return error if api version is invalid', async () => { + const result = await createUseCase().execute({ + apiVersion: 'invalid', + userAgent: 'user-agent', + username: 'test@test.te', + password: 'qweqwe123123', + codeVerifier: 'code-verifier', + recoveryCodes: '1234 5678', + }) + + expect(result.isFailed()).toBe(true) + }) + + it('should return error if api version does not support recovery sign in', async () => { + const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20161215, + userAgent: 'user-agent', + username: 'test@test.te', + password: 'qweqwe123123', + codeVerifier: 'code-verifier', + recoveryCodes: '1234 5678', + }) + + expect(result.isFailed()).toBe(true) + }) + it('should return error if password does not match', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'asdasd123123', @@ -191,6 +239,7 @@ describe('SignInWithRecoveryCodes', () => { getSetting.execute = jest.fn().mockReturnValue(Result.fail('not found')) const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', @@ -206,6 +255,7 @@ describe('SignInWithRecoveryCodes', () => { generateRecoveryCodes.execute = jest.fn().mockReturnValue(Result.fail('Oops')) const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', @@ -224,6 +274,7 @@ describe('SignInWithRecoveryCodes', () => { } as jest.Mocked) const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', @@ -235,8 +286,49 @@ describe('SignInWithRecoveryCodes', () => { expect(result.getError()).toBe('Invalid user uuid') }) + it('should return error if user requires human verification but no hvmtoken provided', async () => { + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(maxNonCaptchaAttempts) + verifyHumanInteractionUseCase = {} as jest.Mocked + verifyHumanInteractionUseCase.execute = jest + .fn() + .mockReturnValueOnce(Result.fail('Human verification step failed.')) + + const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, + userAgent: 'user-agent', + username: 'test@test.te', + password: 'qweqwe123123', + codeVerifier: 'code-verifier', + recoveryCodes: 'foo', + }) + + expect(result.isFailed()).toBe(true) + expect(result.getError()).toBe('Human verification step failed.') + }) + + it('should return auth response with human verification required and passing', async () => { + lockRepository.getLockCounter = jest.fn().mockReturnValueOnce(maxNonCaptchaAttempts) + verifyHumanInteractionUseCase = {} as jest.Mocked + verifyHumanInteractionUseCase.execute = jest.fn().mockReturnValueOnce(Result.ok()) + + const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, + userAgent: 'user-agent', + username: 'test@test.te', + password: 'qweqwe123123', + codeVerifier: 'code-verifier', + recoveryCodes: 'foo', + }) + + expect(clearLoginAttempts.execute).toHaveBeenCalled() + expect(deleteSetting.execute).toHaveBeenCalled() + expect(authenticatorRepository.removeByUserUuid).toHaveBeenCalled() + expect(result.isFailed()).toBe(false) + }) + it('should return auth response', async () => { const result = await createUseCase().execute({ + apiVersion: ApiVersion.VERSIONS.v20200115, userAgent: 'user-agent', username: 'test@test.te', password: 'qweqwe123123', diff --git a/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.ts b/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.ts index 7e318c588..bf7e829fe 100644 --- a/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.ts +++ b/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes.ts @@ -15,6 +15,8 @@ import { DeleteSetting } from '../DeleteSetting/DeleteSetting' import { AuthenticatorRepositoryInterface } from '../../Authenticator/AuthenticatorRepositoryInterface' import { ApiVersion } from '../../Api/ApiVersion' import { GetSetting } from '../GetSetting/GetSetting' +import { LockRepositoryInterface } from '../../User/LockRepositoryInterface' +import { VerifyHumanInteraction } from '../VerifyHumanInteraction/VerifyHumanInteraction' export class SignInWithRecoveryCodes implements UseCaseInterface { constructor( @@ -28,15 +30,39 @@ export class SignInWithRecoveryCodes implements UseCaseInterface> { + const apiVersionOrError = ApiVersion.create(dto.apiVersion) + if (apiVersionOrError.isFailed()) { + return Result.fail(apiVersionOrError.getError()) + } + const apiVersion = apiVersionOrError.getValue() + + if (!apiVersion.isSupportedForRecoverySignIn()) { + return Result.fail('Unsupported api version') + } + const usernameOrError = Username.create(dto.username) if (usernameOrError.isFailed()) { return Result.fail(`Could not sign in with recovery codes: ${usernameOrError.getError()}`) } const username = usernameOrError.getValue() + const user = await this.userRepository.findOneByUsernameOrEmail(username) + const userIdentifier = user?.uuid + + const humanVerificationBeforeCheckingUsernameAndPasswordResult = await this.checkHumanVerificationIfNeeded( + userIdentifier, + dto.hvmToken, + ) + if (humanVerificationBeforeCheckingUsernameAndPasswordResult.isFailed()) { + return Result.fail(humanVerificationBeforeCheckingUsernameAndPasswordResult.getError()) + } + const validCodeVerifier = await this.validateCodeVerifier(dto.codeVerifier) if (!validCodeVerifier) { await this.increaseLoginAttempts.execute({ email: username.value }) @@ -58,8 +84,6 @@ export class SignInWithRecoveryCodes implements UseCaseInterface> { + if (!userIdentifier) { + return Result.ok() + } + + const numberOfFailedAttempts = await this.lockRepository.getLockCounter(userIdentifier, 'non-captcha') + const numberOfFailedAttemptsInCaptchaMode = await this.lockRepository.getLockCounter(userIdentifier, 'captcha') + + const isEligibleForNonCaptchaMode = + numberOfFailedAttemptsInCaptchaMode === 0 && numberOfFailedAttempts < this.maxNonCaptchaAttempts + + if (isEligibleForNonCaptchaMode) { + return Result.ok() + } + + return this.verifyHumanInteractionUseCase.execute(hvmToken) + } } diff --git a/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodesDTO.ts b/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodesDTO.ts index f921ba528..7ae63b14e 100644 --- a/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodesDTO.ts +++ b/packages/auth/src/Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodesDTO.ts @@ -1,7 +1,11 @@ export interface SignInWithRecoveryCodesDTO { + apiVersion: string userAgent: string username: string password: string codeVerifier: string recoveryCodes: string + hvmToken?: string + snjs?: string + application?: string } diff --git a/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.spec.ts b/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.spec.ts index ded2aa598..342aaf3d2 100644 --- a/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.spec.ts +++ b/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.spec.ts @@ -1,46 +1,23 @@ import { DomainEventPublisherInterface, EmailBackupRequestedEvent } from '@standardnotes/domain-events' -import { Result, SettingName, Timestamps, Uuid } from '@standardnotes/domain-core' import { RoleServiceInterface } from '../../Role/RoleServiceInterface' -import { GetSetting } from '../GetSetting/GetSetting' import { GetUserKeyParams } from '../GetUserKeyParams/GetUserKeyParams' import { TriggerEmailBackupForUser } from './TriggerEmailBackupForUser' import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface' -import { Setting } from '../../Setting/Setting' -import { EncryptionVersion } from '../../Encryption/EncryptionVersion' describe('TriggerEmailBackupForUser', () => { let roleService: RoleServiceInterface - let getSetting: GetSetting let getUserKeyParamsUseCase: GetUserKeyParams let domainEventPublisher: DomainEventPublisherInterface let domainEventFactory: DomainEventFactoryInterface const createUseCase = () => - new TriggerEmailBackupForUser( - roleService, - getSetting, - getUserKeyParamsUseCase, - domainEventPublisher, - domainEventFactory, - ) + new TriggerEmailBackupForUser(roleService, getUserKeyParamsUseCase, domainEventPublisher, domainEventFactory) beforeEach(() => { roleService = {} as jest.Mocked roleService.userHasPermission = jest.fn().mockResolvedValue(true) - const setting = Setting.create({ - name: SettingName.NAMES.ListedAuthorSecrets, - value: null, - serverEncryptionVersion: EncryptionVersion.Default, - userUuid: Uuid.create('00000000-0000-0000-0000-000000000000').getValue(), - sensitive: false, - timestamps: Timestamps.create(123, 123).getValue(), - }).getValue() - - getSetting = {} as jest.Mocked - getSetting.execute = jest.fn().mockResolvedValue(Result.ok({ setting, decryptedValue: 'not_muted' })) - getUserKeyParamsUseCase = {} as jest.Mocked getUserKeyParamsUseCase.execute = jest.fn().mockResolvedValue({ keyParams: {} }) diff --git a/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.ts b/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.ts index f753cc530..ce9bec073 100644 --- a/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.ts +++ b/packages/auth/src/Domain/UseCase/TriggerEmailBackupForUser/TriggerEmailBackupForUser.ts @@ -1,10 +1,8 @@ -import { Result, SettingName, UseCaseInterface, Uuid } from '@standardnotes/domain-core' +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' import { PermissionName } from '@standardnotes/features' import { TriggerEmailBackupForUserDTO } from './TriggerEmailBackupForUserDTO' import { RoleServiceInterface } from '../../Role/RoleServiceInterface' -import { GetSetting } from '../GetSetting/GetSetting' -import { MuteFailedBackupsEmailsOption } from '@standardnotes/settings' import { GetUserKeyParams } from '../GetUserKeyParams/GetUserKeyParams' import { DomainEventPublisherInterface } from '@standardnotes/domain-events' import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface' @@ -12,7 +10,6 @@ import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInter export class TriggerEmailBackupForUser implements UseCaseInterface { constructor( private roleService: RoleServiceInterface, - private getSetting: GetSetting, private getUserKeyParamsUseCase: GetUserKeyParams, private domainEventPublisher: DomainEventPublisherInterface, private domainEventFactory: DomainEventFactoryInterface, @@ -34,31 +31,13 @@ export class TriggerEmailBackupForUser implements UseCaseInterface { return Result.fail(`User ${userUuid.value} is not permitted for email backups`) } - let userHasEmailsMuted = false - const emailsMutedSettingOrError = await this.getSetting.execute({ - allowSensitiveRetrieval: true, - decrypted: true, - settingName: SettingName.NAMES.MuteFailedBackupsEmails, - userUuid: userUuid.value, - }) - let emailsMutedSetting = null - if (!emailsMutedSettingOrError.isFailed()) { - emailsMutedSetting = emailsMutedSettingOrError.getValue() - userHasEmailsMuted = emailsMutedSetting.decryptedValue === MuteFailedBackupsEmailsOption.Muted - } - const keyParamsResponse = await this.getUserKeyParamsUseCase.execute({ userUuid: userUuid.value, authenticated: false, }) await this.domainEventPublisher.publish( - this.domainEventFactory.createEmailBackupRequestedEvent( - userUuid.value, - emailsMutedSetting?.setting.id.toString() as string, - userHasEmailsMuted, - keyParamsResponse.keyParams, - ), + this.domainEventFactory.createEmailBackupRequestedEvent(userUuid.value, keyParamsResponse.keyParams), ) return Result.ok() diff --git a/packages/auth/src/Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions.ts b/packages/auth/src/Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions.ts index e8096e562..338f3ecf1 100644 --- a/packages/auth/src/Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions.ts +++ b/packages/auth/src/Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions.ts @@ -9,8 +9,6 @@ import { GenerateRecoveryCodes } from '../GenerateRecoveryCodes/GenerateRecovery export class TriggerPostSettingUpdateActions implements UseCaseInterface { private readonly emailSettingToSubscriptionRejectionLevelMap: Map = new Map([ - [SettingName.NAMES.MuteFailedBackupsEmails, EmailLevel.LEVELS.FailedEmailBackup], - [SettingName.NAMES.MuteFailedCloudBackupsEmails, EmailLevel.LEVELS.FailedCloudBackup], [SettingName.NAMES.MuteMarketingEmails, EmailLevel.LEVELS.Marketing], [SettingName.NAMES.MuteSignInEmails, EmailLevel.LEVELS.SignIn], ]) @@ -47,12 +45,7 @@ export class TriggerPostSettingUpdateActions implements UseCaseInterface { } private isChangingMuteEmailsSetting(settingName: string): boolean { - return [ - SettingName.NAMES.MuteFailedBackupsEmails, - SettingName.NAMES.MuteFailedCloudBackupsEmails, - SettingName.NAMES.MuteMarketingEmails, - SettingName.NAMES.MuteSignInEmails, - ].includes(settingName) + return [SettingName.NAMES.MuteMarketingEmails, SettingName.NAMES.MuteSignInEmails].includes(settingName) } private isEnablingEmailBackupSetting(settingName: string, newValue: string | null): boolean { diff --git a/packages/auth/src/Domain/UseCase/UpdateUser.spec.ts b/packages/auth/src/Domain/UseCase/UpdateUser.spec.ts deleted file mode 100644 index 7ac155ff5..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateUser.spec.ts +++ /dev/null @@ -1,60 +0,0 @@ -import 'reflect-metadata' - -import { TimerInterface } from '@standardnotes/time' - -import { User } from '../User/User' -import { UserRepositoryInterface } from '../User/UserRepositoryInterface' -import { AuthResponseFactoryInterface } from '../Auth/AuthResponseFactoryInterface' -import { AuthResponseFactoryResolverInterface } from '../Auth/AuthResponseFactoryResolverInterface' - -import { UpdateUser } from './UpdateUser' -import { Session } from '../Session/Session' - -describe('UpdateUser', () => { - let userRepository: UserRepositoryInterface - let authResponseFactoryResolver: AuthResponseFactoryResolverInterface - let authResponseFactory: AuthResponseFactoryInterface - let user: User - let timer: TimerInterface - - const createUseCase = () => new UpdateUser(userRepository, authResponseFactoryResolver, timer) - - beforeEach(() => { - userRepository = {} as jest.Mocked - userRepository.save = jest.fn() - userRepository.findOneByUsernameOrEmail = jest.fn().mockReturnValue(undefined) - - authResponseFactory = {} as jest.Mocked - authResponseFactory.createResponse = jest - .fn() - .mockReturnValue({ response: { foo: 'bar' }, session: {} as jest.Mocked }) - - authResponseFactoryResolver = {} as jest.Mocked - authResponseFactoryResolver.resolveAuthResponseFactoryVersion = jest.fn().mockReturnValue(authResponseFactory) - - user = {} as jest.Mocked - user.uuid = '123' - user.email = 'test@test.te' - user.createdAt = new Date(1) - - timer = {} as jest.Mocked - timer.getUTCDate = jest.fn().mockReturnValue(new Date(1)) - }) - - it('should update user fields and save it', async () => { - expect( - await createUseCase().execute({ - user, - updatedWithUserAgent: 'Mozilla', - apiVersion: '20190520', - }), - ).toEqual({ success: true, authResponse: { foo: 'bar' } }) - - expect(userRepository.save).toHaveBeenCalledWith({ - createdAt: new Date(1), - email: 'test@test.te', - uuid: '123', - updatedAt: new Date(1), - }) - }) -}) diff --git a/packages/auth/src/Domain/UseCase/UpdateUser.ts b/packages/auth/src/Domain/UseCase/UpdateUser.ts deleted file mode 100644 index ed831ed5d..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateUser.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { TimerInterface } from '@standardnotes/time' -import { inject, injectable } from 'inversify' -import TYPES from '../../Bootstrap/Types' -import { AuthResponseFactoryResolverInterface } from '../Auth/AuthResponseFactoryResolverInterface' -import { UserRepositoryInterface } from '../User/UserRepositoryInterface' -import { UpdateUserDTO } from './UpdateUserDTO' -import { UpdateUserResponse } from './UpdateUserResponse' -import { UseCaseInterface } from './UseCaseInterface' - -@injectable() -export class UpdateUser implements UseCaseInterface { - constructor( - @inject(TYPES.Auth_UserRepository) private userRepository: UserRepositoryInterface, - @inject(TYPES.Auth_AuthResponseFactoryResolver) - private authResponseFactoryResolver: AuthResponseFactoryResolverInterface, - @inject(TYPES.Auth_Timer) private timer: TimerInterface, - ) {} - - async execute(dto: UpdateUserDTO): Promise { - dto.user.updatedAt = this.timer.getUTCDate() - - const updatedUser = await this.userRepository.save(dto.user) - - const authResponseFactory = this.authResponseFactoryResolver.resolveAuthResponseFactoryVersion(dto.apiVersion) - - const result = await authResponseFactory.createResponse({ - user: updatedUser, - apiVersion: dto.apiVersion, - userAgent: dto.updatedWithUserAgent, - ephemeralSession: false, - readonlyAccess: false, - }) - - return { - success: true, - authResponse: result.response, - } - } -} diff --git a/packages/auth/src/Domain/UseCase/UpdateUserDTO.ts b/packages/auth/src/Domain/UseCase/UpdateUserDTO.ts deleted file mode 100644 index efc2dd13d..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateUserDTO.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { User } from '../User/User' - -export type UpdateUserDTO = { - user: User - apiVersion: string - updatedWithUserAgent: string -} diff --git a/packages/auth/src/Domain/UseCase/UpdateUserResponse.ts b/packages/auth/src/Domain/UseCase/UpdateUserResponse.ts deleted file mode 100644 index 81e8ab629..000000000 --- a/packages/auth/src/Domain/UseCase/UpdateUserResponse.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AuthResponse20161215 } from '../Auth/AuthResponse20161215' -import { AuthResponse20200115 } from '../Auth/AuthResponse20200115' - -export type UpdateUserResponse = { - success: boolean - authResponse?: AuthResponse20161215 | AuthResponse20200115 -} diff --git a/packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.spec.ts b/packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.spec.ts new file mode 100644 index 000000000..070892bcc --- /dev/null +++ b/packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.spec.ts @@ -0,0 +1,43 @@ +import { VerifyHumanInteraction } from './VerifyHumanInteraction' +import { CaptchaServerInterface } from '../../HumanVerification/CaptchaServerInterface' + +describe('HumanVerification', () => { + let captchaServer: CaptchaServerInterface + const createHumanVerification = () => new VerifyHumanInteraction(true, captchaServer) + + beforeEach(() => { + captchaServer = {} as jest.Mocked + captchaServer.verify = jest.fn().mockReturnValue(true) + }) + + describe('Verified', () => { + it('should pass human verification', async () => { + captchaServer.verify = jest.fn().mockReturnValue(true) + const result = await createHumanVerification().execute('foobar') + expect(result.isFailed()).toBeFalsy() + }) + + it('should not pass human verification if token is missing', async () => { + const result = await createHumanVerification().execute() + expect(result.isFailed()).toBeTruthy() + }) + + it('should pass human verification when verification disabled', async () => { + const result = await new VerifyHumanInteraction(false, captchaServer).execute('foobar') + expect(result.isFailed()).toBeFalsy() + }) + + it('should pass human verification when no captcha url defined', async () => { + const result = await new VerifyHumanInteraction(true, captchaServer).execute('foobar') + expect(result.isFailed()).toBeFalsy() + }) + }) + + describe('Unverified', () => { + it('should pass not human verification', async () => { + captchaServer.verify = jest.fn().mockReturnValue(false) + const result = await createHumanVerification().execute('foobar') + expect(result.isFailed()).toBeTruthy() + }) + }) +}) diff --git a/packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.ts b/packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.ts new file mode 100644 index 000000000..cee5293bf --- /dev/null +++ b/packages/auth/src/Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction.ts @@ -0,0 +1,23 @@ +import { Result, UseCaseInterface } from '@standardnotes/domain-core' +import { CaptchaServerInterface } from '../../HumanVerification/CaptchaServerInterface' + +export class VerifyHumanInteraction implements UseCaseInterface { + constructor( + private isEnabled: boolean, + private captchaServer: CaptchaServerInterface, + ) {} + + async execute(hvmToken?: string): Promise> { + if (!this.isEnabled) { + return Result.ok() + } + + if (!hvmToken) { + return Result.fail('No HVM token available.') + } + + const isSuccess = await this.captchaServer.verify(hvmToken) + + return isSuccess ? Result.ok() : Result.fail('Human verification step failed.') + } +} diff --git a/packages/auth/src/Domain/User/LockRepositoryInterface.ts b/packages/auth/src/Domain/User/LockRepositoryInterface.ts index 820b5bf93..bfe53b352 100644 --- a/packages/auth/src/Domain/User/LockRepositoryInterface.ts +++ b/packages/auth/src/Domain/User/LockRepositoryInterface.ts @@ -1,8 +1,7 @@ export interface LockRepositoryInterface { resetLockCounter(userIdentifier: string): Promise - updateLockCounter(userIdentifier: string, counter: number): Promise - getLockCounter(userIdentifier: string): Promise - lockUser(userIdentifier: string): Promise + updateLockCounter(userIdentifier: string, counter: number, mode: 'captcha' | 'non-captcha'): Promise + getLockCounter(userIdentifier: string, mode: 'captcha' | 'non-captcha'): Promise isUserLocked(userIdentifier: string): Promise lockSuccessfullOTP(userIdentifier: string, otp: string): Promise isOTPLocked(userIdentifier: string, otp: string): Promise diff --git a/packages/auth/src/Infra/Http/HumanVerification/HttpCaptchaServer.ts b/packages/auth/src/Infra/Http/HumanVerification/HttpCaptchaServer.ts new file mode 100644 index 000000000..4d31a0f13 --- /dev/null +++ b/packages/auth/src/Infra/Http/HumanVerification/HttpCaptchaServer.ts @@ -0,0 +1,31 @@ +import { AxiosInstance } from 'axios' +import { Logger } from 'winston' + +import { CaptchaServerInterface } from '../../../Domain/HumanVerification/CaptchaServerInterface' + +export class HttpCaptchaServer implements CaptchaServerInterface { + constructor( + private logger: Logger, + private httpClient: AxiosInstance, + private captchaServerUrl?: string, + ) {} + + async verify(hvmToken: string): Promise { + if (!this.captchaServerUrl) { + return true + } + + try { + const response = await this.httpClient.request({ + method: 'GET', + url: `${this.captchaServerUrl}/verify?token=${hvmToken}`, + }) + const data = response.data + + return data.status === 'pass' + } catch (error) { + this.logger.error('Could not get result from captcha server', error) + return false + } + } +} diff --git a/packages/auth/src/Infra/InMemory/InMemorySessionTokensCooldownRepository.ts b/packages/auth/src/Infra/InMemory/InMemorySessionTokensCooldownRepository.ts new file mode 100644 index 000000000..9d758f774 --- /dev/null +++ b/packages/auth/src/Infra/InMemory/InMemorySessionTokensCooldownRepository.ts @@ -0,0 +1,41 @@ +import { Uuid } from '@standardnotes/domain-core' +import { SessionTokensCooldownRepositoryInterface } from '../../Domain/Session/SessionTokensCooldownRepositoryInterface' + +export class InMemorySessionTokensCooldownRepository implements SessionTokensCooldownRepositoryInterface { + private inMemoryStore: Map + private readonly COOLDOWN_FORMAT_VERSION = 1 + + constructor() { + this.inMemoryStore = new Map() + } + + async getHashedTokens(sessionUuid: Uuid): Promise<{ hashedAccessToken: string; hashedRefreshToken: string } | null> { + const result = this.inMemoryStore.get(sessionUuid.value) + if (!result) { + return null + } + + const [version, hashedAccessToken, hashedRefreshToken] = result.split(':') + + if (parseInt(version) !== this.COOLDOWN_FORMAT_VERSION) { + return null + } + + return { + hashedAccessToken, + hashedRefreshToken, + } + } + + async setCooldown(dto: { + sessionUuid: Uuid + hashedAccessToken: string + hashedRefreshToken: string + cooldownPeriodInSeconds: number + }): Promise { + this.inMemoryStore.set( + dto.sessionUuid.value, + `${this.COOLDOWN_FORMAT_VERSION}:${dto.hashedAccessToken}:${dto.hashedRefreshToken}`, + ) + } +} diff --git a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts index ea8cb156c..02ba113af 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts @@ -13,18 +13,20 @@ import { BaseAdminController } from './Base/BaseAdminController' import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken' import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken' import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting' +import { GetSetting } from './../../Domain/UseCase/GetSetting/GetSetting' import { UserRepositoryInterface } from '../../Domain/User/UserRepositoryInterface' @controller('/admin') export class AnnotatedAdminController extends BaseAdminController { constructor( @inject(TYPES.Auth_DeleteSetting) override doDeleteSetting: DeleteSetting, + @inject(TYPES.Auth_GetSetting) override doGetSetting: GetSetting, @inject(TYPES.Auth_UserRepository) override userRepository: UserRepositoryInterface, @inject(TYPES.Auth_CreateSubscriptionToken) override createSubscriptionToken: CreateSubscriptionToken, @inject(TYPES.Auth_CreateOfflineSubscriptionToken) override createOfflineSubscriptionToken: CreateOfflineSubscriptionToken, ) { - super(doDeleteSetting, userRepository, createSubscriptionToken, createOfflineSubscriptionToken) + super(doDeleteSetting, doGetSetting, userRepository, createSubscriptionToken, createOfflineSubscriptionToken) } @httpGet('/user/:email') @@ -32,6 +34,11 @@ export class AnnotatedAdminController extends BaseAdminController { return super.getUser(request) } + @httpGet('/users/:userUuid/listed-code') + override async getListedCode(request: Request): Promise { + return super.getListedCode(request) + } + @httpDelete('/users/:userUuid/mfa') override async deleteMFASetting(request: Request): Promise { return super.deleteMFASetting(request) diff --git a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAuthController.ts b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAuthController.ts index 6a8a8bff4..07fda89aa 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAuthController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAuthController.ts @@ -1,7 +1,6 @@ import { Request, Response } from 'express' import { controller, - httpGet, httpPost, // eslint-disable-next-line @typescript-eslint/no-unused-vars results, @@ -17,6 +16,14 @@ import { GetUserKeyParams } from '../../Domain/UseCase/GetUserKeyParams/GetUserK import { AuthController } from '../../Controller/AuthController' import { inject } from 'inversify' import { BaseAuthController } from './Base/BaseAuthController' +import { DomainEventPublisherInterface } from '@standardnotes/domain-events' +import { DomainEventFactoryInterface } from '../../Domain/Event/DomainEventFactoryInterface' +import { Register } from '../../Domain/UseCase/Register' +import { SessionServiceInterface } from '../../Domain/Session/SessionServiceInterface' +import { VerifyHumanInteraction } from '../../Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction' +import { CookieFactoryInterface } from '../../Domain/Auth/Cookies/CookieFactoryInterface' +import { SignInWithRecoveryCodes } from '../../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes' +import { DeleteSessionByToken } from '../../Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken' @controller('/auth') export class AnnotatedAuthController extends BaseAuthController { @@ -28,18 +35,34 @@ export class AnnotatedAuthController extends BaseAuthController { @inject(TYPES.Auth_IncreaseLoginAttempts) override increaseLoginAttempts: IncreaseLoginAttempts, @inject(TYPES.Auth_Logger) override logger: Logger, @inject(TYPES.Auth_AuthController) override authController: AuthController, + @inject(TYPES.Auth_Register) override registerUser: Register, + @inject(TYPES.Auth_DomainEventPublisher) override domainEventPublisher: DomainEventPublisherInterface, + @inject(TYPES.Auth_DomainEventFactory) override domainEventFactory: DomainEventFactoryInterface, + @inject(TYPES.Auth_SessionService) override sessionService: SessionServiceInterface, + @inject(TYPES.Auth_VerifyHumanInteraction) override humanVerificationUseCase: VerifyHumanInteraction, + @inject(TYPES.Auth_CookieFactory) override cookieFactory: CookieFactoryInterface, + @inject(TYPES.Auth_SignInWithRecoveryCodes) override signInWithRecoveryCodes: SignInWithRecoveryCodes, + @inject(TYPES.Auth_DeleteSessionByToken) override deleteSessionByToken: DeleteSessionByToken, + @inject(TYPES.Auth_CAPTCHA_UI_URL) override captchaUIUrl: string, ) { - super(verifyMFA, signInUseCase, getUserKeyParams, clearLoginAttempts, increaseLoginAttempts, logger, authController) - } - - @httpGet('/params', TYPES.Auth_OptionalCrossServiceTokenMiddleware) - override async params(request: Request, response: Response): Promise { - return super.params(request, response) - } - - @httpPost('/sign_in', TYPES.Auth_LockMiddleware) - override async signIn(request: Request): Promise { - return super.signIn(request) + super( + verifyMFA, + signInUseCase, + getUserKeyParams, + clearLoginAttempts, + increaseLoginAttempts, + logger, + authController, + registerUser, + domainEventPublisher, + domainEventFactory, + sessionService, + humanVerificationUseCase, + cookieFactory, + signInWithRecoveryCodes, + deleteSessionByToken, + captchaUIUrl, + ) } @httpPost('/pkce_params', TYPES.Auth_OptionalCrossServiceTokenMiddleware) @@ -48,8 +71,8 @@ export class AnnotatedAuthController extends BaseAuthController { } @httpPost('/pkce_sign_in', TYPES.Auth_LockMiddleware) - override async pkceSignIn(request: Request): Promise { - return super.pkceSignIn(request) + override async pkceSignIn(request: Request, response: Response): Promise { + return super.pkceSignIn(request, response) } @httpPost('/recovery/codes', TYPES.Auth_RequiredCrossServiceTokenMiddleware) @@ -58,8 +81,8 @@ export class AnnotatedAuthController extends BaseAuthController { } @httpPost('/recovery/login', TYPES.Auth_LockMiddleware) - override async recoveryLogin(request: Request): Promise { - return super.recoveryLogin(request) + override async recoveryLogin(request: Request, response: Response): Promise { + return super.recoveryLogin(request, response) } @httpPost('/recovery/params') @@ -73,7 +96,7 @@ export class AnnotatedAuthController extends BaseAuthController { } @httpPost('/') - override async register(request: Request): Promise { - return super.register(request) + override async register(request: Request, response: Response): Promise { + return super.register(request, response) } } diff --git a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSessionController.ts b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSessionController.ts index d03b1169d..4453659e9 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSessionController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSessionController.ts @@ -12,6 +12,7 @@ import { DeleteOtherSessionsForUser } from '../../Domain/UseCase/DeleteOtherSess import { DeleteSessionForUser } from '../../Domain/UseCase/DeleteSessionForUser' import { RefreshSessionToken } from '../../Domain/UseCase/RefreshSessionToken' import { BaseSessionController } from './Base/BaseSessionController' +import { CookieFactoryInterface } from '../../Domain/Auth/Cookies/CookieFactoryInterface' @controller('/session') export class AnnotatedSessionController extends BaseSessionController { @@ -20,8 +21,9 @@ export class AnnotatedSessionController extends BaseSessionController { @inject(TYPES.Auth_DeleteOtherSessionsForUser) override deleteOtherSessionsForUser: DeleteOtherSessionsForUser, @inject(TYPES.Auth_RefreshSessionToken) override refreshSessionToken: RefreshSessionToken, + @inject(TYPES.Auth_CookieFactory) override cookieFactory: CookieFactoryInterface, ) { - super(deleteSessionForUser, deleteOtherSessionsForUser, refreshSessionToken) + super(deleteSessionForUser, deleteOtherSessionsForUser, refreshSessionToken, cookieFactory) } @httpDelete('/', TYPES.Auth_RequiredCrossServiceTokenMiddleware, TYPES.Auth_SessionMiddleware) diff --git a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSubscriptionSettingsController.ts b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSubscriptionSettingsController.ts index 1c9e2efe3..fca92625a 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSubscriptionSettingsController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedSubscriptionSettingsController.ts @@ -3,6 +3,7 @@ import { inject } from 'inversify' import { controller, httpGet, + httpPut, // eslint-disable-next-line @typescript-eslint/no-unused-vars results, } from 'inversify-express-utils' @@ -13,6 +14,9 @@ import { GetSubscriptionSetting } from '../../Domain/UseCase/GetSubscriptionSett import { MapperInterface } from '@standardnotes/domain-core' import { SubscriptionSetting } from '../../Domain/Setting/SubscriptionSetting' import { SubscriptionSettingHttpRepresentation } from '../../Mapping/Http/SubscriptionSettingHttpRepresentation' +import { SetSubscriptionSettingValue } from '../../Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue' +import { TriggerPostSettingUpdateActions } from '../../Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions' +import { Logger } from 'winston' @controller('/users/:userUuid') export class AnnotatedSubscriptionSettingsController extends BaseSubscriptionSettingsController { @@ -20,14 +24,33 @@ export class AnnotatedSubscriptionSettingsController extends BaseSubscriptionSet @inject(TYPES.Auth_GetSubscriptionSetting) override doGetSetting: GetSubscriptionSetting, @inject(TYPES.Auth_GetSharedOrRegularSubscriptionForUser) override getSharedOrRegularSubscription: GetSharedOrRegularSubscriptionForUser, + @inject(TYPES.Auth_SetSubscriptionSettingValue) override setSubscriptionSettingValue: SetSubscriptionSettingValue, + @inject(TYPES.Auth_TriggerPostSettingUpdateActions) + override triggerPostSettingUpdateActions: TriggerPostSettingUpdateActions, @inject(TYPES.Auth_SubscriptionSettingHttpMapper) override subscriptionSettingMapper: MapperInterface, + @inject(TYPES.Auth_Logger) override logger: Logger, ) { - super(doGetSetting, getSharedOrRegularSubscription, subscriptionSettingMapper) + super( + doGetSetting, + getSharedOrRegularSubscription, + setSubscriptionSettingValue, + triggerPostSettingUpdateActions, + subscriptionSettingMapper, + logger, + ) } @httpGet('/subscription-settings/:subscriptionSettingName', TYPES.Auth_RequiredCrossServiceTokenMiddleware) override async getSubscriptionSetting(request: Request, response: Response): Promise { return super.getSubscriptionSetting(request, response) } + + @httpPut('/subscription-settings', TYPES.Auth_RequiredCrossServiceTokenMiddleware) + override async updateSubscriptionSetting( + request: Request, + response: Response, + ): Promise { + return super.updateSubscriptionSetting(request, response) + } } diff --git a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedUsersController.ts b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedUsersController.ts index 07f1f0996..2d6136404 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedUsersController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedUsersController.ts @@ -15,6 +15,7 @@ import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts' import { IncreaseLoginAttempts } from '../../Domain/UseCase/IncreaseLoginAttempts' import { ChangeCredentials } from '../../Domain/UseCase/ChangeCredentials/ChangeCredentials' import { BaseUsersController } from './Base/BaseUsersController' +import { CookieFactoryInterface } from '../../Domain/Auth/Cookies/CookieFactoryInterface' @controller('/users') export class AnnotatedUsersController extends BaseUsersController { @@ -24,8 +25,16 @@ export class AnnotatedUsersController extends BaseUsersController { @inject(TYPES.Auth_ClearLoginAttempts) override clearLoginAttempts: ClearLoginAttempts, @inject(TYPES.Auth_IncreaseLoginAttempts) override increaseLoginAttempts: IncreaseLoginAttempts, @inject(TYPES.Auth_ChangeCredentials) override changeCredentialsUseCase: ChangeCredentials, + @inject(TYPES.Auth_CookieFactory) override cookieFactory: CookieFactoryInterface, ) { - super(doDeleteAccount, doGetUserSubscription, clearLoginAttempts, increaseLoginAttempts, changeCredentialsUseCase) + super( + doDeleteAccount, + doGetUserSubscription, + clearLoginAttempts, + increaseLoginAttempts, + changeCredentialsUseCase, + cookieFactory, + ) } @httpDelete('/:userUuid', TYPES.Auth_RequiredCrossServiceTokenMiddleware) diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts index a17f87826..22f40b8cf 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts @@ -4,12 +4,15 @@ import { Request } from 'express' import { CreateOfflineSubscriptionToken } from '../../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken' import { CreateSubscriptionToken } from '../../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken' +import { GetSetting } from './../../../Domain/UseCase/GetSetting/GetSetting' import { DeleteSetting } from '../../../Domain/UseCase/DeleteSetting/DeleteSetting' import { UserRepositoryInterface } from '../../../Domain/User/UserRepositoryInterface' +import { ListedAuthorSecretsData } from '@standardnotes/settings' export class BaseAdminController extends BaseHttpController { constructor( protected doDeleteSetting: DeleteSetting, + protected doGetSetting: GetSetting, protected userRepository: UserRepositoryInterface, protected createSubscriptionToken: CreateSubscriptionToken, protected createOfflineSubscriptionToken: CreateOfflineSubscriptionToken, @@ -77,6 +80,31 @@ export class BaseAdminController extends BaseHttpController { return this.json(result, 400) } + async getListedCode(request: Request): Promise { + const { userUuid } = request.params + + const result = await this.doGetSetting.execute({ + userUuid, + settingName: SettingName.NAMES.ListedAuthorSecrets, + allowSensitiveRetrieval: false, + decrypted: true, + }) + + if (result.isFailed()) { + return this.json('No listed code found', 404) + } + + const decryptedValue = result.getValue().decryptedValue + + if (!decryptedValue) { + return this.json({ error: 'No listed code found' }, 404) + } + + const data: ListedAuthorSecretsData = JSON.parse(decryptedValue as string) + + return this.json(data) + } + async createToken(request: Request): Promise { const { userUuid } = request.params const result = await this.createSubscriptionToken.execute({ diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAuthController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAuthController.ts index 9acb04625..a6500f68a 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAuthController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAuthController.ts @@ -10,6 +10,18 @@ import { VerifyMFA } from '../../../Domain/UseCase/VerifyMFA' import { AuthController } from '../../../Controller/AuthController' import { ResponseLocals } from '../ResponseLocals' import { BaseHttpController, results } from 'inversify-express-utils' +import { Session } from '../../../Domain/Session/Session' +import { ErrorTag, HttpStatusCode } from '@standardnotes/responses' +import { Register } from '../../../Domain/UseCase/Register' +import { ProtocolVersion } from '@standardnotes/common' +import { DomainEventPublisherInterface } from '@standardnotes/domain-events' +import { DomainEventFactoryInterface } from '../../../Domain/Event/DomainEventFactoryInterface' +import { SessionServiceInterface } from '../../../Domain/Session/SessionServiceInterface' +import { AuthResponse20161215 } from '../../../Domain/Auth/AuthResponse20161215' +import { VerifyHumanInteraction } from '../../../Domain/UseCase/VerifyHumanInteraction/VerifyHumanInteraction' +import { CookieFactoryInterface } from '../../../Domain/Auth/Cookies/CookieFactoryInterface' +import { SignInWithRecoveryCodes } from '../../../Domain/UseCase/SignInWithRecoveryCodes/SignInWithRecoveryCodes' +import { DeleteSessionByToken } from '../../../Domain/UseCase/DeleteSessionByToken/DeleteSessionByToken' export class BaseAuthController extends BaseHttpController { constructor( @@ -20,13 +32,20 @@ export class BaseAuthController extends BaseHttpController { protected increaseLoginAttempts: IncreaseLoginAttempts, protected logger: Logger, protected authController: AuthController, - private controllerContainer?: ControllerContainerInterface, + protected registerUser: Register, + protected domainEventPublisher: DomainEventPublisherInterface, + protected domainEventFactory: DomainEventFactoryInterface, + protected sessionService: SessionServiceInterface, + protected humanVerificationUseCase: VerifyHumanInteraction, + protected cookieFactory: CookieFactoryInterface, + protected signInWithRecoveryCodes: SignInWithRecoveryCodes, + protected deleteSessionByToken: DeleteSessionByToken, + protected captchaUIUrl: string, + protected controllerContainer?: ControllerContainerInterface, ) { super() if (this.controllerContainer !== undefined) { - this.controllerContainer.register('auth.params', this.params.bind(this)) - this.controllerContainer.register('auth.signIn', this.signIn.bind(this)) this.controllerContainer.register('auth.pkceParams', this.pkceParams.bind(this)) this.controllerContainer.register('auth.pkceSignIn', this.pkceSignIn.bind(this)) this.controllerContainer.register('auth.users.register', this.register.bind(this)) @@ -37,116 +56,6 @@ export class BaseAuthController extends BaseHttpController { } } - async params(request: Request, response: Response): Promise { - const locals = response.locals as ResponseLocals - - if (locals.session) { - const result = await this.getUserKeyParams.execute({ - email: locals.user.email, - authenticated: true, - }) - - return this.json(result.keyParams) - } - - if (!request.query.email) { - return this.json( - { - error: { - message: 'Please provide an email address.', - }, - }, - 400, - ) - } - - const verifyMFAResponse = await this.verifyMFA.execute({ - email: request.query.email, - requestParams: request.query, - preventOTPFromFurtherUsage: false, - }) - - if (!verifyMFAResponse.success) { - return this.json( - { - error: { - tag: verifyMFAResponse.errorTag, - message: verifyMFAResponse.errorMessage, - payload: verifyMFAResponse.errorPayload, - }, - }, - 401, - ) - } - - const result = await this.getUserKeyParams.execute({ - email: request.query.email, - authenticated: false, - }) - - return this.json(result.keyParams) - } - - async signIn(request: Request): Promise { - if (!request.body.email || !request.body.password) { - this.logger.debug('/auth/sign_in request missing credentials: %O', request.body) - - return this.json( - { - error: { - tag: 'invalid-auth', - message: 'Invalid login credentials.', - }, - }, - 401, - ) - } - - const verifyMFAResponse = await this.verifyMFA.execute({ - email: request.body.email, - requestParams: request.body, - preventOTPFromFurtherUsage: true, - }) - - if (!verifyMFAResponse.success) { - return this.json( - { - error: { - tag: verifyMFAResponse.errorTag, - message: verifyMFAResponse.errorMessage, - payload: verifyMFAResponse.errorPayload, - }, - }, - 401, - ) - } - - const signInResult = await this.signInUseCase.execute({ - apiVersion: request.body.api, - userAgent: request.headers['user-agent'], - email: request.body.email, - password: request.body.password, - ephemeralSession: request.body.ephemeral ?? false, - }) - - if (!signInResult.success) { - await this.increaseLoginAttempts.execute({ email: request.body.email }) - - return this.json( - { - error: { - message: signInResult.errorMessage, - }, - }, - signInResult.errorCode ?? 401, - ) - } - - await this.clearLoginAttempts.execute({ email: request.body.email }) - - return this.json(signInResult.authResponse) - } - async pkceParams(request: Request, response: Response): Promise { const locals = response.locals as ResponseLocals @@ -210,9 +119,9 @@ export class BaseAuthController extends BaseHttpController { return this.json(result.keyParams) } - async pkceSignIn(request: Request): Promise { + async pkceSignIn(request: Request, response: Response): Promise { if (!request.body.email || !request.body.password || !request.body.code_verifier) { - this.logger.debug('/auth/sign_in request missing credentials: %O', request.body) + this.logger.debug('/auth/pkce_sign_in request missing credentials: %O', request.body) return this.json( { @@ -232,10 +141,21 @@ export class BaseAuthController extends BaseHttpController { password: request.body.password, ephemeralSession: request.body.ephemeral ?? false, codeVerifier: request.body.code_verifier, + hvmToken: request.body.hvm_token, + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, }) if (!signInResult.success) { - await this.increaseLoginAttempts.execute({ email: request.body.email }) + const resultOrError = await this.increaseLoginAttempts.execute({ email: request.body.email }) + if (resultOrError.isFailed()) { + this.logger.error(`Failed to increase login attempts ${resultOrError.getError()}`) + } else { + const result = resultOrError.getValue() + if (result.isNonCaptchaLimitReached) { + response.setHeader('x-captcha-required', this.captchaUIUrl) + } + } return this.json( { @@ -249,7 +169,28 @@ export class BaseAuthController extends BaseHttpController { await this.clearLoginAttempts.execute({ email: request.body.email }) - return this.json(signInResult.authResponse) + if (signInResult.result.response !== undefined) { + const session = signInResult.result.session as Session + const user = signInResult.result.response.user + + response.setHeader( + 'Set-Cookie', + this.cookieFactory.createCookieHeaderValue({ + sessionUuid: session.uuid, + accessToken: signInResult.result.cookies?.accessToken as string, + refreshToken: signInResult.result.cookies?.refreshToken as string, + refreshTokenExpiration: session.refreshExpiration, + }), + ) + + return this.json({ + session: signInResult.result.response.sessionBody, + key_params: signInResult.result.response.keyParams, + user, + }) + } + + return this.json(signInResult.result.legacyResponse) } async generateRecoveryCodes(_request: Request, response: Response): Promise { @@ -262,17 +203,53 @@ export class BaseAuthController extends BaseHttpController { return this.json(result.data, result.status) } - async recoveryLogin(request: Request): Promise { - const result = await this.authController.signInWithRecoveryCodes({ + async recoveryLogin(request: Request, response: Response): Promise { + const result = await this.signInWithRecoveryCodes.execute({ apiVersion: request.body.api_version, userAgent: request.headers['user-agent'], codeVerifier: request.body.code_verifier, username: request.body.username, recoveryCodes: request.body.recovery_codes, password: request.body.password, + hvmToken: request.body.hvm_token, + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, }) - return this.json(result.data, result.status) + if (result.isFailed()) { + this.logger.debug(`Failed to sign in with recovery codes: ${result.getError()}`) + + const increasLoginAttemtpsResultOrError = await this.increaseLoginAttempts.execute({ + email: request.body.username, + }) + if (increasLoginAttemtpsResultOrError.isFailed()) { + this.logger.error(`Failed to increase login attempts ${increasLoginAttemtpsResultOrError.getError()}`) + } else { + const increasLoginAttemtpsResult = increasLoginAttemtpsResultOrError.getValue() + if (increasLoginAttemtpsResult.isNonCaptchaLimitReached) { + response.setHeader('x-captcha-required', this.captchaUIUrl) + } + } + + return this.json( + { + error: { + message: 'Invalid login credentials.', + }, + }, + HttpStatusCode.Unauthorized, + ) + } + + await this.clearLoginAttempts.execute({ email: request.body.username }) + + const signInWithRecoveryCodesResult = result.getValue() + + return this.json({ + session: signInWithRecoveryCodesResult.sessionBody, + key_params: signInWithRecoveryCodesResult.keyParams, + user: signInWithRecoveryCodesResult.user, + }) } async recoveryParams(request: Request): Promise { @@ -289,24 +266,160 @@ export class BaseAuthController extends BaseHttpController { async signOut(request: Request, response: Response): Promise { const locals = response.locals as ResponseLocals - const result = await this.authController.signOut({ - readOnlyAccess: locals.readOnlyAccess, - authorizationHeader: request.headers.authorization, - }) - - if (result.headers?.has('x-invalidate-cache')) { - response.setHeader('x-invalidate-cache', result.headers.get('x-invalidate-cache') as string) + if (locals.readOnlyAccess) { + return this.json( + { + error: { + tag: ErrorTag.ReadOnlyAccess, + message: 'Session has read-only access.', + }, + }, + HttpStatusCode.Unauthorized, + ) } - return this.json(result.data, result.status) - } - - async register(request: Request): Promise { - const response = await this.authController.register({ - ...request.body, - userAgent: request.headers['user-agent'], + const authCookies = new Map() + request.headers.cookie?.split(';').forEach((cookie) => { + const parts = cookie.split('=') + if (parts.length === 2 && parts[0].trim().startsWith('access_token_')) { + const existingCookies = authCookies.get(parts[0].trim()) + if (existingCookies) { + existingCookies.push(parts[1].trim()) + authCookies.set(parts[0].trim(), existingCookies) + } else { + authCookies.set(parts[0].trim(), [parts[1].trim()]) + } + } }) - return this.json(response.data, response.status) + const authTokenFromHeaders = (request.headers.authorization as string).replace('Bearer ', '') + + const resultOrError = await this.deleteSessionByToken.execute({ + authTokenFromHeaders, + authCookies, + requestMetadata: { + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, + url: request.headers['x-origin-url'] as string, + method: request.headers['x-origin-method'] as string, + userAgent: request.headers['x-origin-user-agent'] as string, + secChUa: request.headers['x-origin-sec-ch-ua'] as string, + }, + }) + if (resultOrError.isFailed()) { + return this.json( + { + error: { + message: 'Invalid session token.', + }, + }, + HttpStatusCode.Unauthorized, + ) + } + const session = resultOrError.getValue() + + response.setHeader( + 'Set-Cookie', + this.cookieFactory.createCookieHeaderValue({ + sessionUuid: session.uuid, + accessToken: '0', + refreshToken: '0', + refreshTokenExpiration: new Date(1), + }), + ) + + if (session.userUuid !== null) { + response.setHeader('x-invalidate-cache', session.userUuid) + } + + return this.json({}, HttpStatusCode.NoContent) + } + + async register(request: Request, response: Response): Promise { + const hvmToken = request.body.hvm_token + const humanVerificationResult = await this.humanVerificationUseCase.execute(hvmToken) + + if (humanVerificationResult.isFailed()) { + return this.json( + { + error: { + message: humanVerificationResult.getError(), + }, + }, + HttpStatusCode.BadRequest, + ) + } + + if (!request.body.email || !request.body.password) { + return this.json( + { + error: { + message: 'Please enter an email and a password to register.', + }, + }, + HttpStatusCode.BadRequest, + ) + } + + const registerResult = await this.registerUser.execute({ + email: request.body.email, + password: request.body.password, + updatedWithUserAgent: request.headers['user-agent'] as string, + apiVersion: request.body.api, + ephemeralSession: request.body.ephemeral, + pwNonce: request.body.pw_nonce, + kpOrigination: request.body.origination, + kpCreated: request.body.created, + version: request.body.version, + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, + }) + + if (!registerResult.success) { + return this.json( + { + error: { + message: registerResult.errorMessage, + }, + }, + HttpStatusCode.BadRequest, + ) + } + + const registeredUser = registerResult.result.response + ? registerResult.result.response.user + : (registerResult.result.legacyResponse as AuthResponse20161215).user + + await this.clearLoginAttempts.execute({ email: registeredUser.email }) + + await this.domainEventPublisher.publish( + this.domainEventFactory.createUserRegisteredEvent({ + userUuid: registeredUser.uuid, + email: registeredUser.email, + protocolVersion: registeredUser.protocolVersion as ProtocolVersion, + }), + ) + + if (registerResult.result.response === undefined) { + return this.json(registerResult.result.legacyResponse) + } + + const session = registerResult.result.session as Session + + response.setHeader( + 'Set-Cookie', + this.cookieFactory.createCookieHeaderValue({ + sessionUuid: session.uuid, + accessToken: registerResult.result.cookies?.accessToken as string, + refreshToken: registerResult.result.cookies?.refreshToken as string, + refreshTokenExpiration: session.refreshExpiration, + }), + ) + + return this.json({ + session: registerResult.result.response.sessionBody, + key_params: registerResult.result.response.keyParams, + user: registeredUser, + }) } } diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionController.ts index 8e6243ad9..6b05f3992 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionController.ts @@ -7,12 +7,16 @@ import { DeleteOtherSessionsForUser } from '../../../Domain/UseCase/DeleteOtherS import { DeleteSessionForUser } from '../../../Domain/UseCase/DeleteSessionForUser' import { RefreshSessionToken } from '../../../Domain/UseCase/RefreshSessionToken' import { ResponseLocals } from '../ResponseLocals' +import { Session } from '../../../Domain/Session/Session' +import { ApiVersion } from '../../../Domain/Api/ApiVersion' +import { CookieFactoryInterface } from '../../../Domain/Auth/Cookies/CookieFactoryInterface' export class BaseSessionController extends BaseHttpController { constructor( protected deleteSessionForUser: DeleteSessionForUser, protected deleteOtherSessionsForUser: DeleteOtherSessionsForUser, protected refreshSessionToken: RefreshSessionToken, + protected cookieFactory: CookieFactoryInterface, private controllerContainer?: ControllerContainerInterface, ) { super() @@ -134,27 +138,65 @@ export class BaseSessionController extends BaseHttpController { ) } - const result = await this.refreshSessionToken.execute({ - accessToken: request.body.access_token, - refreshToken: request.body.refresh_token, - userAgent: request.headers['user-agent'], + const authCookies = new Map() + request.headers.cookie?.split(';').forEach((cookie) => { + const parts = cookie.split('=') + if ( + parts.length === 2 && + (parts[0].trim().startsWith('access_token_') || parts[0].trim().startsWith('refresh_token_')) + ) { + const existingCookies = authCookies.get(parts[0].trim()) + if (existingCookies) { + existingCookies.push(parts[1].trim()) + authCookies.set(parts[0].trim(), existingCookies) + } else { + authCookies.set(parts[0].trim(), [parts[1].trim()]) + } + } }) - if (!result.success) { + const refreshResult = await this.refreshSessionToken.execute({ + apiVersion: request.body.api ?? ApiVersion.VERSIONS.v20200115, + authTokenFromHeaders: request.body.access_token, + refreshTokenFromHeaders: request.body.refresh_token, + requestMetadata: { + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, + url: request.headers['x-origin-url'] as string, + method: request.headers['x-origin-method'] as string, + userAgent: request.headers['x-origin-user-agent'] as string, + secChUa: request.headers['x-origin-sec-ch-ua'] as string, + }, + authCookies, + }) + + if (!refreshResult.success) { return this.json( { error: { - tag: result.errorTag, - message: result.errorMessage, + tag: refreshResult.errorTag, + message: refreshResult.errorMessage, }, }, 400, ) } - response.setHeader('x-invalidate-cache', result.userUuid as string) + const session = refreshResult.result.session as Session + + response.setHeader('x-invalidate-cache', refreshResult.userUuid as string) + response.setHeader( + 'Set-Cookie', + this.cookieFactory.createCookieHeaderValue({ + sessionUuid: session.uuid, + accessToken: refreshResult.result.sessionCookieRepresentation.accessToken, + refreshToken: refreshResult.result.sessionCookieRepresentation.refreshToken, + refreshTokenExpiration: session.refreshExpiration, + }), + ) + return this.json({ - session: result.sessionPayload, + session: refreshResult.result.sessionHttpRepresentation, }) } } diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionsController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionsController.ts index 89d69f6f8..49eb2fc32 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionsController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSessionsController.ts @@ -28,8 +28,31 @@ export class BaseSessionsController extends BaseHttpController { } async validate(request: Request): Promise { + const authCookies = new Map() + request.headers.cookie?.split(';').forEach((cookie) => { + const parts = cookie.split('=') + if (parts.length === 2 && parts[0].trim().startsWith('access_token_')) { + const existingCookies = authCookies.get(parts[0].trim()) + if (existingCookies) { + existingCookies.push(parts[1].trim()) + authCookies.set(parts[0].trim(), existingCookies) + } else { + authCookies.set(parts[0].trim(), [parts[1].trim()]) + } + } + }) + const authenticateRequestResponse = await this.authenticateRequest.execute({ - authorizationHeader: request.headers.authorization, + authTokenFromHeaders: request.body.authTokenFromHeaders, + authCookies, + requestMetadata: { + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, + url: request.headers['x-origin-url'] as string, + method: request.headers['x-origin-method'] as string, + userAgent: request.headers['x-origin-user-agent'] as string, + secChUa: request.headers['x-origin-sec-ch-ua'] as string, + }, }) if (!authenticateRequestResponse.success) { @@ -46,7 +69,7 @@ export class BaseSessionsController extends BaseHttpController { const user = authenticateRequestResponse.user as User - const sharedVaultOwnerContext = request.headers['x-shared-vault-owner-context'] as string | undefined + const sharedVaultOwnerContext = request.body.sharedVaultOwnerContext as string | undefined const resultOrError = await this.createCrossServiceToken.execute({ user, diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSubscriptionSettingsController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSubscriptionSettingsController.ts index 262178f50..e5f42d84a 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSubscriptionSettingsController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseSubscriptionSettingsController.ts @@ -1,24 +1,35 @@ import { ControllerContainerInterface, MapperInterface } from '@standardnotes/domain-core' import { BaseHttpController, results } from 'inversify-express-utils' import { Request, Response } from 'express' +import { Logger } from 'winston' +import { ErrorTag } from '@standardnotes/responses' import { GetSubscriptionSetting } from '../../../Domain/UseCase/GetSubscriptionSetting/GetSubscriptionSetting' import { GetSharedOrRegularSubscriptionForUser } from '../../../Domain/UseCase/GetSharedOrRegularSubscriptionForUser/GetSharedOrRegularSubscriptionForUser' import { SubscriptionSetting } from '../../../Domain/Setting/SubscriptionSetting' import { SubscriptionSettingHttpRepresentation } from '../../../Mapping/Http/SubscriptionSettingHttpRepresentation' import { ResponseLocals } from '../ResponseLocals' +import { SetSubscriptionSettingValue } from '../../../Domain/UseCase/SetSubscriptionSettingValue/SetSubscriptionSettingValue' +import { TriggerPostSettingUpdateActions } from '../../../Domain/UseCase/TriggerPostSettingUpdateActions/TriggerPostSettingUpdateActions' export class BaseSubscriptionSettingsController extends BaseHttpController { constructor( protected doGetSetting: GetSubscriptionSetting, protected getSharedOrRegularSubscription: GetSharedOrRegularSubscriptionForUser, + protected setSubscriptionSettingValue: SetSubscriptionSettingValue, + protected triggerPostSettingUpdateActions: TriggerPostSettingUpdateActions, protected subscriptionSettingMapper: MapperInterface, + protected logger: Logger, private controllerContainer?: ControllerContainerInterface, ) { super() if (this.controllerContainer !== undefined) { this.controllerContainer.register('auth.users.getSubscriptionSetting', this.getSubscriptionSetting.bind(this)) + this.controllerContainer.register( + 'auth.users.updateSubscriptionSetting', + this.updateSubscriptionSetting.bind(this), + ) } } @@ -64,4 +75,76 @@ export class BaseSubscriptionSettingsController extends BaseHttpController { setting: this.subscriptionSettingMapper.toProjection(settingAndValue.setting), }) } + + async updateSubscriptionSetting( + request: Request, + response: Response, + ): Promise { + const locals = response.locals as ResponseLocals + + if (locals.readOnlyAccess) { + return this.json( + { + error: { + tag: ErrorTag.ReadOnlyAccess, + message: 'Session has read-only access.', + }, + }, + 401, + ) + } + + const subscriptionOrError = await this.getSharedOrRegularSubscription.execute({ + userUuid: locals.user.uuid, + }) + if (subscriptionOrError.isFailed()) { + return this.json( + { + error: { + message: subscriptionOrError.getError(), + }, + }, + 400, + ) + } + const subscription = subscriptionOrError.getValue() + + const { name, value } = request.body + + const result = await this.setSubscriptionSettingValue.execute({ + settingName: name, + value, + userSubscriptionUuid: subscription.uuid, + checkUserPermissions: true, + }) + + if (result.isFailed()) { + return this.json( + { + error: { + message: result.getError(), + }, + }, + 400, + ) + } + const subscriptionSetting = result.getValue() + + const triggerResult = await this.triggerPostSettingUpdateActions.execute({ + updatedSettingName: subscriptionSetting.props.name, + userUuid: locals.user.uuid, + userEmail: locals.user.email, + unencryptedValue: value, + }) + if (triggerResult.isFailed()) { + this.logger.error(`Failed to trigger post setting update actions: ${triggerResult.getError()}`) + } + + return this.json({ + success: true, + setting: subscriptionSetting.props.sensitive + ? undefined + : this.subscriptionSettingMapper.toProjection(subscriptionSetting), + }) + } } diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseUsersController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseUsersController.ts index 8fa203bc9..f78a7e76b 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseUsersController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseUsersController.ts @@ -9,6 +9,7 @@ import { GetUserSubscription } from '../../../Domain/UseCase/GetUserSubscription import { IncreaseLoginAttempts } from '../../../Domain/UseCase/IncreaseLoginAttempts' import { ErrorTag } from '@standardnotes/responses' import { ResponseLocals } from '../ResponseLocals' +import { CookieFactoryInterface } from '../../../Domain/Auth/Cookies/CookieFactoryInterface' export class BaseUsersController extends BaseHttpController { constructor( @@ -17,6 +18,7 @@ export class BaseUsersController extends BaseHttpController { protected clearLoginAttempts: ClearLoginAttempts, protected increaseLoginAttempts: IncreaseLoginAttempts, protected changeCredentialsUseCase: ChangeCredentials, + protected cookieFactory: CookieFactoryInterface, private controllerContainer?: ControllerContainerInterface, ) { super() @@ -157,6 +159,8 @@ export class BaseUsersController extends BaseHttpController { kpOrigination: request.body.origination, updatedWithUserAgent: request.headers['user-agent'], protocolVersion: request.body.version, + snjs: request.headers['x-snjs-version'] as string, + application: request.headers['x-application-version'] as string, }) if (changeCredentialsResult.isFailed()) { @@ -174,8 +178,27 @@ export class BaseUsersController extends BaseHttpController { await this.clearLoginAttempts.execute({ email: locals.user.email }) - response.setHeader('x-invalidate-cache', locals.user.uuid) + const changeCredentialsResultValue = changeCredentialsResult.getValue() + const session = changeCredentialsResultValue.session - return this.json(changeCredentialsResult.getValue()) + response.setHeader('x-invalidate-cache', locals.user.uuid) + if (session) { + response.setHeader( + 'Set-Cookie', + this.cookieFactory.createCookieHeaderValue({ + sessionUuid: session.uuid, + accessToken: changeCredentialsResultValue.cookies?.accessToken as string, + refreshToken: changeCredentialsResultValue.cookies?.refreshToken as string, + refreshTokenExpiration: session.refreshExpiration, + }), + ) + return this.json({ + session: changeCredentialsResultValue.response?.sessionBody, + key_params: changeCredentialsResultValue.response?.keyParams, + user: changeCredentialsResultValue.response?.user, + }) + } + + return this.json(changeCredentialsResultValue.legacyResponse) } } diff --git a/packages/auth/src/Infra/Redis/RedisEphemeralSessionRepository.ts b/packages/auth/src/Infra/Redis/RedisEphemeralSessionRepository.ts index e6451b27e..aaf6d3f7b 100644 --- a/packages/auth/src/Infra/Redis/RedisEphemeralSessionRepository.ts +++ b/packages/auth/src/Infra/Redis/RedisEphemeralSessionRepository.ts @@ -8,6 +8,7 @@ import { EphemeralSessionRepositoryInterface } from '../../Domain/Session/Epheme @injectable() export class RedisEphemeralSessionRepository implements EphemeralSessionRepositoryInterface { private readonly PREFIX = 'session' + private readonly PREFIX_PRIVATE_ID = 'session-private-id' private readonly USER_SESSIONS_PREFIX = 'user-sessions' constructor( @@ -15,6 +16,15 @@ export class RedisEphemeralSessionRepository implements EphemeralSessionReposito @inject(TYPES.Auth_EPHEMERAL_SESSION_AGE) private ephemeralSessionAge: number, ) {} + async findOneByPrivateIdentifier(privateIdentifier: string): Promise { + const stringifiedSession = await this.redisClient.get(`${this.PREFIX_PRIVATE_ID}:${privateIdentifier}`) + if (!stringifiedSession) { + return null + } + + return JSON.parse(stringifiedSession) + } + async deleteOne(uuid: string, userUuid: string): Promise { const pipeline = this.redisClient.pipeline() @@ -86,6 +96,7 @@ export class RedisEphemeralSessionRepository implements EphemeralSessionReposito pipeline.setex(`${this.PREFIX}:${ephemeralSession.uuid}:${ephemeralSession.userUuid}`, ttl, stringifiedSession) pipeline.setex(`${this.PREFIX}:${ephemeralSession.uuid}`, ttl, stringifiedSession) + pipeline.setex(`${this.PREFIX_PRIVATE_ID}:${ephemeralSession.privateIdentifier}`, ttl, stringifiedSession) pipeline.sadd(`${this.USER_SESSIONS_PREFIX}:${ephemeralSession.userUuid}`, ephemeralSession.uuid) pipeline.expire(`${this.USER_SESSIONS_PREFIX}:${ephemeralSession.userUuid}`, ttl) diff --git a/packages/auth/src/Infra/Redis/RedisLockRepository.ts b/packages/auth/src/Infra/Redis/RedisLockRepository.ts new file mode 100644 index 000000000..d1a1d35f0 --- /dev/null +++ b/packages/auth/src/Infra/Redis/RedisLockRepository.ts @@ -0,0 +1,60 @@ +import * as IORedis from 'ioredis' + +import { LockRepositoryInterface } from '../../Domain/User/LockRepositoryInterface' + +export class RedisLockRepository implements LockRepositoryInterface { + private readonly PREFIX = 'lock' + private readonly CAPTCHA_PREFIX = 'captcha-lock' + private readonly OTP_PREFIX = 'otp-lock' + + constructor( + private redisClient: IORedis.Redis, + private maxLoginAttempts: number, + private nonCaptchaLockTTL: number, + private captchaLockTTL: number, + ) {} + + async lockSuccessfullOTP(userIdentifier: string, otp: string): Promise { + await this.redisClient.setex(`${this.OTP_PREFIX}:${userIdentifier}`, 60, otp) + } + + async isOTPLocked(userIdentifier: string, otp: string): Promise { + const lock = await this.redisClient.get(`${this.OTP_PREFIX}:${userIdentifier}`) + + return lock === otp + } + + async resetLockCounter(userIdentifier: string): Promise { + const pipeline = this.redisClient.pipeline() + + pipeline.del(`${this.PREFIX}:${userIdentifier}`) + pipeline.del(`${this.CAPTCHA_PREFIX}:${userIdentifier}`) + + await pipeline.exec() + } + + async updateLockCounter(userIdentifier: string, counter: number, mode: 'captcha' | 'non-captcha'): Promise { + const prefix = mode === 'captcha' ? this.CAPTCHA_PREFIX : this.PREFIX + const lockTTL = mode === 'captcha' ? this.captchaLockTTL : this.nonCaptchaLockTTL + + await this.redisClient.setex(`${prefix}:${userIdentifier}`, lockTTL, counter) + } + + async getLockCounter(userIdentifier: string, mode: 'captcha' | 'non-captcha'): Promise { + const prefix = mode === 'captcha' ? this.CAPTCHA_PREFIX : this.PREFIX + + const counter = await this.redisClient.get(`${prefix}:${userIdentifier}`) + + if (!counter) { + return 0 + } + + return +counter + } + + async isUserLocked(userIdentifier: string): Promise { + const counter = await this.getLockCounter(userIdentifier, 'captcha') + + return counter >= this.maxLoginAttempts + } +} diff --git a/packages/auth/src/Infra/Redis/RedisSessionTokensCooldownRepository.ts b/packages/auth/src/Infra/Redis/RedisSessionTokensCooldownRepository.ts new file mode 100644 index 000000000..24d765cd7 --- /dev/null +++ b/packages/auth/src/Infra/Redis/RedisSessionTokensCooldownRepository.ts @@ -0,0 +1,42 @@ +import * as IORedis from 'ioredis' +import { Uuid } from '@standardnotes/domain-core' + +import { SessionTokensCooldownRepositoryInterface } from '../../Domain/Session/SessionTokensCooldownRepositoryInterface' + +export class RedisSessionTokensCooldownRepository implements SessionTokensCooldownRepositoryInterface { + private readonly PREFIX = 'cooldown:session-tokens' + private readonly COOLDOWN_FORMAT_VERSION = 1 + + constructor(private redisClient: IORedis.Redis) {} + + async getHashedTokens(sessionUuid: Uuid): Promise<{ hashedAccessToken: string; hashedRefreshToken: string } | null> { + const result = await this.redisClient.get(`${this.PREFIX}:${sessionUuid.value}`) + if (!result) { + return null + } + + const [version, hashedAccessToken, hashedRefreshToken] = result.split(':') + + if (parseInt(version) !== this.COOLDOWN_FORMAT_VERSION) { + return null + } + + return { + hashedAccessToken, + hashedRefreshToken, + } + } + + async setCooldown(dto: { + sessionUuid: Uuid + hashedAccessToken: string + hashedRefreshToken: string + cooldownPeriodInSeconds: number + }): Promise { + await this.redisClient.setex( + `${this.PREFIX}:${dto.sessionUuid.value}`, + dto.cooldownPeriodInSeconds, + `${this.COOLDOWN_FORMAT_VERSION}:${dto.hashedAccessToken}:${dto.hashedRefreshToken}`, + ) + } +} diff --git a/packages/auth/src/Infra/TypeORM/TypeORMEphemeralSessionRepository.ts b/packages/auth/src/Infra/TypeORM/TypeORMEphemeralSessionRepository.ts index fbf99c9bb..76d30392a 100644 --- a/packages/auth/src/Infra/TypeORM/TypeORMEphemeralSessionRepository.ts +++ b/packages/auth/src/Infra/TypeORM/TypeORMEphemeralSessionRepository.ts @@ -6,6 +6,7 @@ import { EphemeralSessionRepositoryInterface } from '../../Domain/Session/Epheme export class TypeORMEphemeralSessionRepository implements EphemeralSessionRepositoryInterface { private readonly PREFIX = 'session' + private readonly PREFIX_PRIVATE_ID = 'session-private-id' private readonly USER_SESSIONS_PREFIX = 'user-sessions' constructor( @@ -14,6 +15,17 @@ export class TypeORMEphemeralSessionRepository implements EphemeralSessionReposi private timer: TimerInterface, ) {} + async findOneByPrivateIdentifier(privateIdentifier: string): Promise { + const stringifiedSession = await this.cacheEntryRepository.findUnexpiredOneByKey( + `${this.PREFIX_PRIVATE_ID}:${privateIdentifier}`, + ) + if (!stringifiedSession) { + return null + } + + return JSON.parse(stringifiedSession.props.value) + } + async deleteOne(uuid: string, userUuid: string): Promise { await this.cacheEntryRepository.removeByKey(`${this.PREFIX}:${uuid}`) await this.cacheEntryRepository.removeByKey(`${this.PREFIX}:${uuid}:${userUuid}`) @@ -98,6 +110,14 @@ export class TypeORMEphemeralSessionRepository implements EphemeralSessionReposi }).getValue(), ) + await this.cacheEntryRepository.save( + CacheEntry.create({ + key: `${this.PREFIX_PRIVATE_ID}:${ephemeralSession.privateIdentifier}`, + value: stringifiedSession, + expiresAt: this.timer.getUTCDateNSecondsAhead(ttl), + }).getValue(), + ) + const ephemeralSessionUuidsJSON = await this.cacheEntryRepository.findUnexpiredOneByKey( `${this.USER_SESSIONS_PREFIX}:${ephemeralSession.userUuid}`, ) diff --git a/packages/auth/src/Infra/TypeORM/TypeORMLockRepository.ts b/packages/auth/src/Infra/TypeORM/TypeORMLockRepository.ts index 871c67c77..d5522d6cd 100644 --- a/packages/auth/src/Infra/TypeORM/TypeORMLockRepository.ts +++ b/packages/auth/src/Infra/TypeORM/TypeORMLockRepository.ts @@ -5,13 +5,15 @@ import { LockRepositoryInterface } from '../../Domain/User/LockRepositoryInterfa export class TypeORMLockRepository implements LockRepositoryInterface { private readonly PREFIX = 'lock' + private readonly CAPTCHA_PREFIX = 'captcha-lock' private readonly OTP_PREFIX = 'otp-lock' constructor( private cacheEntryRepository: CacheEntryRepositoryInterface, private timer: TimerInterface, private maxLoginAttempts: number, - private failedLoginLockout: number, + private nonCaptchaLockTTL: number, + private captchaLockTTL: number, ) {} async lockSuccessfullOTP(userIdentifier: string, otp: string): Promise { @@ -38,26 +40,32 @@ export class TypeORMLockRepository implements LockRepositoryInterface { async resetLockCounter(userIdentifier: string): Promise { await this.cacheEntryRepository.removeByKey(`${this.PREFIX}:${userIdentifier}`) + await this.cacheEntryRepository.removeByKey(`${this.CAPTCHA_PREFIX}:${userIdentifier}`) } - async updateLockCounter(userIdentifier: string, counter: number): Promise { - let cacheEntry = await this.cacheEntryRepository.findUnexpiredOneByKey(`${this.PREFIX}:${userIdentifier}`) + async updateLockCounter(userIdentifier: string, counter: number, mode: 'captcha' | 'non-captcha'): Promise { + const prefix = mode === 'captcha' ? this.CAPTCHA_PREFIX : this.PREFIX + const lockTTL = mode === 'captcha' ? this.captchaLockTTL : this.nonCaptchaLockTTL + + let cacheEntry = await this.cacheEntryRepository.findUnexpiredOneByKey(`${prefix}:${userIdentifier}`) if (!cacheEntry) { cacheEntry = CacheEntry.create({ - key: `${this.PREFIX}:${userIdentifier}`, + key: `${prefix}:${userIdentifier}`, value: counter.toString(), - expiresAt: this.timer.getUTCDateNSecondsAhead(this.failedLoginLockout), + expiresAt: this.timer.getUTCDateNSecondsAhead(lockTTL), }).getValue() } else { cacheEntry.props.value = counter.toString() - cacheEntry.props.expiresAt = this.timer.getUTCDateNSecondsAhead(this.failedLoginLockout) + cacheEntry.props.expiresAt = this.timer.getUTCDateNSecondsAhead(lockTTL) } await this.cacheEntryRepository.save(cacheEntry) } - async getLockCounter(userIdentifier: string): Promise { - const counter = await this.cacheEntryRepository.findUnexpiredOneByKey(`${this.PREFIX}:${userIdentifier}`) + async getLockCounter(userIdentifier: string, mode: 'captcha' | 'non-captcha'): Promise { + const prefix = mode === 'captcha' ? this.CAPTCHA_PREFIX : this.PREFIX + + const counter = await this.cacheEntryRepository.findUnexpiredOneByKey(`${prefix}:${userIdentifier}`) if (!counter) { return 0 @@ -66,17 +74,8 @@ export class TypeORMLockRepository implements LockRepositoryInterface { return +counter.props.value } - async lockUser(userIdentifier: string): Promise { - const cacheEntry = await this.cacheEntryRepository.findUnexpiredOneByKey(`${this.PREFIX}:${userIdentifier}`) - if (cacheEntry !== null) { - cacheEntry.props.expiresAt = this.timer.getUTCDateNSecondsAhead(this.failedLoginLockout) - - await this.cacheEntryRepository.save(cacheEntry) - } - } - async isUserLocked(userIdentifier: string): Promise { - const counter = await this.getLockCounter(userIdentifier) + const counter = await this.getLockCounter(userIdentifier, 'captcha') return counter >= this.maxLoginAttempts } diff --git a/packages/auth/src/Infra/TypeORM/TypeORMRevokedSessionRepository.ts b/packages/auth/src/Infra/TypeORM/TypeORMRevokedSessionRepository.ts index 4e30177d2..39e102f27 100644 --- a/packages/auth/src/Infra/TypeORM/TypeORMRevokedSessionRepository.ts +++ b/packages/auth/src/Infra/TypeORM/TypeORMRevokedSessionRepository.ts @@ -12,6 +12,13 @@ export class TypeORMRevokedSessionRepository implements RevokedSessionRepository private ormRepository: Repository, ) {} + async findOneByPrivateIdentifier(privateIdentifier: string): Promise { + return this.ormRepository + .createQueryBuilder('revoked_session') + .where('revoked_session.private_identifier = :privateIdentifier', { privateIdentifier }) + .getOne() + } + async insert(revokedSession: RevokedSession): Promise { await this.ormRepository.insert(revokedSession) } diff --git a/packages/auth/src/Infra/TypeORM/TypeORMSessionRepository.ts b/packages/auth/src/Infra/TypeORM/TypeORMSessionRepository.ts index 7ddcf4a48..511cbcc33 100644 --- a/packages/auth/src/Infra/TypeORM/TypeORMSessionRepository.ts +++ b/packages/auth/src/Infra/TypeORM/TypeORMSessionRepository.ts @@ -17,6 +17,13 @@ export class TypeORMSessionRepository implements SessionRepositoryInterface { @inject(TYPES.Auth_Timer) private timer: TimerInterface, ) {} + async findOneByPrivateIdentifier(privateIdentifier: string): Promise { + return this.ormRepository + .createQueryBuilder('session') + .where('session.private_identifier = :privateIdentifier', { privateIdentifier }) + .getOne() + } + async insert(session: Session): Promise { session.updatedAt = this.timer.getUTCDate() diff --git a/packages/auth/src/Infra/gRPC/AuthServer.ts b/packages/auth/src/Infra/gRPC/AuthServer.ts index e04c30471..93918f7ca 100644 --- a/packages/auth/src/Infra/gRPC/AuthServer.ts +++ b/packages/auth/src/Infra/gRPC/AuthServer.ts @@ -2,7 +2,7 @@ import * as grpc from '@grpc/grpc-js' import { Status } from '@grpc/grpc-js/build/src/constants' import { - AuthorizationHeader, + RequestValidationOptions, ConnectionValidationResponse, IAuthServer, SessionValidationResponse, @@ -88,14 +88,34 @@ export class AuthServer implements IAuthServer { } async validate( - call: grpc.ServerUnaryCall, + call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise { try { this.logger.debug('[SessionsServer] Validating session via gRPC') + const cookies = new Map() + for (const cookie of call.request.getCookieList()) { + const existingCookies = cookies.get(cookie.getName()) + if (existingCookies) { + existingCookies.push(cookie.getValue()) + cookies.set(cookie.getName(), existingCookies) + } else { + cookies.set(cookie.getName(), [cookie.getValue()]) + } + } + const authenticateRequestResponse = await this.authenticateRequest.execute({ - authorizationHeader: call.request.getBearerToken(), + authTokenFromHeaders: call.request.getBearerToken(), + authCookies: cookies, + requestMetadata: { + snjs: call.metadata.get('x-snjs-version').pop() as string, + application: call.metadata.get('x-application-version').pop() as string, + url: call.metadata.get('x-origin-url').pop() as string, + method: call.metadata.get('x-origin-method').pop() as string, + userAgent: call.metadata.get('x-origin-user-agent').pop() as string, + secChUa: call.metadata.get('x-origin-sec-ch-ua').pop() as string, + }, }) if (!authenticateRequestResponse.success) { @@ -116,10 +136,9 @@ export class AuthServer implements IAuthServer { const user = authenticateRequestResponse.user as User - const sharedVaultOwnerMetadata = call.metadata.get('x-shared-vault-owner-context') let sharedVaultOwnerContext = undefined - if (sharedVaultOwnerMetadata.length > 0 && sharedVaultOwnerMetadata[0].length > 0) { - sharedVaultOwnerContext = sharedVaultOwnerMetadata[0].toString() + if (call.request.hasSharedVaultOwnerContext()) { + sharedVaultOwnerContext = call.request.getSharedVaultOwnerContext() } const resultOrError = await this.createCrossServiceToken.execute({ diff --git a/packages/common/package.json b/packages/common/package.json index dbe4bae44..7aa4039a1 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -26,7 +26,7 @@ "clean": "rm -fr dist", "build": "tsc --build", "lint": "eslint . --ext .ts", - "test": "jest --coverage --no-cache" + "test": "jest --coverage --no-cache --maxWorkers=2" }, "devDependencies": { "@types/jest": "^29.5.1", diff --git a/packages/domain-core/package.json b/packages/domain-core/package.json index 11ffb8e2a..8a5466263 100644 --- a/packages/domain-core/package.json +++ b/packages/domain-core/package.json @@ -27,7 +27,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "test": "jest --coverage --no-cache --passWithNoTests" + "test": "jest --coverage --no-cache --passWithNoTests --maxWorkers=2" }, "dependencies": { "uuid": "^9.0.0" diff --git a/packages/domain-core/src/Domain/Email/EmailLevel.ts b/packages/domain-core/src/Domain/Email/EmailLevel.ts index 4fcd8bd82..9df82e097 100644 --- a/packages/domain-core/src/Domain/Email/EmailLevel.ts +++ b/packages/domain-core/src/Domain/Email/EmailLevel.ts @@ -9,7 +9,6 @@ export class EmailLevel extends ValueObject { SignIn: 'SIGN_IN', Marketing: 'MARKETING', FailedCloudBackup: 'FAILED_CLOUD_BACKUP', - FailedEmailBackup: 'FAILED_EMAIL_BACKUP', } get value(): string { diff --git a/packages/domain-core/src/Domain/Setting/SettingName.ts b/packages/domain-core/src/Domain/Setting/SettingName.ts index 59b82c10e..cf5340df7 100644 --- a/packages/domain-core/src/Domain/Setting/SettingName.ts +++ b/packages/domain-core/src/Domain/Setting/SettingName.ts @@ -14,8 +14,6 @@ export class SettingName extends ValueObject { OneDriveBackupToken: 'ONE_DRIVE_BACKUP_TOKEN', GoogleDriveBackupFrequency: 'GOOGLE_DRIVE_BACKUP_FREQUENCY', GoogleDriveBackupToken: 'GOOGLE_DRIVE_BACKUP_TOKEN', - MuteFailedBackupsEmails: 'MUTE_FAILED_BACKUPS_EMAILS', - MuteFailedCloudBackupsEmails: 'MUTE_FAILED_CLOUD_BACKUPS_EMAILS', MuteSignInEmails: 'MUTE_SIGN_IN_EMAILS', MuteMarketingEmails: 'MUTE_MARKETING_EMAILS', ListedAuthorSecrets: 'LISTED_AUTHOR_SECRETS', diff --git a/packages/domain-events-infra/package.json b/packages/domain-events-infra/package.json index 247e6085e..df06d4fbb 100644 --- a/packages/domain-events-infra/package.json +++ b/packages/domain-events-infra/package.json @@ -27,7 +27,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "test": "jest --coverage --no-cache" + "test": "jest --coverage --no-cache --maxWorkers=2" }, "dependencies": { "@aws-sdk/client-sns": "^3.484.0", diff --git a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventPublisher.spec.ts b/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventPublisher.spec.ts index f6e4b1f9c..a7ef8f2bc 100644 --- a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventPublisher.spec.ts +++ b/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventPublisher.spec.ts @@ -24,9 +24,6 @@ describe('RedisDomainEventPublisher', () => { it('should publish an event to a channel', async () => { await createPublisher().publish(event) - expect(redisClient.publish).toHaveBeenCalledWith( - 'events', - 'eJyrViqpLEhVslIKcQ0OUdJRKkiszMlPTFGyqlZKy89XslJKSixSqq0FAPbUDIQ=', - ) + expect(redisClient.publish).toHaveBeenCalledWith('events', expect.any(String)) }) }) diff --git a/packages/domain-events/package.json b/packages/domain-events/package.json index d71042794..20c93cc1d 100644 --- a/packages/domain-events/package.json +++ b/packages/domain-events/package.json @@ -26,7 +26,7 @@ "clean": "rm -fr dist", "build": "tsc --build", "lint": "eslint . --ext .ts", - "test": "jest --coverage --no-cache --passWithNoTests" + "test": "jest --coverage --no-cache --passWithNoTests --maxWorkers=2" }, "dependencies": { "@standardnotes/predicates": "workspace:*", diff --git a/packages/domain-events/src/Domain/Event/EmailBackupRequestedEventPayload.ts b/packages/domain-events/src/Domain/Event/EmailBackupRequestedEventPayload.ts index 204c319e0..400231800 100644 --- a/packages/domain-events/src/Domain/Event/EmailBackupRequestedEventPayload.ts +++ b/packages/domain-events/src/Domain/Event/EmailBackupRequestedEventPayload.ts @@ -1,6 +1,4 @@ export interface EmailBackupRequestedEventPayload { userUuid: string - userHasEmailsMuted: boolean - muteEmailsSettingUuid: string keyParams: Record } diff --git a/packages/files/CHANGELOG.md b/packages/files/CHANGELOG.md index daf5a0803..413556b4a 100644 --- a/packages/files/CHANGELOG.md +++ b/packages/files/CHANGELOG.md @@ -3,18 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -# [1.38.0](https://github.com/standardnotes/server/compare/@standardnotes/files-server@1.37.12...@standardnotes/files-server@1.38.0) (2024-03-20) - -### Features - -* add CORS_ORIGIN_STRICT_MODE_ENABLED env var to determine if CORS origin should be restricted ([5c02435](https://github.com/standardnotes/server/commit/5c02435ee478b893747d3f9e41062aae12d7ff10)) - -## [1.37.12](https://github.com/standardnotes/server/compare/@standardnotes/files-server@1.37.11...@standardnotes/files-server@1.37.12) (2024-03-18) - -### Bug Fixes - -* cors issues on clients - fixes [#1046](https://github.com/standardnotes/server/issues/1046) ([#1049](https://github.com/standardnotes/server/issues/1049)) ([6d7ca1b](https://github.com/standardnotes/server/commit/6d7ca1b926fd45d744275bd3c1f4c05b010f76c8)) - ## [1.37.11](https://github.com/standardnotes/server/compare/@standardnotes/files-server@1.37.10...@standardnotes/files-server@1.37.11) (2024-01-19) **Note:** Version bump only for package @standardnotes/files-server diff --git a/packages/files/Dockerfile b/packages/files/Dockerfile index c6bcfcd83..32a80ef0b 100644 --- a/packages/files/Dockerfile +++ b/packages/files/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/files ENTRYPOINT [ "/workspace/packages/files/docker/entrypoint.sh" ] diff --git a/packages/files/bin/server.ts b/packages/files/bin/server.ts index 276976610..c7d0be08e 100644 --- a/packages/files/bin/server.ts +++ b/packages/files/bin/server.ts @@ -66,9 +66,8 @@ void container.load().then((container) => { app.use(raw({ limit: requestPayloadLimit, type: 'application/octet-stream' })) app.use(urlencoded({ extended: true, limit: requestPayloadLimit })) - const corsAllowedOrigins = env.get('CORS_ALLOWED_ORIGINS', true) - ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') - : [] + const corsAllowedOrigins = container.get(TYPES.Files_CORS_ALLOWED_ORIGINS) + app.use( cors({ credentials: true, diff --git a/packages/files/package.json b/packages/files/package.json index a1c5a904d..b23404212 100644 --- a/packages/files/package.json +++ b/packages/files/package.json @@ -1,6 +1,6 @@ { "name": "@standardnotes/files-server", - "version": "1.38.0", + "version": "1.37.11", "engines": { "node": ">=18.0.0 <21.0.0" }, @@ -26,8 +26,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --fix --ext .ts", - "pretest": "yarn lint && yarn build", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "start": "yarn node dist/bin/server.js", "worker": "yarn node dist/bin/worker.js" }, diff --git a/packages/files/src/Bootstrap/Container.ts b/packages/files/src/Bootstrap/Container.ts index d042f3655..8feb51c60 100644 --- a/packages/files/src/Bootstrap/Container.ts +++ b/packages/files/src/Bootstrap/Container.ts @@ -54,6 +54,8 @@ import { MoveFile } from '../Domain/UseCase/MoveFile/MoveFile' import { SharedVaultValetTokenAuthMiddleware } from '../Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware' import { RecalculateQuota } from '../Domain/UseCase/RecalculateQuota/RecalculateQuota' import { FileQuotaRecalculationRequestedEventHandler } from '../Domain/Handler/FileQuotaRecalculationRequestedEventHandler' +import { ValetTokenRepositoryInterface } from '../Domain/ValetToken/ValetTokenRepositoryInterface' +import { RedisValetTokenRepository } from '../Infra/Redis/RedisValetTokenRepository' export class ContainerConfigLoader { constructor(private mode: 'server' | 'worker' = 'server') {} @@ -72,6 +74,9 @@ export class ContainerConfigLoader { const container = new Container() // env vars + container + .bind(TYPES.Files_CORS_ALLOWED_ORIGINS) + .toConstantValue(env.get('CORS_ALLOWED_ORIGINS', true) ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') : []) container.bind(TYPES.Files_VALET_TOKEN_SECRET).toConstantValue(env.get('VALET_TOKEN_SECRET')) container .bind(TYPES.Files_MAX_CHUNK_BYTES) @@ -100,6 +105,19 @@ export class ContainerConfigLoader { container.bind(TYPES.Files_Timer).toConstantValue(new Timer()) + container.bind(TYPES.Files_REDIS_URL).toConstantValue(env.get('REDIS_URL')) + + const redisUrl = container.get(TYPES.Files_REDIS_URL) as string + const isRedisInClusterMode = redisUrl.indexOf(',') > 0 + let redis + if (isRedisInClusterMode) { + redis = new Redis.Cluster(redisUrl.split(',')) + } else { + redis = new Redis(redisUrl) + } + + container.bind(TYPES.Files_Redis).toConstantValue(redis) + // services container .bind>(TYPES.Files_ValetTokenDecoder) @@ -108,24 +126,15 @@ export class ContainerConfigLoader { .bind(TYPES.Files_DomainEventFactory) .toConstantValue(new DomainEventFactory(container.get(TYPES.Files_Timer))) + container + .bind(TYPES.Files_ValetTokenRepository) + .toConstantValue(new RedisValetTokenRepository(container.get(TYPES.Files_Redis))) + if (isConfiguredForInMemoryCache) { container .bind(TYPES.Files_UploadRepository) .toConstantValue(new InMemoryUploadRepository(container.get(TYPES.Files_Timer))) } else { - container.bind(TYPES.Files_REDIS_URL).toConstantValue(env.get('REDIS_URL')) - - const redisUrl = container.get(TYPES.Files_REDIS_URL) as string - const isRedisInClusterMode = redisUrl.indexOf(',') > 0 - let redis - if (isRedisInClusterMode) { - redis = new Redis.Cluster(redisUrl.split(',')) - } else { - redis = new Redis(redisUrl) - } - - container.bind(TYPES.Files_Redis).toConstantValue(redis) - container.bind(TYPES.Files_UploadRepository).to(RedisUploadRepository) } @@ -223,6 +232,7 @@ export class ContainerConfigLoader { container.get(TYPES.Files_UploadRepository), container.get(TYPES.Files_DomainEventPublisher), container.get(TYPES.Files_DomainEventFactory), + container.get(TYPES.Files_ValetTokenRepository), ), ) container diff --git a/packages/files/src/Bootstrap/Types.ts b/packages/files/src/Bootstrap/Types.ts index 37ac0ce7f..f985a0963 100644 --- a/packages/files/src/Bootstrap/Types.ts +++ b/packages/files/src/Bootstrap/Types.ts @@ -29,6 +29,7 @@ const TYPES = { // repositories Files_UploadRepository: Symbol.for('Files_UploadRepository'), + Files_ValetTokenRepository: Symbol.for('Files_ValetTokenRepository'), // middleware Files_ValetTokenAuthMiddleware: Symbol.for('Files_ValetTokenAuthMiddleware'), @@ -50,6 +51,7 @@ const TYPES = { Files_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING: Symbol.for( 'Files_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING', ), + Files_CORS_ALLOWED_ORIGINS: Symbol.for('Files_CORS_ALLOWED_ORIGINS'), // Handlers Files_DomainEventMessageHandler: Symbol.for('Files_DomainEventMessageHandler'), diff --git a/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.spec.ts b/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.spec.ts index 9cc07526f..cf8ed4cf4 100644 --- a/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.spec.ts +++ b/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.spec.ts @@ -9,17 +9,28 @@ import { FileUploaderInterface } from '../../Services/FileUploaderInterface' import { UploadRepositoryInterface } from '../../Upload/UploadRepositoryInterface' import { FinishUploadSession } from './FinishUploadSession' +import { ValetTokenRepositoryInterface } from '../../ValetToken/ValetTokenRepositoryInterface' describe('FinishUploadSession', () => { let fileUploader: FileUploaderInterface let uploadRepository: UploadRepositoryInterface let domainEventPublisher: DomainEventPublisherInterface let domainEventFactory: DomainEventFactoryInterface + let valetTokenRepository: ValetTokenRepositoryInterface const createUseCase = () => - new FinishUploadSession(fileUploader, uploadRepository, domainEventPublisher, domainEventFactory) + new FinishUploadSession( + fileUploader, + uploadRepository, + domainEventPublisher, + domainEventFactory, + valetTokenRepository, + ) beforeEach(() => { + valetTokenRepository = {} as jest.Mocked + valetTokenRepository.markAsUsed = jest.fn() + fileUploader = {} as jest.Mocked fileUploader.finishUploadSession = jest.fn().mockReturnValue('ETag123') @@ -45,6 +56,7 @@ describe('FinishUploadSession', () => { userUuid: '00000000-0000-0000-0000-000000000000', uploadBytesLimit: 100, uploadBytesUsed: 0, + valetToken: 'valet-token', }) expect(fileUploader.finishUploadSession).not.toHaveBeenCalled() @@ -57,6 +69,7 @@ describe('FinishUploadSession', () => { userUuid: 'invalid', uploadBytesLimit: 100, uploadBytesUsed: 0, + valetToken: 'valet-token', }) expect(result.isFailed()).toBeTruthy() @@ -74,6 +87,7 @@ describe('FinishUploadSession', () => { userUuid: '00000000-0000-0000-0000-000000000000', uploadBytesLimit: 100, uploadBytesUsed: 0, + valetToken: 'valet-token', }) expect(result.getError()).toEqual('Could not finish upload session') @@ -88,6 +102,7 @@ describe('FinishUploadSession', () => { userUuid: '00000000-0000-0000-0000-000000000000', uploadBytesLimit: 100, uploadBytesUsed: 0, + valetToken: 'valet-token', }) expect(fileUploader.finishUploadSession).toHaveBeenCalledWith('123', '00000000-0000-0000-0000-000000000000/2-3-4', [ @@ -103,6 +118,7 @@ describe('FinishUploadSession', () => { sharedVaultUuid: '00000000-0000-0000-0000-000000000000', uploadBytesLimit: 100, uploadBytesUsed: 0, + valetToken: 'valet-token', }) expect(fileUploader.finishUploadSession).toHaveBeenCalledWith('123', '00000000-0000-0000-0000-000000000000/2-3-4', [ @@ -118,6 +134,7 @@ describe('FinishUploadSession', () => { sharedVaultUuid: 'invalid', uploadBytesLimit: 100, uploadBytesUsed: 0, + valetToken: 'valet-token', }) expect(result.isFailed()).toBeTruthy() @@ -137,6 +154,7 @@ describe('FinishUploadSession', () => { userUuid: '00000000-0000-0000-0000-000000000000', uploadBytesLimit: 100, uploadBytesUsed: 20, + valetToken: 'valet-token', }) expect(result.getError()).toEqual('Could not finish upload session. You are out of space.') @@ -156,6 +174,7 @@ describe('FinishUploadSession', () => { userUuid: '00000000-0000-0000-0000-000000000000', uploadBytesLimit: -1, uploadBytesUsed: 20, + valetToken: 'valet-token', }) expect(result.isFailed()).toBeFalsy() diff --git a/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.ts b/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.ts index 3d70e6272..2bb8e4325 100644 --- a/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.ts +++ b/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSession.ts @@ -5,6 +5,7 @@ import { FinishUploadSessionDTO } from './FinishUploadSessionDTO' import { FileUploaderInterface } from '../../Services/FileUploaderInterface' import { UploadRepositoryInterface } from '../../Upload/UploadRepositoryInterface' import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInterface' +import { ValetTokenRepositoryInterface } from '../../ValetToken/ValetTokenRepositoryInterface' export class FinishUploadSession implements UseCaseInterface { constructor( @@ -12,6 +13,7 @@ export class FinishUploadSession implements UseCaseInterface { private uploadRepository: UploadRepositoryInterface, private domainEventPublisher: DomainEventPublisherInterface, private domainEventFactory: DomainEventFactoryInterface, + private valetTokenRepository: ValetTokenRepositoryInterface, ) {} async execute(dto: FinishUploadSessionDTO): Promise> { @@ -74,6 +76,8 @@ export class FinishUploadSession implements UseCaseInterface { ) } + await this.valetTokenRepository.markAsUsed(dto.valetToken) + return Result.ok() } catch (error) { return Result.fail('Could not finish upload session') diff --git a/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSessionDTO.ts b/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSessionDTO.ts index 2c4d1d274..ec29168e3 100644 --- a/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSessionDTO.ts +++ b/packages/files/src/Domain/UseCase/FinishUploadSession/FinishUploadSessionDTO.ts @@ -4,4 +4,5 @@ export type FinishUploadSessionDTO = { resourceRemoteIdentifier: string uploadBytesUsed: number uploadBytesLimit: number + valetToken: string } diff --git a/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.spec.ts b/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.spec.ts index 439d2a27b..b7321bce0 100644 --- a/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.spec.ts +++ b/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.spec.ts @@ -10,16 +10,22 @@ import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInter import { RemoveFile } from './RemoveFile' import { FileRemoverInterface } from '../../Services/FileRemoverInterface' +import { ValetTokenRepositoryInterface } from '../../ValetToken/ValetTokenRepositoryInterface' describe('RemoveFile', () => { let fileRemover: FileRemoverInterface let domainEventPublisher: DomainEventPublisherInterface let domainEventFactory: DomainEventFactoryInterface + let valetTokenRepository: ValetTokenRepositoryInterface let logger: Logger - const createUseCase = () => new RemoveFile(fileRemover, domainEventPublisher, domainEventFactory, logger) + const createUseCase = () => + new RemoveFile(fileRemover, domainEventPublisher, domainEventFactory, valetTokenRepository, logger) beforeEach(() => { + valetTokenRepository = {} as jest.Mocked + valetTokenRepository.markAsUsed = jest.fn() + fileRemover = {} as jest.Mocked fileRemover.remove = jest.fn().mockReturnValue(413) @@ -49,6 +55,7 @@ describe('RemoveFile', () => { userUuid: '1-2-3', regularSubscriptionUuid: '3-4-5', }, + valetToken: 'valet-token', }) expect(result.isFailed()).toEqual(true) @@ -56,7 +63,7 @@ describe('RemoveFile', () => { }) it('should indicate of an error of no proper input', async () => { - const result = await createUseCase().execute({}) + const result = await createUseCase().execute({ valetToken: 'valet-token' }) expect(result.isFailed()).toEqual(true) expect(domainEventPublisher.publish).not.toHaveBeenCalled() @@ -69,6 +76,7 @@ describe('RemoveFile', () => { userUuid: '1-2-3', regularSubscriptionUuid: '3-4-5', }, + valetToken: 'valet-token', }) expect(fileRemover.remove).toHaveBeenCalledWith('1-2-3/2-3-4') @@ -82,6 +90,7 @@ describe('RemoveFile', () => { sharedVaultUuid: '1-2-3', vaultOwnerUuid: '3-4-5', }, + valetToken: 'valet-token', }) expect(fileRemover.remove).toHaveBeenCalledWith('1-2-3/2-3-4') diff --git a/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.ts b/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.ts index 3d0595c0f..aca344b83 100644 --- a/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.ts +++ b/packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.ts @@ -7,6 +7,7 @@ import { DomainEventFactoryInterface } from '../../Event/DomainEventFactoryInter import { FileRemoverInterface } from '../../Services/FileRemoverInterface' import { RemoveFileDTO } from './RemoveFileDTO' import { Result, UseCaseInterface } from '@standardnotes/domain-core' +import { ValetTokenRepositoryInterface } from '../../ValetToken/ValetTokenRepositoryInterface' @injectable() export class RemoveFile implements UseCaseInterface { @@ -14,6 +15,7 @@ export class RemoveFile implements UseCaseInterface { @inject(TYPES.Files_FileRemover) private fileRemover: FileRemoverInterface, @inject(TYPES.Files_DomainEventPublisher) private domainEventPublisher: DomainEventPublisherInterface, @inject(TYPES.Files_DomainEventFactory) private domainEventFactory: DomainEventFactoryInterface, + @inject(TYPES.Files_ValetTokenRepository) private valetTokenRepository: ValetTokenRepositoryInterface, @inject(TYPES.Files_Logger) private logger: Logger, ) {} @@ -52,6 +54,8 @@ export class RemoveFile implements UseCaseInterface { return Result.fail('Could not remove file') } + await this.valetTokenRepository.markAsUsed(dto.valetToken) + return Result.ok() } catch (error) { this.logger.error(`Could not remove resource: ${resourceUuid} - ${(error as Error).message}`) diff --git a/packages/files/src/Domain/UseCase/RemoveFile/RemoveFileDTO.ts b/packages/files/src/Domain/UseCase/RemoveFile/RemoveFileDTO.ts index 4ff45f4e6..6a5e75743 100644 --- a/packages/files/src/Domain/UseCase/RemoveFile/RemoveFileDTO.ts +++ b/packages/files/src/Domain/UseCase/RemoveFile/RemoveFileDTO.ts @@ -9,4 +9,5 @@ export interface RemoveFileDTO { vaultOwnerUuid: string resourceRemoteIdentifier: string } + valetToken: string } diff --git a/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.spec.ts b/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.spec.ts index f5a0719c6..f686d7b88 100644 --- a/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.spec.ts +++ b/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.spec.ts @@ -5,14 +5,20 @@ import { Logger } from 'winston' import { FileDownloaderInterface } from '../../Services/FileDownloaderInterface' import { StreamDownloadFile } from './StreamDownloadFile' +import { ValetTokenRepositoryInterface } from '../../ValetToken/ValetTokenRepositoryInterface' describe('StreamDownloadFile', () => { let fileDownloader: FileDownloaderInterface let logger: Logger + const valetToken = 'valet-token' + let valetTokenRepository: ValetTokenRepositoryInterface - const createUseCase = () => new StreamDownloadFile(fileDownloader, logger) + const createUseCase = () => new StreamDownloadFile(fileDownloader, valetTokenRepository, logger) beforeEach(() => { + valetTokenRepository = {} as jest.Mocked + valetTokenRepository.markAsUsed = jest.fn() + fileDownloader = {} as jest.Mocked fileDownloader.createDownloadStream = jest.fn().mockReturnValue(new Readable()) @@ -26,11 +32,28 @@ describe('StreamDownloadFile', () => { resourceRemoteIdentifier: '1-2-3', startRange: 0, endRange: 200, + endRangeOfFile: 300, + valetToken, }) expect(result.success).toBeTruthy() }) + it('should mark valet token as used if the last chunk is being streamed', async () => { + const result = await createUseCase().execute({ + ownerUuid: '2-3-4', + resourceRemoteIdentifier: '1-2-3', + startRange: 0, + endRange: 200, + endRangeOfFile: 200, + valetToken, + }) + + expect(result.success).toBeTruthy() + + expect(valetTokenRepository.markAsUsed).toHaveBeenCalledWith(valetToken) + }) + it('should not stream download file contents from S3 if it fails', async () => { fileDownloader.createDownloadStream = jest.fn().mockImplementation(() => { throw new Error('oops') @@ -41,6 +64,8 @@ describe('StreamDownloadFile', () => { resourceRemoteIdentifier: '1-2-3', startRange: 0, endRange: 200, + endRangeOfFile: 200, + valetToken, }) expect(result.success).toBeFalsy() diff --git a/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.ts b/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.ts index 7b57b0f5b..065465586 100644 --- a/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.ts +++ b/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFile.ts @@ -5,11 +5,13 @@ import { FileDownloaderInterface } from '../../Services/FileDownloaderInterface' import { UseCaseInterface } from '../UseCaseInterface' import { StreamDownloadFileDTO } from './StreamDownloadFileDTO' import { StreamDownloadFileResponse } from './StreamDownloadFileResponse' +import { ValetTokenRepositoryInterface } from '../../ValetToken/ValetTokenRepositoryInterface' @injectable() export class StreamDownloadFile implements UseCaseInterface { constructor( @inject(TYPES.Files_FileDownloader) private fileDownloader: FileDownloaderInterface, + @inject(TYPES.Files_ValetTokenRepository) private valetTokenRepository: ValetTokenRepositoryInterface, @inject(TYPES.Files_Logger) private logger: Logger, ) {} @@ -21,6 +23,10 @@ export class StreamDownloadFile implements UseCaseInterface { dto.endRange, ) + if (dto.endRange === dto.endRangeOfFile) { + await this.valetTokenRepository.markAsUsed(dto.valetToken) + } + return { success: true, readStream, diff --git a/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFileDTO.ts b/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFileDTO.ts index 664fa5bf9..317041d9c 100644 --- a/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFileDTO.ts +++ b/packages/files/src/Domain/UseCase/StreamDownloadFile/StreamDownloadFileDTO.ts @@ -3,4 +3,6 @@ export type StreamDownloadFileDTO = { resourceRemoteIdentifier: string startRange: number endRange: number + endRangeOfFile: number + valetToken: string } diff --git a/packages/files/src/Domain/ValetToken/ValetTokenRepositoryInterface.ts b/packages/files/src/Domain/ValetToken/ValetTokenRepositoryInterface.ts new file mode 100644 index 000000000..5b022ae0d --- /dev/null +++ b/packages/files/src/Domain/ValetToken/ValetTokenRepositoryInterface.ts @@ -0,0 +1,4 @@ +export interface ValetTokenRepositoryInterface { + markAsUsed(valetToken: string): Promise + isUsed(valetToken: string): Promise +} diff --git a/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.spec.ts b/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.spec.ts index 511f7245d..e17ea9c74 100644 --- a/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.spec.ts +++ b/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.spec.ts @@ -93,7 +93,7 @@ describe('AnnotatedFilesController', () => { expect(response.writeHead).toHaveBeenCalledWith(206, { 'Accept-Ranges': 'bytes', 'Content-Length': 100000, - 'Content-Range': 'bytes 0-99999/555555', + 'Content-Range': 'bytes 0-99999/555554', 'Content-Type': 'application/octet-stream', }) @@ -122,14 +122,14 @@ describe('AnnotatedFilesController', () => { expect(response.writeHead).toHaveBeenNthCalledWith(1, 206, { 'Accept-Ranges': 'bytes', 'Content-Length': 100000, - 'Content-Range': 'bytes 0-99999/555555', + 'Content-Range': 'bytes 0-99999/555554', 'Content-Type': 'application/octet-stream', }) expect(response.writeHead).toHaveBeenNthCalledWith(2, 206, { 'Accept-Ranges': 'bytes', 'Content-Length': 100000, - 'Content-Range': 'bytes 100000-199999/555555', + 'Content-Range': 'bytes 100000-199999/555554', 'Content-Type': 'application/octet-stream', }) }) @@ -145,7 +145,7 @@ describe('AnnotatedFilesController', () => { expect(response.writeHead).toHaveBeenCalledWith(206, { 'Accept-Ranges': 'bytes', 'Content-Length': 50000, - 'Content-Range': 'bytes 0-49999/555555', + 'Content-Range': 'bytes 0-49999/555554', 'Content-Type': 'application/octet-stream', }) @@ -163,7 +163,7 @@ describe('AnnotatedFilesController', () => { expect(response.writeHead).toHaveBeenCalledWith(206, { 'Accept-Ranges': 'bytes', 'Content-Length': 100000, - 'Content-Range': 'bytes 0-99999/555555', + 'Content-Range': 'bytes 0-99999/555554', 'Content-Type': 'application/octet-stream', }) diff --git a/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.ts b/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.ts index 305f17ff3..ccaf62a16 100644 --- a/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.ts +++ b/packages/files/src/Infra/InversifyExpress/AnnotatedFilesController.ts @@ -12,6 +12,7 @@ import { CreateUploadSession } from '../../Domain/UseCase/CreateUploadSession/Cr import { FinishUploadSession } from '../../Domain/UseCase/FinishUploadSession/FinishUploadSession' import { GetFileMetadata } from '../../Domain/UseCase/GetFileMetadata/GetFileMetadata' import { RemoveFile } from '../../Domain/UseCase/RemoveFile/RemoveFile' +import { ValetTokenResponseLocals } from './Middleware/ValetTokenResponseLocals' @controller('/v1/files', TYPES.Files_ValetTokenAuthMiddleware) export class AnnotatedFilesController extends BaseHttpController { @@ -83,15 +84,17 @@ export class AnnotatedFilesController extends BaseHttpController { _request: Request, response: Response, ): Promise { - if (response.locals.permittedOperation !== ValetTokenOperation.Write) { + const locals = response.locals as ValetTokenResponseLocals + if (locals.permittedOperation !== ValetTokenOperation.Write) { return this.badRequest('Not permitted for this operation') } const result = await this.finishUploadSession.execute({ - userUuid: response.locals.userUuid, - resourceRemoteIdentifier: response.locals.permittedResources[0].remoteIdentifier, - uploadBytesLimit: response.locals.uploadBytesLimit, - uploadBytesUsed: response.locals.uploadBytesUsed, + userUuid: locals.userUuid, + resourceRemoteIdentifier: locals.permittedResources[0].remoteIdentifier, + uploadBytesLimit: locals.uploadBytesLimit, + uploadBytesUsed: locals.uploadBytesUsed, + valetToken: locals.valetToken, }) if (result.isFailed()) { @@ -108,16 +111,18 @@ export class AnnotatedFilesController extends BaseHttpController { _request: Request, response: Response, ): Promise { - if (response.locals.permittedOperation !== ValetTokenOperation.Delete) { + const locals = response.locals as ValetTokenResponseLocals + if (locals.permittedOperation !== ValetTokenOperation.Delete) { return this.badRequest('Not permitted for this operation') } const result = await this.removeFile.execute({ userInput: { - userUuid: response.locals.userUuid, - resourceRemoteIdentifier: response.locals.permittedResources[0].remoteIdentifier, - regularSubscriptionUuid: response.locals.regularSubscriptionUuid, + userUuid: locals.userUuid, + resourceRemoteIdentifier: locals.permittedResources[0].remoteIdentifier, + regularSubscriptionUuid: locals.regularSubscriptionUuid, }, + valetToken: locals.valetToken, }) if (result.isFailed()) { @@ -132,7 +137,8 @@ export class AnnotatedFilesController extends BaseHttpController { request: Request, response: Response, ): Promise Writable)> { - if (response.locals.permittedOperation !== ValetTokenOperation.Read) { + const locals = response.locals as ValetTokenResponseLocals + if (locals.permittedOperation !== ValetTokenOperation.Read) { return this.badRequest('Not permitted for this operation') } @@ -147,20 +153,21 @@ export class AnnotatedFilesController extends BaseHttpController { } const fileMetadataOrError = await this.getFileMetadata.execute({ - ownerUuid: response.locals.userUuid, - resourceRemoteIdentifier: response.locals.permittedResources[0].remoteIdentifier, + ownerUuid: locals.userUuid, + resourceRemoteIdentifier: locals.permittedResources[0].remoteIdentifier, }) if (fileMetadataOrError.isFailed()) { return this.badRequest(fileMetadataOrError.getError()) } const fileSize = fileMetadataOrError.getValue() + const endRangeOfFile = fileSize - 1 const startRange = Number(range.replace(/\D/g, '')) - const endRange = Math.min(startRange + chunkSize - 1, fileSize - 1) + const endRange = Math.min(startRange + chunkSize - 1, endRangeOfFile) const headers = { - 'Content-Range': `bytes ${startRange}-${endRange}/${fileSize}`, + 'Content-Range': `bytes ${startRange}-${endRange}/${endRangeOfFile}`, 'Accept-Ranges': 'bytes', 'Content-Length': endRange - startRange + 1, 'Content-Type': 'application/octet-stream', @@ -169,10 +176,12 @@ export class AnnotatedFilesController extends BaseHttpController { response.writeHead(206, headers) const result = await this.streamDownloadFile.execute({ - ownerUuid: response.locals.userUuid, - resourceRemoteIdentifier: response.locals.permittedResources[0].remoteIdentifier, + ownerUuid: locals.userUuid, + resourceRemoteIdentifier: locals.permittedResources[0].remoteIdentifier, startRange, endRange, + endRangeOfFile, + valetToken: locals.valetToken, }) if (!result.success) { diff --git a/packages/files/src/Infra/InversifyExpress/AnnotatedSharedVaultFilesController.ts b/packages/files/src/Infra/InversifyExpress/AnnotatedSharedVaultFilesController.ts index c8c1914db..7d8d1b9da 100644 --- a/packages/files/src/Infra/InversifyExpress/AnnotatedSharedVaultFilesController.ts +++ b/packages/files/src/Infra/InversifyExpress/AnnotatedSharedVaultFilesController.ts @@ -2,7 +2,7 @@ import { BaseHttpController, controller, httpDelete, httpGet, httpPost, results import { Request, Response } from 'express' import { inject } from 'inversify' import { Writable } from 'stream' -import { SharedVaultValetTokenData, ValetTokenOperation } from '@standardnotes/security' +import { ValetTokenOperation } from '@standardnotes/security' import { Logger } from 'winston' import TYPES from '../../Bootstrap/Types' @@ -13,6 +13,7 @@ import { MoveFile } from '../../Domain/UseCase/MoveFile/MoveFile' import { RemoveFile } from '../../Domain/UseCase/RemoveFile/RemoveFile' import { StreamDownloadFile } from '../../Domain/UseCase/StreamDownloadFile/StreamDownloadFile' import { UploadFileChunk } from '../../Domain/UseCase/UploadFileChunk/UploadFileChunk' +import { SharedVaultValetTokenResponseLocals } from './Middleware/SharedVaultValetTokenResponseLocals' @controller('/v1/shared-vault/files', TYPES.Files_SharedVaultValetTokenAuthMiddleware) export class AnnotatedSharedVaultFilesController extends BaseHttpController { @@ -35,12 +36,12 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { _request: Request, response: Response, ): Promise { - const locals = response.locals as SharedVaultValetTokenData - if (locals.permittedOperation !== ValetTokenOperation.Move) { + const locals = response.locals as SharedVaultValetTokenResponseLocals + if (locals.valetTokenData.permittedOperation !== ValetTokenOperation.Move) { return this.badRequest('Not permitted for this operation') } - const moveOperation = locals.moveOperation + const moveOperation = locals.valetTokenData.moveOperation if (!moveOperation) { return this.badRequest('Missing move operation data') } @@ -49,7 +50,7 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { moveType: moveOperation.type, from: moveOperation.from, to: moveOperation.to, - resourceRemoteIdentifier: locals.remoteIdentifier, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, }) if (result.isFailed()) { @@ -64,14 +65,14 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { _request: Request, response: Response, ): Promise { - const locals = response.locals as SharedVaultValetTokenData - if (locals.permittedOperation !== ValetTokenOperation.Write) { + const locals = response.locals as SharedVaultValetTokenResponseLocals + if (locals.valetTokenData.permittedOperation !== ValetTokenOperation.Write) { return this.badRequest('Not permitted for this operation') } const result = await this.createUploadSession.execute({ - ownerUuid: locals.sharedVaultUuid, - resourceRemoteIdentifier: locals.remoteIdentifier, + ownerUuid: locals.valetTokenData.sharedVaultUuid, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, }) if (!result.success) { @@ -86,8 +87,8 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { request: Request, response: Response, ): Promise { - const locals = response.locals as SharedVaultValetTokenData - if (locals.permittedOperation !== ValetTokenOperation.Write) { + const locals = response.locals as SharedVaultValetTokenResponseLocals + if (locals.valetTokenData.permittedOperation !== ValetTokenOperation.Write) { return this.badRequest('Not permitted for this operation') } @@ -97,9 +98,9 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { } const result = await this.uploadFileChunk.execute({ - ownerUuid: locals.sharedVaultUuid, - resourceRemoteIdentifier: locals.remoteIdentifier, - resourceUnencryptedFileSize: locals.unencryptedFileSize as number, + ownerUuid: locals.valetTokenData.sharedVaultUuid, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, + resourceUnencryptedFileSize: locals.valetTokenData.unencryptedFileSize as number, chunkId, data: request.body, }) @@ -116,21 +117,22 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { _request: Request, response: Response, ): Promise { - const locals = response.locals as SharedVaultValetTokenData - if (locals.permittedOperation !== ValetTokenOperation.Write) { + const locals = response.locals as SharedVaultValetTokenResponseLocals + if (locals.valetTokenData.permittedOperation !== ValetTokenOperation.Write) { return this.badRequest('Not permitted for this operation') } - if (locals.uploadBytesLimit === undefined) { + if (locals.valetTokenData.uploadBytesLimit === undefined) { return this.badRequest('Missing upload bytes limit') } const result = await this.finishUploadSession.execute({ - userUuid: locals.vaultOwnerUuid, - sharedVaultUuid: locals.sharedVaultUuid, - resourceRemoteIdentifier: locals.remoteIdentifier, - uploadBytesLimit: locals.uploadBytesLimit, - uploadBytesUsed: locals.uploadBytesUsed, + userUuid: locals.valetTokenData.vaultOwnerUuid, + sharedVaultUuid: locals.valetTokenData.sharedVaultUuid, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, + uploadBytesLimit: locals.valetTokenData.uploadBytesLimit, + uploadBytesUsed: locals.valetTokenData.uploadBytesUsed, + valetToken: locals.valetToken, }) if (result.isFailed()) { @@ -147,17 +149,18 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { _request: Request, response: Response, ): Promise { - const locals = response.locals as SharedVaultValetTokenData - if (locals.permittedOperation !== ValetTokenOperation.Delete) { + const locals = response.locals as SharedVaultValetTokenResponseLocals + if (locals.valetTokenData.permittedOperation !== ValetTokenOperation.Delete) { return this.badRequest('Not permitted for this operation') } const result = await this.removeFile.execute({ vaultInput: { - sharedVaultUuid: locals.sharedVaultUuid, - vaultOwnerUuid: locals.vaultOwnerUuid, - resourceRemoteIdentifier: locals.remoteIdentifier, + sharedVaultUuid: locals.valetTokenData.sharedVaultUuid, + vaultOwnerUuid: locals.valetTokenData.vaultOwnerUuid, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, }, + valetToken: locals.valetToken, }) if (result.isFailed()) { @@ -172,8 +175,8 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { request: Request, response: Response, ): Promise Writable)> { - const locals = response.locals as SharedVaultValetTokenData - if (locals.permittedOperation !== ValetTokenOperation.Read) { + const locals = response.locals as SharedVaultValetTokenResponseLocals + if (locals.valetTokenData.permittedOperation !== ValetTokenOperation.Read) { return this.badRequest('Not permitted for this operation') } @@ -188,20 +191,21 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { } const fileMetadataOrError = await this.getFileMetadata.execute({ - ownerUuid: locals.sharedVaultUuid, - resourceRemoteIdentifier: locals.remoteIdentifier, + ownerUuid: locals.valetTokenData.sharedVaultUuid, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, }) if (fileMetadataOrError.isFailed()) { return this.badRequest(fileMetadataOrError.getError()) } const fileSize = fileMetadataOrError.getValue() + const endRangeOfFile = fileSize - 1 const startRange = Number(range.replace(/\D/g, '')) - const endRange = Math.min(startRange + chunkSize - 1, fileSize - 1) + const endRange = Math.min(startRange + chunkSize - 1, endRangeOfFile) const headers = { - 'Content-Range': `bytes ${startRange}-${endRange}/${fileSize}`, + 'Content-Range': `bytes ${startRange}-${endRange}/${endRangeOfFile}`, 'Accept-Ranges': 'bytes', 'Content-Length': endRange - startRange + 1, 'Content-Type': 'application/octet-stream', @@ -210,10 +214,12 @@ export class AnnotatedSharedVaultFilesController extends BaseHttpController { response.writeHead(206, headers) const result = await this.streamDownloadFile.execute({ - ownerUuid: locals.sharedVaultUuid, - resourceRemoteIdentifier: locals.remoteIdentifier, + ownerUuid: locals.valetTokenData.sharedVaultUuid, + resourceRemoteIdentifier: locals.valetTokenData.remoteIdentifier, startRange, endRange, + valetToken: locals.valetToken, + endRangeOfFile, }) if (!result.success) { diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware.ts b/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware.ts index 4be3e9f98..108fc58a9 100644 --- a/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware.ts +++ b/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware.ts @@ -6,11 +6,14 @@ import { BaseMiddleware } from 'inversify-express-utils' import { Logger } from 'winston' import TYPES from '../../../Bootstrap/Types' +import { SharedVaultValetTokenResponseLocals } from './SharedVaultValetTokenResponseLocals' +import { ValetTokenRepositoryInterface } from '../../../Domain/ValetToken/ValetTokenRepositoryInterface' @injectable() export class SharedVaultValetTokenAuthMiddleware extends BaseMiddleware { constructor( @inject(TYPES.Files_ValetTokenDecoder) private tokenDecoder: TokenDecoderInterface, + @inject(TYPES.Files_ValetTokenRepository) private valetTokenRepository: ValetTokenRepositoryInterface, @inject(TYPES.Files_Logger) private logger: Logger, ) { super() @@ -32,6 +35,22 @@ export class SharedVaultValetTokenAuthMiddleware extends BaseMiddleware { return } + if (await this.valetTokenRepository.isUsed(valetToken)) { + this.logger.debug('Already used valet token.', { + valetToken, + codeTag: 'SharedVaultValetTokenAuthMiddleware', + }) + + response.status(401).send({ + error: { + tag: 'invalid-auth', + message: 'Invalid valet token.', + }, + }) + + return + } + const valetTokenData = this.tokenDecoder.decodeToken(valetToken) if (valetTokenData === undefined) { @@ -72,15 +91,18 @@ export class SharedVaultValetTokenAuthMiddleware extends BaseMiddleware { return } - const whitelistedData: SharedVaultValetTokenData = { - sharedVaultUuid: valetTokenData.sharedVaultUuid, - vaultOwnerUuid: valetTokenData.vaultOwnerUuid, - remoteIdentifier: valetTokenData.remoteIdentifier, - permittedOperation: valetTokenData.permittedOperation, - uploadBytesUsed: valetTokenData.uploadBytesUsed, - uploadBytesLimit: valetTokenData.uploadBytesLimit, - unencryptedFileSize: valetTokenData.unencryptedFileSize, - moveOperation: valetTokenData.moveOperation, + const whitelistedData: SharedVaultValetTokenResponseLocals = { + valetToken, + valetTokenData: { + sharedVaultUuid: valetTokenData.sharedVaultUuid, + vaultOwnerUuid: valetTokenData.vaultOwnerUuid, + remoteIdentifier: valetTokenData.remoteIdentifier, + permittedOperation: valetTokenData.permittedOperation, + uploadBytesUsed: valetTokenData.uploadBytesUsed, + uploadBytesLimit: valetTokenData.uploadBytesLimit, + unencryptedFileSize: valetTokenData.unencryptedFileSize, + moveOperation: valetTokenData.moveOperation, + }, } Object.assign(response.locals, whitelistedData) diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenResponseLocals.ts b/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenResponseLocals.ts new file mode 100644 index 000000000..7666072b5 --- /dev/null +++ b/packages/files/src/Infra/InversifyExpress/Middleware/SharedVaultValetTokenResponseLocals.ts @@ -0,0 +1,6 @@ +import { SharedVaultValetTokenData } from '@standardnotes/security' + +export interface SharedVaultValetTokenResponseLocals { + valetToken: string + valetTokenData: SharedVaultValetTokenData +} diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts index 4b1e2648b..6c165d4a3 100644 --- a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts +++ b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.spec.ts @@ -4,9 +4,11 @@ import { ValetTokenAuthMiddleware } from './ValetTokenAuthMiddleware' import { NextFunction, Request, Response } from 'express' import { Logger } from 'winston' import { TokenDecoderInterface, ValetTokenData } from '@standardnotes/security' +import { ValetTokenRepositoryInterface } from '../../../Domain/ValetToken/ValetTokenRepositoryInterface' describe('ValetTokenAuthMiddleware', () => { let tokenDecoder: TokenDecoderInterface + let valetTokenRepository: ValetTokenRepositoryInterface let request: Request let response: Response let next: NextFunction @@ -16,9 +18,12 @@ describe('ValetTokenAuthMiddleware', () => { error: jest.fn(), } as unknown as jest.Mocked - const createMiddleware = () => new ValetTokenAuthMiddleware(tokenDecoder, logger) + const createMiddleware = () => new ValetTokenAuthMiddleware(tokenDecoder, valetTokenRepository, logger) beforeEach(() => { + valetTokenRepository = {} as jest.Mocked + valetTokenRepository.isUsed = jest.fn().mockResolvedValue(false) + tokenDecoder = {} as jest.Mocked> tokenDecoder.decodeToken = jest.fn().mockReturnValue({ userUuid: '1-2-3', @@ -75,6 +80,7 @@ describe('ValetTokenAuthMiddleware', () => { ], uploadBytesLimit: -1, uploadBytesUsed: 80, + valetToken: 'valet-token', }) expect(next).toHaveBeenCalled() @@ -108,6 +114,7 @@ describe('ValetTokenAuthMiddleware', () => { ], uploadBytesLimit: -1, uploadBytesUsed: 80, + valetToken: 'valet-token', }) expect(next).toHaveBeenCalled() @@ -134,6 +141,16 @@ describe('ValetTokenAuthMiddleware', () => { expect(next).not.toHaveBeenCalled() }) + it('should not authorize user with valet token already used', async () => { + request.headers['x-valet-token'] = 'valet-token' + valetTokenRepository.isUsed = jest.fn().mockResolvedValue(true) + + await createMiddleware().handler(request, response, next) + + expect(response.status).toHaveBeenCalledWith(401) + expect(next).not.toHaveBeenCalled() + }) + it('should authorize user with no space left for upload for download operations', async () => { request.headers['x-valet-token'] = 'valet-token' @@ -163,6 +180,7 @@ describe('ValetTokenAuthMiddleware', () => { ], uploadBytesLimit: 100, uploadBytesUsed: 80, + valetToken: 'valet-token', }) expect(next).toHaveBeenCalled() diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts index 8cb5c842d..e4dea0075 100644 --- a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts +++ b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenAuthMiddleware.ts @@ -5,11 +5,14 @@ import { inject, injectable } from 'inversify' import { BaseMiddleware } from 'inversify-express-utils' import { Logger } from 'winston' import TYPES from '../../../Bootstrap/Types' +import { ValetTokenResponseLocals } from './ValetTokenResponseLocals' +import { ValetTokenRepositoryInterface } from '../../../Domain/ValetToken/ValetTokenRepositoryInterface' @injectable() export class ValetTokenAuthMiddleware extends BaseMiddleware { constructor( @inject(TYPES.Files_ValetTokenDecoder) private tokenDecoder: TokenDecoderInterface, + @inject(TYPES.Files_ValetTokenRepository) private valetTokenRepository: ValetTokenRepositoryInterface, @inject(TYPES.Files_Logger) private logger: Logger, ) { super() @@ -31,6 +34,22 @@ export class ValetTokenAuthMiddleware extends BaseMiddleware { return } + if (await this.valetTokenRepository.isUsed(valetToken)) { + this.logger.debug('Already used valet token.', { + valetToken, + codeTag: 'ValetTokenAuthMiddleware', + }) + + response.status(401).send({ + error: { + tag: 'invalid-auth', + message: 'Invalid valet token.', + }, + }) + + return + } + const valetTokenData = this.tokenDecoder.decodeToken(valetToken) if (valetTokenData === undefined) { @@ -73,12 +92,15 @@ export class ValetTokenAuthMiddleware extends BaseMiddleware { return } - response.locals.userUuid = valetTokenData.userUuid - response.locals.permittedResources = valetTokenData.permittedResources - response.locals.permittedOperation = valetTokenData.permittedOperation - response.locals.uploadBytesUsed = valetTokenData.uploadBytesUsed - response.locals.uploadBytesLimit = valetTokenData.uploadBytesLimit - response.locals.regularSubscriptionUuid = valetTokenData.regularSubscriptionUuid + Object.assign(response.locals, { + userUuid: valetTokenData.userUuid, + permittedResources: valetTokenData.permittedResources, + permittedOperation: valetTokenData.permittedOperation, + uploadBytesUsed: valetTokenData.uploadBytesUsed, + uploadBytesLimit: valetTokenData.uploadBytesLimit, + regularSubscriptionUuid: valetTokenData.regularSubscriptionUuid, + valetToken, + } as ValetTokenResponseLocals) return next() } catch (error) { diff --git a/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenResponseLocals.ts b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenResponseLocals.ts new file mode 100644 index 000000000..e5f256455 --- /dev/null +++ b/packages/files/src/Infra/InversifyExpress/Middleware/ValetTokenResponseLocals.ts @@ -0,0 +1,14 @@ +import { ValetTokenOperation } from '@standardnotes/security' + +export interface ValetTokenResponseLocals { + valetToken: string + userUuid: string + permittedResources: Array<{ + remoteIdentifier: string + unencryptedFileSize?: number + }> + permittedOperation: ValetTokenOperation + uploadBytesUsed: number + uploadBytesLimit: number + regularSubscriptionUuid: string +} diff --git a/packages/files/src/Infra/Redis/RedisValetTokenRepository.ts b/packages/files/src/Infra/Redis/RedisValetTokenRepository.ts new file mode 100644 index 000000000..1a41d8bc5 --- /dev/null +++ b/packages/files/src/Infra/Redis/RedisValetTokenRepository.ts @@ -0,0 +1,19 @@ +import * as IORedis from 'ioredis' + +import { ValetTokenRepositoryInterface } from '../../Domain/ValetToken/ValetTokenRepositoryInterface' + +export class RedisValetTokenRepository implements ValetTokenRepositoryInterface { + private readonly VALET_TOKEN_PREFIX = 'vt' + + constructor(private redisClient: IORedis.Redis) {} + + async markAsUsed(valetToken: string): Promise { + const dayInSeconds = 60 * 60 * 24 + + await this.redisClient.setex(`${this.VALET_TOKEN_PREFIX}:${valetToken}`, dayInSeconds, 'used') + } + + async isUsed(valetToken: string): Promise { + return (await this.redisClient.get(`${this.VALET_TOKEN_PREFIX}:${valetToken}`)) === 'used' + } +} diff --git a/packages/grpc/lib/auth_grpc_pb.d.ts b/packages/grpc/lib/auth_grpc_pb.d.ts index d525d9520..b2f58e58d 100644 --- a/packages/grpc/lib/auth_grpc_pb.d.ts +++ b/packages/grpc/lib/auth_grpc_pb.d.ts @@ -12,12 +12,12 @@ interface IAuthService extends grpc.ServiceDefinition { +interface IAuthService_Ivalidate extends grpc.MethodDefinition { path: "/auth.Auth/validate"; requestStream: false; responseStream: false; - requestSerialize: grpc.serialize; - requestDeserialize: grpc.deserialize; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; responseSerialize: grpc.serialize; responseDeserialize: grpc.deserialize; } @@ -34,14 +34,14 @@ interface IAuthService_IvalidateWebsocket extends grpc.MethodDefinition; + validate: grpc.handleUnaryCall; validateWebsocket: grpc.handleUnaryCall; } export interface IAuthClient { - validate(request: auth_pb.AuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; - validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; - validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; + validate(request: auth_pb.RequestValidationOptions, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; + validate(request: auth_pb.RequestValidationOptions, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; + validate(request: auth_pb.RequestValidationOptions, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall; validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall; validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall; @@ -49,9 +49,9 @@ export interface IAuthClient { export class AuthClient extends grpc.Client implements IAuthClient { constructor(address: string, credentials: grpc.ChannelCredentials, options?: object); - public validate(request: auth_pb.AuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; - public validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; - public validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; + public validate(request: auth_pb.RequestValidationOptions, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; + public validate(request: auth_pb.RequestValidationOptions, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; + public validate(request: auth_pb.RequestValidationOptions, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall; public validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall; public validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall; public validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall; diff --git a/packages/grpc/lib/auth_grpc_pb.js b/packages/grpc/lib/auth_grpc_pb.js index a56d9ea4f..2bc408b81 100644 --- a/packages/grpc/lib/auth_grpc_pb.js +++ b/packages/grpc/lib/auth_grpc_pb.js @@ -4,17 +4,6 @@ var grpc = require('@grpc/grpc-js'); var auth_pb = require('./auth_pb.js'); -function serialize_auth_AuthorizationHeader(arg) { - if (!(arg instanceof auth_pb.AuthorizationHeader)) { - throw new Error('Expected argument of type auth.AuthorizationHeader'); - } - return Buffer.from(arg.serializeBinary()); -} - -function deserialize_auth_AuthorizationHeader(buffer_arg) { - return auth_pb.AuthorizationHeader.deserializeBinary(new Uint8Array(buffer_arg)); -} - function serialize_auth_ConnectionValidationResponse(arg) { if (!(arg instanceof auth_pb.ConnectionValidationResponse)) { throw new Error('Expected argument of type auth.ConnectionValidationResponse'); @@ -26,6 +15,17 @@ function deserialize_auth_ConnectionValidationResponse(buffer_arg) { return auth_pb.ConnectionValidationResponse.deserializeBinary(new Uint8Array(buffer_arg)); } +function serialize_auth_RequestValidationOptions(arg) { + if (!(arg instanceof auth_pb.RequestValidationOptions)) { + throw new Error('Expected argument of type auth.RequestValidationOptions'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_auth_RequestValidationOptions(buffer_arg) { + return auth_pb.RequestValidationOptions.deserializeBinary(new Uint8Array(buffer_arg)); +} + function serialize_auth_SessionValidationResponse(arg) { if (!(arg instanceof auth_pb.SessionValidationResponse)) { throw new Error('Expected argument of type auth.SessionValidationResponse'); @@ -54,10 +54,10 @@ var AuthService = exports.AuthService = { path: '/auth.Auth/validate', requestStream: false, responseStream: false, - requestType: auth_pb.AuthorizationHeader, + requestType: auth_pb.RequestValidationOptions, responseType: auth_pb.SessionValidationResponse, - requestSerialize: serialize_auth_AuthorizationHeader, - requestDeserialize: deserialize_auth_AuthorizationHeader, + requestSerialize: serialize_auth_RequestValidationOptions, + requestDeserialize: deserialize_auth_RequestValidationOptions, responseSerialize: serialize_auth_SessionValidationResponse, responseDeserialize: deserialize_auth_SessionValidationResponse, }, diff --git a/packages/grpc/lib/auth_pb.d.ts b/packages/grpc/lib/auth_pb.d.ts index 7bb7b0f9b..57f2e9610 100644 --- a/packages/grpc/lib/auth_pb.d.ts +++ b/packages/grpc/lib/auth_pb.d.ts @@ -6,23 +6,57 @@ import * as jspb from "google-protobuf"; -export class AuthorizationHeader extends jspb.Message { - getBearerToken(): string; - setBearerToken(value: string): AuthorizationHeader; +export class Cookie extends jspb.Message { + getName(): string; + setName(value: string): Cookie; + getValue(): string; + setValue(value: string): Cookie; serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): AuthorizationHeader.AsObject; - static toObject(includeInstance: boolean, msg: AuthorizationHeader): AuthorizationHeader.AsObject; + toObject(includeInstance?: boolean): Cookie.AsObject; + static toObject(includeInstance: boolean, msg: Cookie): Cookie.AsObject; static extensions: {[key: number]: jspb.ExtensionFieldInfo}; static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; - static serializeBinaryToWriter(message: AuthorizationHeader, writer: jspb.BinaryWriter): void; - static deserializeBinary(bytes: Uint8Array): AuthorizationHeader; - static deserializeBinaryFromReader(message: AuthorizationHeader, reader: jspb.BinaryReader): AuthorizationHeader; + static serializeBinaryToWriter(message: Cookie, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): Cookie; + static deserializeBinaryFromReader(message: Cookie, reader: jspb.BinaryReader): Cookie; } -export namespace AuthorizationHeader { +export namespace Cookie { + export type AsObject = { + name: string, + value: string, + } +} + +export class RequestValidationOptions extends jspb.Message { + getBearerToken(): string; + setBearerToken(value: string): RequestValidationOptions; + clearCookieList(): void; + getCookieList(): Array; + setCookieList(value: Array): RequestValidationOptions; + addCookie(value?: Cookie, index?: number): Cookie; + + hasSharedVaultOwnerContext(): boolean; + clearSharedVaultOwnerContext(): void; + getSharedVaultOwnerContext(): string | undefined; + setSharedVaultOwnerContext(value: string): RequestValidationOptions; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RequestValidationOptions.AsObject; + static toObject(includeInstance: boolean, msg: RequestValidationOptions): RequestValidationOptions.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: RequestValidationOptions, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RequestValidationOptions; + static deserializeBinaryFromReader(message: RequestValidationOptions, reader: jspb.BinaryReader): RequestValidationOptions; +} + +export namespace RequestValidationOptions { export type AsObject = { bearerToken: string, + cookieList: Array, + sharedVaultOwnerContext?: string, } } diff --git a/packages/grpc/lib/auth_pb.js b/packages/grpc/lib/auth_pb.js index 1e34c4e2b..fb49ebe06 100644 --- a/packages/grpc/lib/auth_pb.js +++ b/packages/grpc/lib/auth_pb.js @@ -21,8 +21,9 @@ var global = (function() { return Function('return this')(); }.call(null)); -goog.exportSymbol('proto.auth.AuthorizationHeader', null, global); goog.exportSymbol('proto.auth.ConnectionValidationResponse', null, global); +goog.exportSymbol('proto.auth.Cookie', null, global); +goog.exportSymbol('proto.auth.RequestValidationOptions', null, global); goog.exportSymbol('proto.auth.SessionValidationResponse', null, global); goog.exportSymbol('proto.auth.WebsocketConnectionAuthorizationHeader', null, global); /** @@ -35,16 +36,37 @@ goog.exportSymbol('proto.auth.WebsocketConnectionAuthorizationHeader', null, glo * @extends {jspb.Message} * @constructor */ -proto.auth.AuthorizationHeader = function(opt_data) { +proto.auth.Cookie = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; -goog.inherits(proto.auth.AuthorizationHeader, jspb.Message); +goog.inherits(proto.auth.Cookie, jspb.Message); if (goog.DEBUG && !COMPILED) { /** * @public * @override */ - proto.auth.AuthorizationHeader.displayName = 'proto.auth.AuthorizationHeader'; + proto.auth.Cookie.displayName = 'proto.auth.Cookie'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.auth.RequestValidationOptions = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.auth.RequestValidationOptions.repeatedFields_, null); +}; +goog.inherits(proto.auth.RequestValidationOptions, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.auth.RequestValidationOptions.displayName = 'proto.auth.RequestValidationOptions'; } /** * Generated by JsPbCodeGenerator. @@ -125,8 +147,8 @@ if (jspb.Message.GENERATE_TO_OBJECT) { * http://goto/soy-param-migration * @return {!Object} */ -proto.auth.AuthorizationHeader.prototype.toObject = function(opt_includeInstance) { - return proto.auth.AuthorizationHeader.toObject(opt_includeInstance, this); +proto.auth.Cookie.prototype.toObject = function(opt_includeInstance) { + return proto.auth.Cookie.toObject(opt_includeInstance, this); }; @@ -135,13 +157,14 @@ proto.auth.AuthorizationHeader.prototype.toObject = function(opt_includeInstance * @param {boolean|undefined} includeInstance Deprecated. Whether to include * the JSPB instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.auth.AuthorizationHeader} msg The msg instance to transform. + * @param {!proto.auth.Cookie} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.auth.AuthorizationHeader.toObject = function(includeInstance, msg) { +proto.auth.Cookie.toObject = function(includeInstance, msg) { var f, obj = { - bearerToken: jspb.Message.getFieldWithDefault(msg, 1, "") + name: jspb.Message.getFieldWithDefault(msg, 1, ""), + value: jspb.Message.getFieldWithDefault(msg, 2, "") }; if (includeInstance) { @@ -155,23 +178,23 @@ proto.auth.AuthorizationHeader.toObject = function(includeInstance, msg) { /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.auth.AuthorizationHeader} + * @return {!proto.auth.Cookie} */ -proto.auth.AuthorizationHeader.deserializeBinary = function(bytes) { +proto.auth.Cookie.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.auth.AuthorizationHeader; - return proto.auth.AuthorizationHeader.deserializeBinaryFromReader(msg, reader); + var msg = new proto.auth.Cookie; + return proto.auth.Cookie.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.auth.AuthorizationHeader} msg The message object to deserialize into. + * @param {!proto.auth.Cookie} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.auth.AuthorizationHeader} + * @return {!proto.auth.Cookie} */ -proto.auth.AuthorizationHeader.deserializeBinaryFromReader = function(msg, reader) { +proto.auth.Cookie.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -180,7 +203,11 @@ proto.auth.AuthorizationHeader.deserializeBinaryFromReader = function(msg, reade switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); - msg.setBearerToken(value); + msg.setName(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setValue(value); break; default: reader.skipField(); @@ -195,9 +222,9 @@ proto.auth.AuthorizationHeader.deserializeBinaryFromReader = function(msg, reade * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.auth.AuthorizationHeader.prototype.serializeBinary = function() { +proto.auth.Cookie.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.auth.AuthorizationHeader.serializeBinaryToWriter(this, writer); + proto.auth.Cookie.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -205,11 +232,185 @@ proto.auth.AuthorizationHeader.prototype.serializeBinary = function() { /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.auth.AuthorizationHeader} message + * @param {!proto.auth.Cookie} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.auth.AuthorizationHeader.serializeBinaryToWriter = function(message, writer) { +proto.auth.Cookie.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getName(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getValue(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } +}; + + +/** + * optional string name = 1; + * @return {string} + */ +proto.auth.Cookie.prototype.getName = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.auth.Cookie} returns this + */ +proto.auth.Cookie.prototype.setName = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string value = 2; + * @return {string} + */ +proto.auth.Cookie.prototype.getValue = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.auth.Cookie} returns this + */ +proto.auth.Cookie.prototype.setValue = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.auth.RequestValidationOptions.repeatedFields_ = [2]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.auth.RequestValidationOptions.prototype.toObject = function(opt_includeInstance) { + return proto.auth.RequestValidationOptions.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.auth.RequestValidationOptions} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.auth.RequestValidationOptions.toObject = function(includeInstance, msg) { + var f, obj = { + bearerToken: jspb.Message.getFieldWithDefault(msg, 1, ""), + cookieList: jspb.Message.toObjectList(msg.getCookieList(), + proto.auth.Cookie.toObject, includeInstance), + sharedVaultOwnerContext: jspb.Message.getFieldWithDefault(msg, 3, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.auth.RequestValidationOptions} + */ +proto.auth.RequestValidationOptions.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.auth.RequestValidationOptions; + return proto.auth.RequestValidationOptions.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.auth.RequestValidationOptions} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.auth.RequestValidationOptions} + */ +proto.auth.RequestValidationOptions.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setBearerToken(value); + break; + case 2: + var value = new proto.auth.Cookie; + reader.readMessage(value,proto.auth.Cookie.deserializeBinaryFromReader); + msg.addCookie(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setSharedVaultOwnerContext(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.auth.RequestValidationOptions.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.auth.RequestValidationOptions.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.auth.RequestValidationOptions} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.auth.RequestValidationOptions.serializeBinaryToWriter = function(message, writer) { var f = undefined; f = message.getBearerToken(); if (f.length > 0) { @@ -218,6 +419,21 @@ proto.auth.AuthorizationHeader.serializeBinaryToWriter = function(message, write f ); } + f = message.getCookieList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 2, + f, + proto.auth.Cookie.serializeBinaryToWriter + ); + } + f = /** @type {string} */ (jspb.Message.getField(message, 3)); + if (f != null) { + writer.writeString( + 3, + f + ); + } }; @@ -225,20 +441,94 @@ proto.auth.AuthorizationHeader.serializeBinaryToWriter = function(message, write * optional string bearer_token = 1; * @return {string} */ -proto.auth.AuthorizationHeader.prototype.getBearerToken = function() { +proto.auth.RequestValidationOptions.prototype.getBearerToken = function() { return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); }; /** * @param {string} value - * @return {!proto.auth.AuthorizationHeader} returns this + * @return {!proto.auth.RequestValidationOptions} returns this */ -proto.auth.AuthorizationHeader.prototype.setBearerToken = function(value) { +proto.auth.RequestValidationOptions.prototype.setBearerToken = function(value) { return jspb.Message.setProto3StringField(this, 1, value); }; +/** + * repeated Cookie cookie = 2; + * @return {!Array} + */ +proto.auth.RequestValidationOptions.prototype.getCookieList = function() { + return /** @type{!Array} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.auth.Cookie, 2)); +}; + + +/** + * @param {!Array} value + * @return {!proto.auth.RequestValidationOptions} returns this +*/ +proto.auth.RequestValidationOptions.prototype.setCookieList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 2, value); +}; + + +/** + * @param {!proto.auth.Cookie=} opt_value + * @param {number=} opt_index + * @return {!proto.auth.Cookie} + */ +proto.auth.RequestValidationOptions.prototype.addCookie = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.auth.Cookie, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.auth.RequestValidationOptions} returns this + */ +proto.auth.RequestValidationOptions.prototype.clearCookieList = function() { + return this.setCookieList([]); +}; + + +/** + * optional string shared_vault_owner_context = 3; + * @return {string} + */ +proto.auth.RequestValidationOptions.prototype.getSharedVaultOwnerContext = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.auth.RequestValidationOptions} returns this + */ +proto.auth.RequestValidationOptions.prototype.setSharedVaultOwnerContext = function(value) { + return jspb.Message.setField(this, 3, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.auth.RequestValidationOptions} returns this + */ +proto.auth.RequestValidationOptions.prototype.clearSharedVaultOwnerContext = function() { + return jspb.Message.setField(this, 3, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.auth.RequestValidationOptions.prototype.hasSharedVaultOwnerContext = function() { + return jspb.Message.getField(this, 3) != null; +}; + + diff --git a/packages/grpc/proto/auth.proto b/packages/grpc/proto/auth.proto index 6ee183dfd..ef36e6f1c 100644 --- a/packages/grpc/proto/auth.proto +++ b/packages/grpc/proto/auth.proto @@ -2,8 +2,15 @@ syntax = "proto3"; package auth; -message AuthorizationHeader { +message Cookie { + string name = 1; + string value = 2; +} + +message RequestValidationOptions { string bearer_token = 1; + repeated Cookie cookie = 2; + optional string shared_vault_owner_context = 3; } message SessionValidationResponse { @@ -19,6 +26,6 @@ message ConnectionValidationResponse { } service Auth { - rpc validate(AuthorizationHeader) returns (SessionValidationResponse) {} + rpc validate(RequestValidationOptions) returns (SessionValidationResponse) {} rpc validateWebsocket(WebsocketConnectionAuthorizationHeader) returns (ConnectionValidationResponse) {} } diff --git a/packages/home-server/.env.sample b/packages/home-server/.env.sample index 33bc977b0..0ae57cfc1 100644 --- a/packages/home-server/.env.sample +++ b/packages/home-server/.env.sample @@ -9,3 +9,7 @@ PSEUDO_KEY_PARAMS_KEY= VALET_TOKEN_SECRET= FILES_SERVER_URL= + +COOKIE_DOMAIN=localhost +COOKIE_SECURE=false +COOKIE_PARTITIONED=false diff --git a/packages/home-server/CHANGELOG.md b/packages/home-server/CHANGELOG.md index 3eb34f526..a4daf83f2 100644 --- a/packages/home-server/CHANGELOG.md +++ b/packages/home-server/CHANGELOG.md @@ -3,34 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -# [1.23.0](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.68...@standardnotes/home-server@1.23.0) (2024-03-20) - -### Features - -* add CORS_ORIGIN_STRICT_MODE_ENABLED env var to determine if CORS origin should be restricted ([5c02435](https://github.com/standardnotes/server/commit/5c02435ee478b893747d3f9e41062aae12d7ff10)) - -## [1.22.68](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.67...@standardnotes/home-server@1.22.68) (2024-03-18) - -**Note:** Version bump only for package @standardnotes/home-server - -## [1.22.67](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.66...@standardnotes/home-server@1.22.67) (2024-03-18) - -### Bug Fixes - -* cors issues on clients - fixes [#1046](https://github.com/standardnotes/server/issues/1046) ([#1049](https://github.com/standardnotes/server/issues/1049)) ([6d7ca1b](https://github.com/standardnotes/server/commit/6d7ca1b926fd45d744275bd3c1f4c05b010f76c8)) - -## [1.22.66](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.65...@standardnotes/home-server@1.22.66) (2024-03-18) - -**Note:** Version bump only for package @standardnotes/home-server - -## [1.22.65](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.64...@standardnotes/home-server@1.22.65) (2024-03-15) - -**Note:** Version bump only for package @standardnotes/home-server - -## [1.22.64](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.63...@standardnotes/home-server@1.22.64) (2024-02-09) - -**Note:** Version bump only for package @standardnotes/home-server - ## [1.22.63](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.22.62...@standardnotes/home-server@1.22.63) (2024-01-19) **Note:** Version bump only for package @standardnotes/home-server diff --git a/packages/home-server/package.json b/packages/home-server/package.json index 2c90ab310..8ff53e6bb 100644 --- a/packages/home-server/package.json +++ b/packages/home-server/package.json @@ -1,6 +1,6 @@ { "name": "@standardnotes/home-server", - "version": "1.23.0", + "version": "1.22.63", "engines": { "node": ">=18.0.0 <21.0.0" }, @@ -33,6 +33,7 @@ "@standardnotes/files-server": "workspace:^", "@standardnotes/revisions-server": "workspace:^", "@standardnotes/syncing-server": "workspace:^", + "cookie-parser": "^1.4.6", "cors": "2.8.5", "dotenv": "^16.0.1", "express": "^4.18.2", @@ -44,6 +45,7 @@ "winston": "^3.8.1" }, "devDependencies": { + "@types/cookie-parser": "^1", "@types/cors": "^2.8.9", "@types/express": "^4.17.14", "@typescript-eslint/eslint-plugin": "^6.5.0", diff --git a/packages/home-server/src/Server/HomeServer.ts b/packages/home-server/src/Server/HomeServer.ts index e01d54f50..c724bb942 100644 --- a/packages/home-server/src/Server/HomeServer.ts +++ b/packages/home-server/src/Server/HomeServer.ts @@ -11,6 +11,7 @@ import { Container } from 'inversify' import { InversifyExpressServer } from 'inversify-express-utils' import helmet from 'helmet' import * as cors from 'cors' +import * as cookieParser from 'cookie-parser' import * as http from 'http' import { text, json, Request, Response, NextFunction, raw } from 'express' import * as winston from 'winston' @@ -129,6 +130,9 @@ export class HomeServer implements HomeServerInterface { ], }), ) + + app.use(cookieParser()) + const corsAllowedOrigins = env.get('CORS_ALLOWED_ORIGINS', true) ? env.get('CORS_ALLOWED_ORIGINS', true).split(',') : [] diff --git a/packages/predicates/package.json b/packages/predicates/package.json index ab583f740..41dfb20bb 100644 --- a/packages/predicates/package.json +++ b/packages/predicates/package.json @@ -28,7 +28,7 @@ "start": "tsc -p tsconfig.json --watch", "build": "tsc --build", "lint": "eslint . --ext .ts", - "test": "jest --coverage --no-cache --passWithNoTests" + "test": "jest --coverage --no-cache --passWithNoTests --maxWorkers=2" }, "devDependencies": { "@types/jest": "^29.5.1", diff --git a/packages/revisions/Dockerfile b/packages/revisions/Dockerfile index a76805ee8..185e30399 100644 --- a/packages/revisions/Dockerfile +++ b/packages/revisions/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/revisions ENTRYPOINT [ "/workspace/packages/revisions/docker/entrypoint.sh" ] diff --git a/packages/revisions/package.json b/packages/revisions/package.json index 02e2d7560..129200ff2 100644 --- a/packages/revisions/package.json +++ b/packages/revisions/package.json @@ -24,8 +24,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "pretest": "yarn lint && yarn build", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "start": "yarn node dist/bin/server.js", "worker": "yarn node dist/bin/worker.js" }, @@ -47,7 +46,7 @@ "inversify": "^6.0.1", "inversify-express-utils": "^6.4.3", "ioredis": "^5.3.2", - "mysql2": "^3.0.1", + "mysql2": "^3.9.7", "reflect-metadata": "^0.2.1", "sqlite3": "^5.1.6", "typeorm": "^0.3.17", diff --git a/packages/scheduler/Dockerfile b/packages/scheduler/Dockerfile index f17c88332..90982b25d 100644 --- a/packages/scheduler/Dockerfile +++ b/packages/scheduler/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/scheduler ENTRYPOINT [ "/workspace/packages/scheduler/docker/entrypoint.sh" ] diff --git a/packages/scheduler/package.json b/packages/scheduler/package.json index c049b292b..1c0484293 100644 --- a/packages/scheduler/package.json +++ b/packages/scheduler/package.json @@ -20,8 +20,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "pretest": "yarn lint && yarn build", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "worker": "yarn node dist/bin/worker.js", "verify:jobs": "yarn node dist/bin/verify.js", "setup:env": "cp .env.sample .env", @@ -39,7 +38,7 @@ "dotenv": "^16.0.1", "inversify": "^6.0.1", "ioredis": "^5.2.4", - "mysql2": "^3.0.1", + "mysql2": "^3.9.7", "reflect-metadata": "^0.2.1", "typeorm": "^0.3.17", "winston": "^3.8.1" diff --git a/packages/security/package.json b/packages/security/package.json index 76ba31016..2875e78c0 100644 --- a/packages/security/package.json +++ b/packages/security/package.json @@ -28,7 +28,7 @@ "start": "tsc -p tsconfig.json --watch", "build": "tsc --build", "lint": "eslint . --ext .ts", - "test": "jest --coverage --no-cache" + "test": "jest --coverage --no-cache --maxWorkers=2" }, "dependencies": { "jsonwebtoken": "^9.0.0", diff --git a/packages/security/src/Domain/Token/CrossServiceTokenData.ts b/packages/security/src/Domain/Token/CrossServiceTokenData.ts index 8064c74fa..2eafa4ae7 100644 --- a/packages/security/src/Domain/Token/CrossServiceTokenData.ts +++ b/packages/security/src/Domain/Token/CrossServiceTokenData.ts @@ -24,4 +24,5 @@ export type CrossServiceTokenData = { refresh_expiration: string } extensionKey?: string + hasContentLimit?: boolean } diff --git a/packages/settings/src/Domain/index.ts b/packages/settings/src/Domain/index.ts index 0a29f80aa..483a0223c 100644 --- a/packages/settings/src/Domain/index.ts +++ b/packages/settings/src/Domain/index.ts @@ -1,6 +1,5 @@ export * from './EmailBackupFrequency/EmailBackupFrequency' export * from './ListedAuthorSecretsData/ListedAuthorSecretsData' export * from './LogSessionUserAgent/LogSessionUserAgentOption' -export * from './MuteFailedBackupsEmails/MuteFailedBackupsEmailsOption' export * from './MuteMarketingEmails/MuteMarketingEmailsOption' export * from './MuteSignInEmails/MuteSignInEmailsOption' diff --git a/packages/sncrypto-node/package.json b/packages/sncrypto-node/package.json index 9b5607dbe..b6b32cc23 100644 --- a/packages/sncrypto-node/package.json +++ b/packages/sncrypto-node/package.json @@ -26,7 +26,7 @@ "clean": "rm -fr dist", "build": "tsc --build", "lint": "eslint . --ext .ts", - "test": "jest spec" + "test": "jest --coverage --no-cache --maxWorkers=2" }, "dependencies": { "@standardnotes/sncrypto-common": "^1.13.4", diff --git a/packages/syncing-server/CHANGELOG.md b/packages/syncing-server/CHANGELOG.md index c7e3f74fb..4f58a6176 100644 --- a/packages/syncing-server/CHANGELOG.md +++ b/packages/syncing-server/CHANGELOG.md @@ -3,12 +3,6 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. -## [1.136.2](https://github.com/standardnotes/server/compare/@standardnotes/syncing-server@1.136.1...@standardnotes/syncing-server@1.136.2) (2024-03-15) - -### Bug Fixes - -* allow handling of new api version ([9d49764](https://github.com/standardnotes/server/commit/9d49764b841e73655e19523eddf10498addc9fb4)) - ## [1.136.1](https://github.com/standardnotes/server/compare/@standardnotes/syncing-server@1.136.0...@standardnotes/syncing-server@1.136.1) (2024-01-19) **Note:** Version bump only for package @standardnotes/syncing-server diff --git a/packages/syncing-server/Dockerfile b/packages/syncing-server/Dockerfile index f17a3eae3..ab16d812f 100644 --- a/packages/syncing-server/Dockerfile +++ b/packages/syncing-server/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/syncing-server ENTRYPOINT [ "/workspace/packages/syncing-server/docker/entrypoint.sh" ] diff --git a/packages/syncing-server/package.json b/packages/syncing-server/package.json index 596d15dbd..76179fdf6 100644 --- a/packages/syncing-server/package.json +++ b/packages/syncing-server/package.json @@ -1,6 +1,6 @@ { "name": "@standardnotes/syncing-server", - "version": "1.136.2", + "version": "1.136.1", "engines": { "node": ">=18.0.0 <21.0.0" }, @@ -24,8 +24,7 @@ "build": "tsc --build", "lint": "eslint . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", - "pretest": "yarn lint && yarn build", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "start": "yarn node dist/bin/server.js", "worker": "yarn node dist/bin/worker.js", "content-size": "yarn node dist/bin/content.js", @@ -56,7 +55,7 @@ "inversify-express-utils": "^6.4.3", "ioredis": "^5.3.2", "jsonwebtoken": "^9.0.0", - "mysql2": "^3.0.1", + "mysql2": "^3.9.7", "prettyjson": "^1.2.5", "reflect-metadata": "^0.2.1", "semver": "^7.5.4", diff --git a/packages/syncing-server/src/Bootstrap/Container.ts b/packages/syncing-server/src/Bootstrap/Container.ts index dc93e4a12..9d20a8ce4 100644 --- a/packages/syncing-server/src/Bootstrap/Container.ts +++ b/packages/syncing-server/src/Bootstrap/Container.ts @@ -169,8 +169,10 @@ import { DummyMetricStore } from '../Infra/Dummy/DummyMetricStore' import { CheckForTrafficAbuse } from '../Domain/UseCase/Syncing/CheckForTrafficAbuse/CheckForTrafficAbuse' import { FixContentSizes } from '../Domain/UseCase/Syncing/FixContentSizes/FixContentSizes' import { ContentSizesFixRequestedEventHandler } from '../Domain/Handler/ContentSizesFixRequestedEventHandler' +import { CheckForContentLimit } from '../Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit' export class ContainerConfigLoader { + private readonly DEFAULT_FREE_USER_CONTENT_LIMIT_BYTES = 100_000_000 private readonly DEFAULT_CONTENT_SIZE_TRANSFER_LIMIT = 10_000_000 private readonly DEFAULT_MAX_ITEMS_LIMIT = 300 private readonly DEFAULT_FILE_UPLOAD_PATH = `${__dirname}/../../uploads` @@ -538,6 +540,13 @@ export class ContainerConfigLoader { .toConstantValue( env.get('MAX_ITEMS_LIMIT', true) ? +env.get('MAX_ITEMS_LIMIT', true) : this.DEFAULT_MAX_ITEMS_LIMIT, ) + container + .bind(TYPES.Sync_FREE_USER_CONTENT_LIMIT_BYTES) + .toConstantValue( + env.get('FREE_USER_CONTENT_LIMIT_BYTES', true) + ? +env.get('FREE_USER_CONTENT_LIMIT_BYTES', true) + : this.DEFAULT_FREE_USER_CONTENT_LIMIT_BYTES, + ) container.bind(TYPES.Sync_VALET_TOKEN_SECRET).toConstantValue(env.get('VALET_TOKEN_SECRET', true)) container .bind(TYPES.Sync_VALET_TOKEN_TTL) @@ -691,6 +700,14 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_MetricsStore), ), ) + container + .bind(TYPES.Sync_CheckForContentLimit) + .toConstantValue( + new CheckForContentLimit( + container.get(TYPES.Sync_SQLItemRepository), + container.get(TYPES.Sync_FREE_USER_CONTENT_LIMIT_BYTES), + ), + ) container .bind(TYPES.Sync_SaveItems) .toConstantValue( @@ -703,6 +720,7 @@ export class ContainerConfigLoader { container.get(TYPES.Sync_SendEventToClient), container.get(TYPES.Sync_SendEventToClients), container.get(TYPES.Sync_DomainEventFactory), + container.get(TYPES.Sync_CheckForContentLimit), container.get(TYPES.Sync_Logger), ), ) diff --git a/packages/syncing-server/src/Bootstrap/Types.ts b/packages/syncing-server/src/Bootstrap/Types.ts index 7d71b9a33..1c2abbebb 100644 --- a/packages/syncing-server/src/Bootstrap/Types.ts +++ b/packages/syncing-server/src/Bootstrap/Types.ts @@ -38,6 +38,7 @@ const TYPES = { Sync_VERSION: Symbol.for('Sync_VERSION'), Sync_CONTENT_SIZE_TRANSFER_LIMIT: Symbol.for('Sync_CONTENT_SIZE_TRANSFER_LIMIT'), Sync_MAX_ITEMS_LIMIT: Symbol.for('Sync_MAX_ITEMS_LIMIT'), + Sync_FREE_USER_CONTENT_LIMIT_BYTES: Symbol.for('Sync_FREE_USER_CONTENT_LIMIT_BYTES'), Sync_FILE_UPLOAD_PATH: Symbol.for('Sync_FILE_UPLOAD_PATH'), Sync_VALET_TOKEN_SECRET: Symbol.for('Sync_VALET_TOKEN_SECRET'), Sync_VALET_TOKEN_TTL: Symbol.for('Sync_VALET_TOKEN_TTL'), @@ -84,6 +85,7 @@ const TYPES = { Sync_UpdateExistingItem: Symbol.for('Sync_UpdateExistingItem'), Sync_GetItems: Symbol.for('Sync_GetItems'), Sync_SaveItems: Symbol.for('Sync_SaveItems'), + Sync_CheckForContentLimit: Symbol.for('Sync_CheckForContentLimit'), Sync_GetUserNotifications: Symbol.for('Sync_GetUserNotifications'), Sync_DetermineSharedVaultOperationOnItem: Symbol.for('Sync_DetermineSharedVaultOperationOnItem'), Sync_UpdateStorageQuotaUsedInSharedVault: Symbol.for('Sync_UpdateStorageQuotaUsedInSharedVault'), diff --git a/packages/syncing-server/src/Domain/Item/ItemHash.ts b/packages/syncing-server/src/Domain/Item/ItemHash.ts index 447e8a8b6..95351be32 100644 --- a/packages/syncing-server/src/Domain/Item/ItemHash.ts +++ b/packages/syncing-server/src/Domain/Item/ItemHash.ts @@ -22,6 +22,10 @@ export class ItemHash extends ValueObject { return this.props.shared_vault_uuid !== null } + calculateContentSize(): number { + return Buffer.byteLength(JSON.stringify(this)) + } + get sharedVaultUuid(): Uuid | null { if (!this.representsASharedVaultItem()) { return null diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.spec.ts new file mode 100644 index 000000000..476b2e89a --- /dev/null +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.spec.ts @@ -0,0 +1,95 @@ +import { ContentType } from '@standardnotes/domain-core' +import { ItemContentSizeDescriptor } from '../../../Item/ItemContentSizeDescriptor' +import { ItemHash } from '../../../Item/ItemHash' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' +import { CheckForContentLimit } from './CheckForContentLimit' + +describe('CheckForContentLimit', () => { + let itemRepository: ItemRepositoryInterface + let freeUserContentLimitInBytes: number + let itemHash: ItemHash + + const createUseCase = () => new CheckForContentLimit(itemRepository, freeUserContentLimitInBytes) + + beforeEach(() => { + itemRepository = {} as ItemRepositoryInterface + + itemHash = ItemHash.create({ + uuid: '00000000-0000-0000-0000-000000000000', + content: 'test content', + content_type: ContentType.TYPES.Note, + user_uuid: '00000000-0000-0000-0000-000000000000', + key_system_identifier: null, + shared_vault_uuid: null, + }).getValue() + + freeUserContentLimitInBytes = 100 + }) + + it('should return a failure result if user uuid is invalid', async () => { + const useCase = createUseCase() + const result = await useCase.execute({ userUuid: 'invalid-uuid', itemsBeingModified: [itemHash] }) + + expect(result.isFailed()).toBe(true) + }) + + it('should return a failure result if user has exceeded their content limit', async () => { + itemRepository.findContentSizeForComputingTransferLimit = jest + .fn() + .mockResolvedValue([ItemContentSizeDescriptor.create('00000000-0000-0000-0000-000000000000', 101).getValue()]) + + const useCase = createUseCase() + const result = await useCase.execute({ + userUuid: '00000000-0000-0000-0000-000000000000', + itemsBeingModified: [itemHash], + }) + + expect(result.isFailed()).toBe(true) + }) + + it('should return a success result if user has not exceeded their content limit', async () => { + itemRepository.findContentSizeForComputingTransferLimit = jest + .fn() + .mockResolvedValue([ItemContentSizeDescriptor.create('00000000-0000-0000-0000-000000000000', 99).getValue()]) + + const useCase = createUseCase() + const result = await useCase.execute({ + userUuid: '00000000-0000-0000-0000-000000000000', + itemsBeingModified: [itemHash], + }) + + expect(result.isFailed()).toBe(false) + }) + + it('should return a success result if user has exceeded their content limit but user modifications are not increasing content size', async () => { + itemHash.calculateContentSize = jest.fn().mockReturnValue(99) + + itemRepository.findContentSizeForComputingTransferLimit = jest + .fn() + .mockResolvedValue([ItemContentSizeDescriptor.create('00000000-0000-0000-0000-000000000000', 101).getValue()]) + + const useCase = createUseCase() + const result = await useCase.execute({ + userUuid: '00000000-0000-0000-0000-000000000000', + itemsBeingModified: [itemHash], + }) + + expect(result.isFailed()).toBe(false) + }) + + it('should treat items with no content size defined as 0', async () => { + itemHash.calculateContentSize = jest.fn().mockReturnValue(99) + + itemRepository.findContentSizeForComputingTransferLimit = jest + .fn() + .mockResolvedValue([ItemContentSizeDescriptor.create('00000000-0000-0000-0000-000000000000', null).getValue()]) + + const useCase = createUseCase() + const result = await useCase.execute({ + userUuid: '00000000-0000-0000-0000-000000000000', + itemsBeingModified: [itemHash], + }) + + expect(result.isFailed()).toBe(false) + }) +}) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.ts new file mode 100644 index 000000000..3bc49778d --- /dev/null +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimit.ts @@ -0,0 +1,66 @@ +import { Result, UseCaseInterface, Uuid } from '@standardnotes/domain-core' + +import { CheckForContentLimitDTO } from './CheckForContentLimitDTO' +import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' +import { ItemContentSizeDescriptor } from '../../../Item/ItemContentSizeDescriptor' +import { ItemHash } from '../../../Item/ItemHash' + +export class CheckForContentLimit implements UseCaseInterface { + constructor( + private itemRepository: ItemRepositoryInterface, + private freeUserContentLimitInBytes: number, + ) {} + + async execute(dto: CheckForContentLimitDTO): Promise> { + const userUuidOrError = Uuid.create(dto.userUuid) + if (userUuidOrError.isFailed()) { + return Result.fail(userUuidOrError.getError()) + } + const userUuid = userUuidOrError.getValue() + + const contentSizeDescriptors = await this.itemRepository.findContentSizeForComputingTransferLimit({ + userUuid: userUuid.value, + }) + + const isContentLimitExceeded = await this.isContentLimitExceeded(contentSizeDescriptors) + const isUserModificationsIncreasingContentSize = this.userModificationsAreIncreasingContentSize( + contentSizeDescriptors, + dto.itemsBeingModified, + ) + + if (isContentLimitExceeded && isUserModificationsIncreasingContentSize) { + return Result.fail('You have exceeded your content limit. Please upgrade your account.') + } + + return Result.ok() + } + + private userModificationsAreIncreasingContentSize( + contentSizeDescriptors: ItemContentSizeDescriptor[], + itemHashes: ItemHash[], + ): boolean { + for (const itemHash of itemHashes) { + const contentSizeDescriptor = contentSizeDescriptors.find( + (descriptor) => descriptor.props.uuid.value === itemHash.props.uuid, + ) + if (contentSizeDescriptor) { + const afterModificationSize = itemHash.calculateContentSize() + const beforeModificationSize = contentSizeDescriptor.props.contentSize ?? 0 + if (afterModificationSize > beforeModificationSize) { + return true + } + } + } + + return false + } + + private async isContentLimitExceeded(contentSizeDescriptors: ItemContentSizeDescriptor[]): Promise { + const totalContentSize = contentSizeDescriptors.reduce( + (acc, descriptor) => acc + (descriptor.props.contentSize ? +descriptor.props.contentSize : 0), + 0, + ) + + return totalContentSize > this.freeUserContentLimitInBytes + } +} diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimitDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimitDTO.ts new file mode 100644 index 000000000..41220e9c9 --- /dev/null +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/CheckForContentLimit/CheckForContentLimitDTO.ts @@ -0,0 +1,6 @@ +import { ItemHash } from '../../../Item/ItemHash' + +export interface CheckForContentLimitDTO { + userUuid: string + itemsBeingModified: ItemHash[] +} diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts index 5a74dc780..33c42398a 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.spec.ts @@ -13,6 +13,7 @@ import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryIn import { ItemsChangedOnServerEvent } from '@standardnotes/domain-events' import { SendEventToClients } from '../SendEventToClients/SendEventToClients' import { SharedVaultAssociation } from '../../../SharedVault/SharedVaultAssociation' +import { CheckForContentLimit } from '../CheckForContentLimit/CheckForContentLimit' describe('SaveItems', () => { let itemSaveValidator: ItemSaveValidatorInterface @@ -26,6 +27,7 @@ describe('SaveItems', () => { let sendEventToClient: SendEventToClient let sendEventToClients: SendEventToClients let domainEventFactory: DomainEventFactoryInterface + let checkForContentLimit: CheckForContentLimit const createUseCase = () => new SaveItems( @@ -37,10 +39,14 @@ describe('SaveItems', () => { sendEventToClient, sendEventToClients, domainEventFactory, + checkForContentLimit, logger, ) beforeEach(() => { + checkForContentLimit = {} as jest.Mocked + checkForContentLimit.execute = jest.fn().mockResolvedValue(Result.ok()) + sendEventToClient = {} as jest.Mocked sendEventToClient.execute = jest.fn().mockReturnValue(Result.ok()) @@ -84,6 +90,7 @@ describe('SaveItems', () => { logger = {} as jest.Mocked logger.debug = jest.fn() logger.error = jest.fn() + logger.warn = jest.fn() itemHash1 = ItemHash.create({ uuid: '00000000-0000-0000-0000-000000000000', @@ -114,6 +121,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -139,6 +147,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -164,6 +173,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -186,6 +196,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -209,6 +220,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -228,6 +240,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -247,6 +260,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -293,6 +307,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -321,6 +336,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -346,6 +362,7 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() @@ -392,9 +409,64 @@ describe('SaveItems', () => { sessionUuid: 'session-uuid', snjsVersion: '2.200.0', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeFalsy() expect(result.getValue().syncToken).toEqual('MjowLjAwMDE2') }) + + it('should succeed if a free user has no content limit', async () => { + checkForContentLimit.execute = jest.fn().mockResolvedValue(Result.fail('exceeded')) + + const useCase = createUseCase() + const result = await useCase.execute({ + itemHashes: [itemHash1], + userUuid: '00000000-0000-0000-0000-000000000000', + apiVersion: '1', + readOnlyAccess: false, + sessionUuid: 'session-uuid', + snjsVersion: '2.200.0', + isFreeUser: true, + hasContentLimit: false, + }) + + expect(result.isFailed()).toBeFalsy() + }) + + it('should return a failure result if a free user has exceeded their content limit', async () => { + checkForContentLimit.execute = jest.fn().mockResolvedValue(Result.fail('exceeded')) + + const useCase = createUseCase() + const result = await useCase.execute({ + itemHashes: [itemHash1], + userUuid: '00000000-0000-0000-0000-000000000000', + apiVersion: '1', + readOnlyAccess: false, + sessionUuid: 'session-uuid', + snjsVersion: '2.200.0', + isFreeUser: true, + hasContentLimit: true, + }) + + expect(result.isFailed()).toBeTruthy() + }) + + it('should succeed if a free user has not exceeded their content limit', async () => { + checkForContentLimit.execute = jest.fn().mockResolvedValue(Result.ok()) + + const useCase = createUseCase() + const result = await useCase.execute({ + itemHashes: [itemHash1], + userUuid: '00000000-0000-0000-0000-000000000000', + apiVersion: '1', + readOnlyAccess: false, + sessionUuid: 'session-uuid', + snjsVersion: '2.200.0', + isFreeUser: true, + hasContentLimit: false, + }) + + expect(result.isFailed()).toBeFalsy() + }) }) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts index ec81d1059..9acd7fb18 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItems.ts @@ -14,6 +14,7 @@ import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface' import { SendEventToClient } from '../SendEventToClient/SendEventToClient' import { DomainEventFactoryInterface } from '../../../Event/DomainEventFactoryInterface' import { SendEventToClients } from '../SendEventToClients/SendEventToClients' +import { CheckForContentLimit } from '../CheckForContentLimit/CheckForContentLimit' export class SaveItems implements UseCaseInterface { private readonly SYNC_TOKEN_VERSION = 2 @@ -27,6 +28,7 @@ export class SaveItems implements UseCaseInterface { private sendEventToClient: SendEventToClient, private sendEventToClients: SendEventToClients, private domainEventFactory: DomainEventFactoryInterface, + private checkForContentLimit: CheckForContentLimit, private logger: Logger, ) {} @@ -34,6 +36,20 @@ export class SaveItems implements UseCaseInterface { const savedItems: Array = [] const conflicts: Array = [] + if (dto.hasContentLimit) { + const checkForContentLimitResult = await this.checkForContentLimit.execute({ + userUuid: dto.userUuid, + itemsBeingModified: dto.itemHashes, + }) + if (checkForContentLimitResult.isFailed()) { + this.logger.warn(`Checking for content limit failed. Error: ${checkForContentLimitResult.getError()}`, { + userId: dto.userUuid, + }) + + return Result.fail(checkForContentLimitResult.getError()) + } + } + const lastUpdatedTimestamp = this.timer.getTimestampInMicroseconds() for (const itemHash of dto.itemHashes) { diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts index 205e11d60..ea088fb1b 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SaveItems/SaveItemsDTO.ts @@ -8,4 +8,5 @@ export interface SaveItemsDTO { sessionUuid: string | null snjsVersion: string isFreeUser: boolean + hasContentLimit: boolean } diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts index 254ad5f7d..a419084b3 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.spec.ts @@ -157,6 +157,7 @@ describe('SyncItems', () => { sessionUuid: null, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.getValue()).toEqual({ conflicts: [], @@ -185,6 +186,7 @@ describe('SyncItems', () => { isFreeUser: false, readOnlyAccess: false, sessionUuid: null, + hasContentLimit: false, }) }) @@ -208,6 +210,7 @@ describe('SyncItems', () => { sessionUuid: null, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) } catch (error) { caughtError = error @@ -228,6 +231,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.getValue()).toEqual({ conflicts: [], @@ -255,6 +259,7 @@ describe('SyncItems', () => { snjsVersion: '1.2.3', isFreeUser: false, sharedVaultUuids: ['00000000-0000-0000-0000-000000000000'], + hasContentLimit: false, }) expect(result.getValue()).toEqual({ conflicts: [], @@ -307,6 +312,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.getValue()).toEqual({ @@ -347,6 +353,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeTruthy() @@ -368,6 +375,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeTruthy() @@ -389,6 +397,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeTruthy() @@ -410,6 +419,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeTruthy() @@ -431,6 +441,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeTruthy() @@ -452,6 +463,7 @@ describe('SyncItems', () => { apiVersion: ApiVersion.v20200115, snjsVersion: '1.2.3', isFreeUser: false, + hasContentLimit: false, }) expect(result.isFailed()).toBeTruthy() diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts index 320d2dfb4..c0082a752 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItems.ts @@ -48,6 +48,7 @@ export class SyncItems implements UseCaseInterface { sessionUuid: dto.sessionUuid, snjsVersion: dto.snjsVersion, isFreeUser: dto.isFreeUser, + hasContentLimit: dto.hasContentLimit, }) if (saveItemsResultOrError.isFailed()) { return Result.fail(saveItemsResultOrError.getError()) diff --git a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts index d81da6c1c..c5a7d42d1 100644 --- a/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts +++ b/packages/syncing-server/src/Domain/UseCase/Syncing/SyncItems/SyncItemsDTO.ts @@ -14,4 +14,5 @@ export type SyncItemsDTO = { readOnlyAccess: boolean sessionUuid: string | null isFreeUser: boolean + hasContentLimit: boolean } diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts index f83b918d7..d2ae68f44 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/Base/BaseItemsController.ts @@ -132,6 +132,7 @@ export class BaseItemsController extends BaseHttpController { sessionUuid: locals.session ? locals.session.uuid : null, sharedVaultUuids, isFreeUser: locals.isFreeUser, + hasContentLimit: !!locals.hasContentLimit, }) if (syncResult.isFailed()) { return this.json({ error: { message: syncResult.getError() } }, HttpStatusCode.BadRequest) diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts index 78c362b23..f09ebaa2b 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/Middleware/InversifyExpressAuthMiddleware.ts @@ -33,6 +33,7 @@ export class InversifyExpressAuthMiddleware extends BaseMiddleware { session: decodedToken.session, readOnlyAccess: decodedToken.session?.readonly_access ?? false, sharedVaultOwnerContext: decodedToken.shared_vault_owner_context, + hasContentLimit: decodedToken.hasContentLimit, } as ResponseLocals) return next() diff --git a/packages/syncing-server/src/Infra/InversifyExpressUtils/ResponseLocals.ts b/packages/syncing-server/src/Infra/InversifyExpressUtils/ResponseLocals.ts index 32fda11d8..8dcb2f439 100644 --- a/packages/syncing-server/src/Infra/InversifyExpressUtils/ResponseLocals.ts +++ b/packages/syncing-server/src/Infra/InversifyExpressUtils/ResponseLocals.ts @@ -21,4 +21,5 @@ export interface ResponseLocals { sharedVaultOwnerContext?: { upload_bytes_limit: number } + hasContentLimit?: boolean } diff --git a/packages/syncing-server/src/Infra/gRPC/SyncingServer.ts b/packages/syncing-server/src/Infra/gRPC/SyncingServer.ts index fe8471b82..97919a33f 100644 --- a/packages/syncing-server/src/Infra/gRPC/SyncingServer.ts +++ b/packages/syncing-server/src/Infra/gRPC/SyncingServer.ts @@ -35,6 +35,7 @@ export class SyncingServer implements ISyncingServer { try { const userUuid = call.metadata.get('x-user-uuid').pop() as string const isFreeUser = call.metadata.get('x-is-free-user').pop() === 'true' + const hasContentLimit = call.metadata.get('x-has-content-limit').pop() === 'true' const checkForItemOperationsAbuseResult = await this.checkForTrafficAbuse.execute({ metricToCheck: Metric.NAMES.ItemOperation, @@ -168,6 +169,7 @@ export class SyncingServer implements ISyncingServer { sessionUuid: call.metadata.get('x-session-uuid').pop() as string, sharedVaultUuids, isFreeUser, + hasContentLimit, }) if (syncResult.isFailed()) { const metadata = new grpc.Metadata() diff --git a/packages/time/package.json b/packages/time/package.json index 80197eaf4..732abcdb1 100644 --- a/packages/time/package.json +++ b/packages/time/package.json @@ -26,7 +26,7 @@ "clean": "rm -fr dist", "build": "tsc --build", "lint": "eslint . --ext .ts", - "test": "jest --coverage --no-cache" + "test": "jest --coverage --no-cache --maxWorkers=2" }, "dependencies": { "dayjs": "^1.11.6", diff --git a/packages/websockets/Dockerfile b/packages/websockets/Dockerfile index 64b221126..ca5345330 100644 --- a/packages/websockets/Dockerfile +++ b/packages/websockets/Dockerfile @@ -10,6 +10,12 @@ RUN corepack enable COPY ./ /workspace +WORKDIR /workspace + +RUN yarn install --immutable + +RUN yarn build + WORKDIR /workspace/packages/websockets ENTRYPOINT [ "/workspace/packages/websockets/docker/entrypoint.sh" ] diff --git a/packages/websockets/package.json b/packages/websockets/package.json index 9652531d8..fc6a170b6 100644 --- a/packages/websockets/package.json +++ b/packages/websockets/package.json @@ -20,8 +20,7 @@ "setup:env": "cp .env.sample .env", "build": "tsc --build", "lint": "eslint . --ext .ts", - "pretest": "yarn lint && yarn build", - "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=50%", + "test": "jest --coverage --no-cache --config=./jest.config.js --maxWorkers=2", "start": "yarn node dist/bin/server.js", "worker": "yarn node dist/bin/worker.js", "typeorm": "typeorm-ts-node-commonjs" @@ -42,7 +41,7 @@ "inversify": "^6.0.1", "inversify-express-utils": "^6.4.3", "ioredis": "^5.2.4", - "mysql2": "^3.0.1", + "mysql2": "^3.9.7", "reflect-metadata": "^0.2.1", "typeorm": "^0.3.17", "winston": "^3.8.1" diff --git a/yarn.lock b/yarn.lock index 5eacd8718..69d4fd6f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5731,7 +5731,7 @@ __metadata: ioredis: "npm:^5.2.4" jest: "npm:^29.5.0" mixpanel: "npm:^0.17.0" - mysql2: "npm:^3.0.1" + mysql2: "npm:^3.9.7" prettier: "npm:^3.0.3" reflect-metadata: "npm:^0.2.1" ts-jest: "npm:^29.1.0" @@ -5753,6 +5753,7 @@ __metadata: "@standardnotes/grpc": "workspace:^" "@standardnotes/security": "workspace:*" "@standardnotes/time": "workspace:*" + "@types/cookie-parser": "npm:^1" "@types/cors": "npm:^2.8.9" "@types/express": "npm:^4.17.14" "@types/ioredis": "npm:^5.0.0" @@ -5764,6 +5765,7 @@ __metadata: "@typescript-eslint/parser": "npm:^6.5.0" agentkeepalive: "npm:^4.5.0" axios: "npm:^1.6.1" + cookie-parser: "npm:^1.4.6" cors: "npm:2.8.5" dotenv: "npm:^16.0.1" eslint: "npm:^8.39.0" @@ -5827,6 +5829,7 @@ __metadata: "@standardnotes/sncrypto-node": "workspace:*" "@standardnotes/time": "workspace:*" "@types/bcryptjs": "npm:^2.4.2" + "@types/cookie-parser": "npm:^1" "@types/cors": "npm:^2.8.9" "@types/express": "npm:^4.17.14" "@types/ioredis": "npm:^5.0.0" @@ -5838,7 +5841,10 @@ __metadata: "@types/uuid": "npm:^9.0.3" "@typescript-eslint/eslint-plugin": "npm:^6.5.0" "@typescript-eslint/parser": "npm:^6.5.0" + agentkeepalive: "npm:^4.5.0" + axios: "npm:^1.6.7" bcryptjs: "npm:2.4.3" + cookie-parser: "npm:^1.4.6" cors: "npm:2.8.5" dayjs: "npm:^1.11.6" dotenv: "npm:^16.0.1" @@ -5849,7 +5855,7 @@ __metadata: inversify-express-utils: "npm:^6.4.3" ioredis: "npm:^5.2.4" jest: "npm:^29.5.0" - mysql2: "npm:^3.0.1" + mysql2: "npm:^3.9.7" otplib: "npm:12.0.1" prettier: "npm:^3.0.3" prettyjson: "npm:^1.2.5" @@ -6044,10 +6050,12 @@ __metadata: "@standardnotes/files-server": "workspace:^" "@standardnotes/revisions-server": "workspace:^" "@standardnotes/syncing-server": "workspace:^" + "@types/cookie-parser": "npm:^1" "@types/cors": "npm:^2.8.9" "@types/express": "npm:^4.17.14" "@typescript-eslint/eslint-plugin": "npm:^6.5.0" "@typescript-eslint/parser": "npm:^6.5.0" + cookie-parser: "npm:^1.4.6" cors: "npm:2.8.5" dotenv: "npm:^16.0.1" eslint: "npm:^8.39.0" @@ -6139,7 +6147,7 @@ __metadata: inversify-express-utils: "npm:^6.4.3" ioredis: "npm:^5.3.2" jest: "npm:^29.5.0" - mysql2: "npm:^3.0.1" + mysql2: "npm:^3.9.7" prettier: "npm:^3.0.3" reflect-metadata: "npm:^0.2.1" sqlite3: "npm:^5.1.6" @@ -6173,7 +6181,7 @@ __metadata: inversify: "npm:^6.0.1" ioredis: "npm:^5.2.4" jest: "npm:^29.5.0" - mysql2: "npm:^3.0.1" + mysql2: "npm:^3.9.7" prettier: "npm:^3.0.3" reflect-metadata: "npm:^0.2.1" ts-jest: "npm:^29.1.0" @@ -6318,7 +6326,7 @@ __metadata: ioredis: "npm:^5.3.2" jest: "npm:^29.5.0" jsonwebtoken: "npm:^9.0.0" - mysql2: "npm:^3.0.1" + mysql2: "npm:^3.9.7" prettier: "npm:^3.0.3" prettyjson: "npm:^1.2.5" reflect-metadata: "npm:^0.2.1" @@ -6393,7 +6401,7 @@ __metadata: inversify-express-utils: "npm:^6.4.3" ioredis: "npm:^5.2.4" jest: "npm:^29.5.0" - mysql2: "npm:^3.0.1" + mysql2: "npm:^3.9.7" prettier: "npm:^3.0.3" reflect-metadata: "npm:^0.2.1" ts-jest: "npm:^29.1.0" @@ -6549,6 +6557,15 @@ __metadata: languageName: node linkType: hard +"@types/cookie-parser@npm:^1": + version: 1.4.6 + resolution: "@types/cookie-parser@npm:1.4.6" + dependencies: + "@types/express": "npm:*" + checksum: b1bbb17bc4189c0e953d4996b3b58bfa20161c27db21f98353e237032e7559aec733735d8902c283300e0a4cded20e62b1a5086af608608ef30a45387e080360 + languageName: node + linkType: hard + "@types/cors@npm:^2.8.9": version: 2.8.13 resolution: "@types/cors@npm:2.8.13" @@ -7552,6 +7569,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.6.7": + version: 1.6.7 + resolution: "axios@npm:1.6.7" + dependencies: + follow-redirects: "npm:^1.15.4" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: a1932b089ece759cd261f175d9ebf4d41c8994cf0c0767cda86055c7a19bcfdade8ae3464bf4cec4c8b142f4a657dc664fb77a41855e8376cf38b86d7a86518f + languageName: node + linkType: hard + "babel-jest@npm:^29.5.0": version: 29.5.0 resolution: "babel-jest@npm:29.5.0" @@ -8521,6 +8549,16 @@ __metadata: languageName: node linkType: hard +"cookie-parser@npm:^1.4.6": + version: 1.4.6 + resolution: "cookie-parser@npm:1.4.6" + dependencies: + cookie: "npm:0.4.1" + cookie-signature: "npm:1.0.6" + checksum: 1e5a63aa82e8eb4e02d2977c6902983dee87b02e87ec5ec43ac3cb1e72da354003716570cd5190c0ad9e8a454c9d3237f4ad6e2f16d0902205a96a1c72b77ba5 + languageName: node + linkType: hard + "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" @@ -8528,6 +8566,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:0.4.1": + version: 0.4.1 + resolution: "cookie@npm:0.4.1" + checksum: 0f2defd60ac93645ee31e82d11da695080435eb4fe5bed9b14d2fc4e0621a66f4c5c60f3eb05761df08a9d6279366e8646edfd1654f359d0b5afc25304fc4ddc + languageName: node + linkType: hard + "cookie@npm:0.5.0": version: 0.5.0 resolution: "cookie@npm:0.5.0" @@ -9552,6 +9597,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.15.4": + version: 1.15.5 + resolution: "follow-redirects@npm:1.15.5" + peerDependenciesMeta: + debug: + optional: true + checksum: d467f13c1c6aa734599b8b369cd7a625b20081af358f6204ff515f6f4116eb440de9c4e0c49f10798eeb0df26c95dd05d5e0d9ddc5786ab1a8a8abefe92929b4 + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.1.1 resolution: "foreground-child@npm:3.1.1" @@ -12165,9 +12220,9 @@ __metadata: languageName: node linkType: hard -"mysql2@npm:^3.0.1": - version: 3.3.3 - resolution: "mysql2@npm:3.3.3" +"mysql2@npm:^3.9.7": + version: 3.9.7 + resolution: "mysql2@npm:3.9.7" dependencies: denque: "npm:^2.1.0" generate-function: "npm:^2.3.1" @@ -12177,7 +12232,7 @@ __metadata: named-placeholders: "npm:^1.1.3" seq-queue: "npm:^0.0.5" sqlstring: "npm:^2.3.2" - checksum: 4bf7ace8f13a54e3117d9259222c629ec32337562cc5c5baf0404410d2c65f4d86038101ed07aa16857f25246ff29d5f5ec9cbea22eaa4703250d834d7d9c8ad + checksum: 7f43b17cc0acdec30791c9b29a97c75f7e4512bbf41c2baa383ce76b50d0a92300083a8dba3cc019423ee3b7710ed7c756baf805449f0c9650e08e5d48454b07 languageName: node linkType: hard