From 69a2466e68ecbdf107ce7fdae9dee37c8a56b72d Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Fri, 1 Mar 2024 16:08:18 +0530 Subject: [PATCH] fix: totp --- src/main/java/io/supertokens/totp/Totp.java | 94 +++++++++---------- .../api/totp/CreateOrUpdateTotpDeviceAPI.java | 38 ++++---- .../webserver/api/totp/GetTotpDevicesAPI.java | 21 +++-- .../api/totp/RemoveTotpDeviceAPI.java | 21 +++-- .../webserver/api/totp/VerifyTotpAPI.java | 18 ++-- .../api/totp/VerifyTotpDeviceAPI.java | 18 ++-- .../usermetadata/RemoveUserMetadataAPI.java | 2 - 7 files changed, 111 insertions(+), 101 deletions(-) diff --git a/src/main/java/io/supertokens/totp/Totp.java b/src/main/java/io/supertokens/totp/Totp.java index 307f49471..58d252410 100644 --- a/src/main/java/io/supertokens/totp/Totp.java +++ b/src/main/java/io/supertokens/totp/Totp.java @@ -6,11 +6,12 @@ import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlag; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.pluginInterface.Storage; +import io.supertokens.pluginInterface.StorageUtils; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.TOTPDevice; import io.supertokens.pluginInterface.totp.TOTPUsedCode; @@ -88,34 +89,34 @@ public static TOTPDevice registerDevice(Main main, String userId, throws StorageQueryException, DeviceAlreadyExistsException, NoSuchAlgorithmException, FeatureNotEnabledException { try { - return registerDevice(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), main, userId, - deviceName, skew, period); + return registerDevice(new AppIdentifier(null, null), StorageLayer.getStorage(main), + main, userId, deviceName, skew, period); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static TOTPDevice registerDevice(AppIdentifierWithStorage appIdentifierWithStorage, Main main, String userId, + public static TOTPDevice registerDevice(AppIdentifier appIdentifier, Storage storage, Main main, String userId, String deviceName, int skew, int period) throws StorageQueryException, DeviceAlreadyExistsException, NoSuchAlgorithmException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (!isTotpEnabled(appIdentifierWithStorage, main)) { + if (!isTotpEnabled(appIdentifier, main)) { throw new FeatureNotEnabledException( "TOTP feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + "feature."); } - TOTPSQLStorage totpStorage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); String secret = generateSecret(); TOTPDevice device = new TOTPDevice(userId, deviceName, secret, period, skew, false); - totpStorage.createDevice(appIdentifierWithStorage, device); + totpStorage.createDevice(appIdentifier, device); return device; } - private static void checkAndStoreCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + private static void checkAndStoreCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, TOTPDevice[] devices, String code) throws InvalidTotpException, TotpNotEnabledException, @@ -154,23 +155,22 @@ private static void checkAndStoreCode(TenantIdentifierWithStorage tenantIdentifi // That's why we need to fetch all the codes (expired + non-expired). // TOTPUsedCode[] usedCodes = - TOTPSQLStorage totpSQLStorage = tenantIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpSQLStorage = StorageUtils.getTOTPStorage(storage); while (true) { try { totpSQLStorage.startTransaction(con -> { try { TOTPUsedCode[] usedCodes = totpSQLStorage.getAllUsedCodesDescOrder_Transaction(con, - tenantIdentifierWithStorage, - userId); + tenantIdentifier, userId); // N represents # of invalid attempts that will trigger rate limiting: - int N = Config.getConfig(tenantIdentifierWithStorage, main).getTotpMaxAttempts(); // (Default 5) + int N = Config.getConfig(tenantIdentifier, main).getTotpMaxAttempts(); // (Default 5) // Count # of contiguous invalids in latest N attempts (stop at first valid): long invalidOutOfN = Arrays.stream(usedCodes).limit(N).takeWhile(usedCode -> !usedCode.isValid) .count(); int rateLimitResetTimeInMs = - Config.getConfig(tenantIdentifierWithStorage, main).getTotpRateLimitCooldownTimeSec() * + Config.getConfig(tenantIdentifier, main).getTotpRateLimitCooldownTimeSec() * 1000; // (Default // 15 mins) @@ -239,7 +239,7 @@ private static void checkAndStoreCode(TenantIdentifierWithStorage tenantIdentifi code, isValid, now + 1000 * expireInSec, now); try { - totpSQLStorage.insertUsedCode_Transaction(con, tenantIdentifierWithStorage, newCode); + totpSQLStorage.insertUsedCode_Transaction(con, tenantIdentifier, newCode); totpSQLStorage.commitTransaction(con); } catch (UsedCodeAlreadyExistsException | TotpNotEnabledException e) { throw new StorageTransactionLogicException(e); @@ -287,14 +287,14 @@ public static boolean verifyDevice(Main main, throws TotpNotEnabledException, UnknownDeviceException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException { try { - return verifyDevice(new TenantIdentifierWithStorage(null, null, null, StorageLayer.getStorage(main)), main, - userId, deviceName, code); + return verifyDevice(new TenantIdentifier(null, null, null), + StorageLayer.getStorage(main), main, userId, deviceName, code); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, + public static boolean verifyDevice(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, String deviceName, String code) throws TotpNotEnabledException, UnknownDeviceException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException, @@ -302,7 +302,7 @@ public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierW // Here boolean return value tells whether the device has been // newly verified (true) OR it was already verified (false) - TOTPSQLStorage totpStorage = tenantIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); TOTPDevice matchingDevice = null; // Here one race condition is that the same device @@ -310,7 +310,7 @@ public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierW // both the API calls will return true, but that's okay. // Check if the user has any devices: - TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifierWithStorage.toAppIdentifier(), userId); + TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifier.toAppIdentifier(), userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } @@ -337,10 +337,10 @@ public static boolean verifyDevice(TenantIdentifierWithStorage tenantIdentifierW // verified in the devices table (because it was deleted/renamed). So the user // gets a UnknownDevceException. // This behaviour is okay so we can ignore it. - checkAndStoreCode(tenantIdentifierWithStorage, main, userId, new TOTPDevice[]{matchingDevice}, + checkAndStoreCode(tenantIdentifier, storage, main, userId, new TOTPDevice[]{matchingDevice}, code); // Will reach here only if the code is valid: - totpStorage.markDeviceAsVerified(tenantIdentifierWithStorage.toAppIdentifier(), userId, deviceName); + totpStorage.markDeviceAsVerified(tenantIdentifier.toAppIdentifier(), userId, deviceName); return true; // Newly verified } @@ -350,29 +350,29 @@ public static void verifyCode(Main main, String userId, throws TotpNotEnabledException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException, FeatureNotEnabledException { try { - verifyCode(new TenantIdentifierWithStorage(null, null, null, StorageLayer.getStorage(main)), main, - userId, code, allowUnverifiedDevices); + verifyCode(new TenantIdentifier(null, null, null), + StorageLayer.getStorage(main), main, userId, code, allowUnverifiedDevices); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static void verifyCode(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String userId, + public static void verifyCode(TenantIdentifier tenantIdentifier, Storage storage, Main main, String userId, String code, boolean allowUnverifiedDevices) throws TotpNotEnabledException, InvalidTotpException, LimitReachedException, StorageQueryException, StorageTransactionLogicException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (!isTotpEnabled(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), main)) { + if (!isTotpEnabled(tenantIdentifier.toAppIdentifier(), main)) { throw new FeatureNotEnabledException( "TOTP feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + "feature."); } - TOTPSQLStorage totpStorage = tenantIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); // Check if the user has any devices: - TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifierWithStorage.toAppIdentifier(), userId); + TOTPDevice[] devices = totpStorage.getDevices(tenantIdentifier.toAppIdentifier(), userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } @@ -386,7 +386,7 @@ public static void verifyCode(TenantIdentifierWithStorage tenantIdentifierWithSt // another API call. We will still check the code against the updated set of // devices and store it in the used codes table. This behaviour is okay so we // can ignore it. - checkAndStoreCode(tenantIdentifierWithStorage, main, userId, devices, code); + checkAndStoreCode(tenantIdentifier, storage, main, userId, devices, code); } @TestOnly @@ -395,7 +395,7 @@ public static void removeDevice(Main main, String userId, throws StorageQueryException, UnknownDeviceException, TotpNotEnabledException, StorageTransactionLogicException { try { - removeDevice(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), + removeDevice(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId, deviceName); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); @@ -405,35 +405,35 @@ public static void removeDevice(Main main, String userId, /** * Delete device and also delete the user if deleting the last device */ - public static void removeDevice(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void removeDevice(AppIdentifier appIdentifier, Storage storage, String userId, String deviceName) throws StorageQueryException, UnknownDeviceException, TotpNotEnabledException, StorageTransactionLogicException, TenantOrAppNotFoundException { - TOTPSQLStorage storage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); try { - storage.startTransaction(con -> { - int deletedCount = storage.deleteDevice_Transaction(con, appIdentifierWithStorage, userId, deviceName); + totpStorage.startTransaction(con -> { + int deletedCount = totpStorage.deleteDevice_Transaction(con, appIdentifier, userId, deviceName); if (deletedCount == 0) { throw new StorageTransactionLogicException(new UnknownDeviceException()); } // Some device(s) were deleted. Check if user has any other device left: // This also takes a lock on the user devices. - TOTPDevice[] devices = storage.getDevices_Transaction(con, appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices_Transaction(con, appIdentifier, userId); if (devices.length == 0) { // no device left. delete user - storage.removeUser_Transaction(con, appIdentifierWithStorage, userId); + totpStorage.removeUser_Transaction(con, appIdentifier, userId); } - storage.commitTransaction(con); + totpStorage.commitTransaction(con); return null; }); return; } catch (StorageTransactionLogicException e) { if (e.actualException instanceof UnknownDeviceException) { // Check if any device exists for the user: - TOTPDevice[] devices = storage.getDevices(appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices(appIdentifier, userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } @@ -451,23 +451,23 @@ public static void updateDeviceName(Main main, String userId, throws StorageQueryException, DeviceAlreadyExistsException, UnknownDeviceException, TotpNotEnabledException { try { - updateDeviceName(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), + updateDeviceName(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId, oldDeviceName, newDeviceName); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static void updateDeviceName(AppIdentifierWithStorage appIdentifierWithStorage, String userId, + public static void updateDeviceName(AppIdentifier appIdentifier, Storage storage, String userId, String oldDeviceName, String newDeviceName) throws StorageQueryException, DeviceAlreadyExistsException, UnknownDeviceException, TotpNotEnabledException, TenantOrAppNotFoundException { - TOTPSQLStorage totpStorage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); try { - totpStorage.updateDeviceName(appIdentifierWithStorage, userId, oldDeviceName, newDeviceName); + totpStorage.updateDeviceName(appIdentifier, userId, oldDeviceName, newDeviceName); } catch (UnknownDeviceException e) { // Check if any device exists for the user: - TOTPDevice[] devices = totpStorage.getDevices(appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices(appIdentifier, userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } else { @@ -480,18 +480,18 @@ public static void updateDeviceName(AppIdentifierWithStorage appIdentifierWithSt public static TOTPDevice[] getDevices(Main main, String userId) throws StorageQueryException, TotpNotEnabledException { try { - return getDevices(new AppIdentifierWithStorage(null, null, StorageLayer.getStorage(main)), + return getDevices(new AppIdentifier(null, null), StorageLayer.getStorage(main), userId); } catch (TenantOrAppNotFoundException e) { throw new IllegalStateException(e); } } - public static TOTPDevice[] getDevices(AppIdentifierWithStorage appIdentifierWithStorage, String userId) + public static TOTPDevice[] getDevices(AppIdentifier appIdentifier, Storage storage, String userId) throws StorageQueryException, TotpNotEnabledException, TenantOrAppNotFoundException { - TOTPSQLStorage totpStorage = appIdentifierWithStorage.getTOTPStorage(); + TOTPSQLStorage totpStorage = StorageUtils.getTOTPStorage(storage); - TOTPDevice[] devices = totpStorage.getDevices(appIdentifierWithStorage, userId); + TOTPDevice[] devices = totpStorage.getDevices(appIdentifier, userId); if (devices.length == 0) { throw new TotpNotEnabledException(); } diff --git a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java index 08dfdca21..31c0c8ee9 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/CreateOrUpdateTotpDeviceAPI.java @@ -1,14 +1,15 @@ package io.supertokens.webserver.api.totp; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.TOTPDevice; import io.supertokens.pluginInterface.totp.exception.DeviceAlreadyExistsException; @@ -66,26 +67,26 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( - req, userId, UserIdType.ANY); + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( + req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the public tenant storage - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - TOTPDevice device = Totp.registerDevice(appIdentifierWithStorage, main, userId, deviceName, skew, period); + TOTPDevice device = Totp.registerDevice(appIdentifier, storage, main, userId, deviceName, skew, period); result.addProperty("status", "OK"); result.addProperty("secret", device.secretKey); @@ -121,26 +122,27 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the public storage - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - Totp.updateDeviceName(appIdentifierWithStorage, userId, existingDeviceName, newDeviceName); + Totp.updateDeviceName(appIdentifier, storage, userId, existingDeviceName, newDeviceName); result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java index 7cc254c7a..400674c70 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/GetTotpDevicesAPI.java @@ -2,13 +2,14 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.TOTPDevice; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; @@ -46,26 +47,26 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - TOTPDevice[] devices = Totp.getDevices(appIdentifierWithStorage, - userId); + TOTPDevice[] devices = Totp.getDevices(appIdentifier, storage, userId); JsonArray devicesArray = new JsonArray(); for (TOTPDevice d : devices) { diff --git a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java index b4eac5b5a..fd56fdcd4 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/RemoveTotpDeviceAPI.java @@ -1,14 +1,15 @@ package io.supertokens.webserver.api.totp; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; +import io.supertokens.pluginInterface.multitenancy.AppIdentifier; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; import io.supertokens.pluginInterface.totp.exception.UnknownDeviceException; @@ -52,26 +53,26 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - AppIdentifierWithStorage appIdentifierWithStorage; + AppIdentifier appIdentifier = getAppIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. // Try to find the appIdentifier with right storage based on the userId - AppIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getStorageAndUserIdMappingForAppSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForAppSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - appIdentifierWithStorage = mappingAndStorage.appIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - appIdentifierWithStorage = enforcePublicTenantAndGetPublicTenantStorage(req); + storage = enforcePublicTenantAndGetPublicTenantStorage(req); } - Totp.removeDevice(appIdentifierWithStorage, userId, deviceName); + Totp.removeDevice(appIdentifier, storage, userId, deviceName); result.addProperty("status", "OK"); result.addProperty("didDeviceExist", true); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java index 6e3916672..0653f03d3 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpAPI.java @@ -5,12 +5,15 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; @@ -56,24 +59,25 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForTenantSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } - Totp.verifyCode(tenantIdentifierWithStorage, main, userId, totp, allowUnverifiedDevices); + Totp.verifyCode(tenantIdentifier, storage, main, userId, totp, allowUnverifiedDevices); result.addProperty("status", "OK"); super.sendJsonResponse(200, result, resp); diff --git a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java index b15e86d32..b4bf1eb8b 100644 --- a/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java +++ b/src/main/java/io/supertokens/webserver/api/totp/VerifyTotpDeviceAPI.java @@ -5,11 +5,14 @@ import com.google.gson.JsonObject; import io.supertokens.Main; +import io.supertokens.StorageAndUserIdMapping; import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; import io.supertokens.pluginInterface.RECIPE_ID; +import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; +import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException; @@ -58,23 +61,24 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I JsonObject result = new JsonObject(); try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; + TenantIdentifier tenantIdentifier = getTenantIdentifier(req); + Storage storage; try { // This step is required only because user_last_active table stores supertokens internal user id. // While sending the usage stats we do a join, so totp tables also must use internal user id. - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = getStorageAndUserIdMappingForTenantSpecificApi( + StorageAndUserIdMapping storageAndUserIdMapping = getStorageAndUserIdMappingForTenantSpecificApi( req, userId, UserIdType.ANY); - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; + if (storageAndUserIdMapping.userIdMapping != null) { + userId = storageAndUserIdMapping.userIdMapping.superTokensUserId; } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; + storage = storageAndUserIdMapping.storage; } catch (UnknownUserIdException e) { // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantStorage(req); + storage = getTenantStorage(req); } - boolean isNewlyVerified = Totp.verifyDevice(tenantIdentifierWithStorage, main, userId, deviceName, totp); + boolean isNewlyVerified = Totp.verifyDevice(tenantIdentifier, storage, main, userId, deviceName, totp); result.addProperty("status", "OK"); result.addProperty("wasAlreadyVerified", !isNewlyVerified); diff --git a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java index 8e6a91a24..47a6e0ad0 100644 --- a/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java +++ b/src/main/java/io/supertokens/webserver/api/usermetadata/RemoveUserMetadataAPI.java @@ -17,14 +17,12 @@ package io.supertokens.webserver.api.usermetadata; import com.google.gson.JsonObject; -import io.supertokens.AppIdentifierWithStorageAndUserIdMapping; import io.supertokens.Main; import io.supertokens.StorageAndUserIdMapping; import io.supertokens.multitenancy.exception.BadPermissionException; import io.supertokens.pluginInterface.Storage; import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.exceptions.StorageQueryException;