From 971e21d7db45ff4261f3df281eb683e496b3c11e Mon Sep 17 00:00:00 2001 From: Sattvik Chakravarthy Date: Tue, 17 Oct 2023 13:58:41 +0530 Subject: [PATCH] fix: mfa cleanup (#837) * fix: mfa cleanup * fix: mfa cleanup * fix: test * fix: pr comments --- .../java/io/supertokens/ee/EEFeatureFlag.java | 5 +- .../io/supertokens/authRecipe/AuthRecipe.java | 4 - .../supertokens/featureflag/EE_FEATURES.java | 2 +- .../java/io/supertokens/inmemorydb/Start.java | 84 +------- .../inmemorydb/config/SQLiteConfig.java | 4 - .../queries/ActiveUsersQueries.java | 28 +-- .../inmemorydb/queries/GeneralQueries.java | 5 - .../inmemorydb/queries/MfaQueries.java | 124 ----------- src/main/java/io/supertokens/mfa/Mfa.java | 52 +---- src/main/java/io/supertokens/totp/Totp.java | 27 +-- .../useridmapping/UserIdMapping.java | 9 - .../io/supertokens/webserver/Webserver.java | 7 - .../webserver/api/mfa/DisableFactorAPI.java | 81 -------- .../webserver/api/mfa/EnableFactorAPI.java | 81 -------- .../webserver/api/mfa/ListFactorsAPI.java | 83 -------- .../io/supertokens/test/FeatureFlagTest.java | 125 +----------- .../supertokens/test/mfa/MfaLicenseTest.java | 152 -------------- .../supertokens/test/mfa/MfaRecipeTest.java | 109 ---------- .../supertokens/test/mfa/MfaStorageTest.java | 192 ------------------ .../io/supertokens/test/mfa/MfaTestBase.java | 148 -------------- .../test/mfa/api/DisableFactorAPITest.java | 93 --------- .../test/mfa/api/EnableFactorAPITest.java | 84 -------- .../test/mfa/api/ListFactorsAPITest.java | 89 -------- .../test/mfa/api/MfaUserIdMappingTest.java | 81 -------- .../test/multitenant/AppTenantUserTest.java | 6 +- .../test/multitenant/TestAppData.java | 5 +- .../api/TestTenantUserAssociation.java | 5 +- .../supertokens/test/totp/TOTPRecipeTest.java | 4 +- .../test/totp/TOTPStorageTest.java | 2 +- .../test/totp/TotpLicenseTest.java | 9 +- .../totp/api/CreateTotpDeviceAPITest.java | 4 +- .../test/totp/api/GetTotpDevicesAPITest.java | 2 +- .../test/totp/api/MultitenantAPITest.java | 2 +- .../totp/api/RemoveTotpDeviceAPITest.java | 2 +- .../test/totp/api/TotpUserIdMappingTest.java | 2 +- .../totp/api/UpdateTotpDeviceAPITest.java | 2 +- .../test/totp/api/VerifyTotpAPITest.java | 2 +- .../totp/api/VerifyTotpDeviceAPITest.java | 2 +- .../test/userIdMapping/UserIdMappingTest.java | 2 +- 39 files changed, 45 insertions(+), 1675 deletions(-) delete mode 100644 src/main/java/io/supertokens/inmemorydb/queries/MfaQueries.java delete mode 100644 src/main/java/io/supertokens/webserver/api/mfa/DisableFactorAPI.java delete mode 100644 src/main/java/io/supertokens/webserver/api/mfa/EnableFactorAPI.java delete mode 100644 src/main/java/io/supertokens/webserver/api/mfa/ListFactorsAPI.java delete mode 100644 src/test/java/io/supertokens/test/mfa/MfaLicenseTest.java delete mode 100644 src/test/java/io/supertokens/test/mfa/MfaRecipeTest.java delete mode 100644 src/test/java/io/supertokens/test/mfa/MfaStorageTest.java delete mode 100644 src/test/java/io/supertokens/test/mfa/MfaTestBase.java delete mode 100644 src/test/java/io/supertokens/test/mfa/api/DisableFactorAPITest.java delete mode 100644 src/test/java/io/supertokens/test/mfa/api/EnableFactorAPITest.java delete mode 100644 src/test/java/io/supertokens/test/mfa/api/ListFactorsAPITest.java delete mode 100644 src/test/java/io/supertokens/test/mfa/api/MfaUserIdMappingTest.java diff --git a/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java b/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java index 18f72ce7d..81c80b4ea 100644 --- a/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java +++ b/ee/src/main/java/io/supertokens/ee/EEFeatureFlag.java @@ -248,6 +248,7 @@ private JsonObject getMFAStats() throws StorageQueryException, TenantOrAppNotFou } mfaStats.add("maus", mfaMauArr); + mfaStats.add("totp", getTOTPStats()); int mfaTotalUsers = 0; for (Storage storage : storages) { @@ -387,10 +388,6 @@ public JsonObject getPaidFeatureStats() throws StorageQueryException, TenantOrAp usageStats.add(EE_FEATURES.DASHBOARD_LOGIN.toString(), getDashboardLoginStats()); } - if (feature == EE_FEATURES.TOTP) { - usageStats.add(EE_FEATURES.TOTP.toString(), getTOTPStats()); - } - if (feature == EE_FEATURES.MFA) { usageStats.add(EE_FEATURES.MFA.toString(), getMFAStats()); } diff --git a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java index 0c4f7b918..508bffaf6 100644 --- a/src/main/java/io/supertokens/authRecipe/AuthRecipe.java +++ b/src/main/java/io/supertokens/authRecipe/AuthRecipe.java @@ -934,8 +934,6 @@ private static void deleteNonAuthRecipeUser(TransactionConnection con, AppIdenti .deleteAllRolesForUser_Transaction(con, appIdentifierWithStorage, userId); appIdentifierWithStorage.getActiveUsersStorage() .deleteUserActive_Transaction(con, appIdentifierWithStorage, userId); - appIdentifierWithStorage.getMfaStorage() - .deleteMfaInfoForUser_Transaction(con, appIdentifierWithStorage, userId); } private static void deleteAuthRecipeUser(TransactionConnection con, @@ -976,8 +974,6 @@ public static boolean deleteNonAuthRecipeUser(TenantIdentifierWithStorage .removeUser(tenantIdentifierWithStorage, userId); finalDidExist = finalDidExist || didExist; - didExist = tenantIdentifierWithStorage.getMfaStorage() - .deleteMfaInfoForUser(tenantIdentifierWithStorage, userId); finalDidExist = finalDidExist || didExist; return finalDidExist; diff --git a/src/main/java/io/supertokens/featureflag/EE_FEATURES.java b/src/main/java/io/supertokens/featureflag/EE_FEATURES.java index de35653b6..e120fbf2f 100644 --- a/src/main/java/io/supertokens/featureflag/EE_FEATURES.java +++ b/src/main/java/io/supertokens/featureflag/EE_FEATURES.java @@ -18,7 +18,7 @@ public enum EE_FEATURES { ACCOUNT_LINKING("account_linking"), MULTI_TENANCY("multi_tenancy"), TEST("test"), - DASHBOARD_LOGIN("dashboard_login"), TOTP("totp"), MFA("mfa"); + DASHBOARD_LOGIN("dashboard_login"), MFA("mfa"); private final String name; diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index cf6e858ae..d344eb594 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -49,8 +49,6 @@ import io.supertokens.pluginInterface.jwt.JWTSigningKeyInfo; import io.supertokens.pluginInterface.jwt.exceptions.DuplicateKeyIdException; import io.supertokens.pluginInterface.jwt.sqlstorage.JWTRecipeSQLStorage; -import io.supertokens.pluginInterface.mfa.MfaStorage; -import io.supertokens.pluginInterface.mfa.sqlStorage.MfaSQLStorage; import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateClientTypeException; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateTenantException; @@ -104,7 +102,7 @@ public class Start implements SessionSQLStorage, EmailPasswordSQLStorage, EmailVerificationSQLStorage, ThirdPartySQLStorage, JWTRecipeSQLStorage, PasswordlessSQLStorage, UserMetadataSQLStorage, UserRolesSQLStorage, UserIdMappingStorage, UserIdMappingSQLStorage, MultitenancyStorage, MultitenancySQLStorage, TOTPSQLStorage, ActiveUsersStorage, - ActiveUsersSQLStorage, DashboardSQLStorage, AuthRecipeSQLStorage, MfaStorage, MfaSQLStorage { + ActiveUsersSQLStorage, DashboardSQLStorage, AuthRecipeSQLStorage { private static final Object appenderLock = new Object(); private static final String APP_ID_KEY_NAME = "app_id"; @@ -618,13 +616,6 @@ public boolean isUserIdBeingUsedInNonAuthRecipe(AppIdentifier appIdentifier, Str } } else if (className.equals(JWTRecipeStorage.class.getName())) { return false; - } else if (className.equals(MfaStorage.class.getName())) { - try { - MultitenancyQueries.getAllTenants(this); - return MfaQueries.listFactors(this, appIdentifier, userId).length > 0; - } catch (SQLException e) { - throw new StorageQueryException(e); - } } else { throw new IllegalStateException("ClassName: " + className + " is not part of NonAuthRecipeStorage"); } @@ -723,12 +714,6 @@ public void addInfoToNonAuthRecipesBasedOnUserId(TenantIdentifier tenantIdentifi } catch (SQLException e) { throw new StorageQueryException(e); } - } else if (className.equals(MfaStorage.class.getName())) { - try { - MfaQueries.enableFactor(this, tenantIdentifier, userId, "emailpassword"); - } catch (SQLException e) { - throw new StorageQueryException(e); - } } else { throw new IllegalStateException("ClassName: " + className + " is not part of NonAuthRecipeStorage"); } @@ -2813,73 +2798,6 @@ public int removeExpiredCodes(TenantIdentifier tenantIdentifier, long expiredBef } } - - // MFA recipe: - @Override - public boolean enableFactor(TenantIdentifier tenantIdentifier, String userId, String factor) - throws StorageQueryException { - try { - int insertedCount = MfaQueries.enableFactor(this, tenantIdentifier, userId, factor); - if (insertedCount == 0) { - return false; - } - return true; - } catch (SQLException e) { - throw new StorageQueryException(e); - } - } - - @Override - public String[] listFactors(TenantIdentifier tenantIdentifier, String userId) - throws StorageQueryException { - try { - return MfaQueries.listFactors(this, tenantIdentifier, userId); - } catch (SQLException e) { - throw new StorageQueryException(e); - } - } - - @Override - public boolean disableFactor(TenantIdentifier tenantIdentifier, String userId, String factor) - throws StorageQueryException { - try { - int deletedCount = MfaQueries.disableFactor(this, tenantIdentifier, userId, factor); - if (deletedCount == 0) { - return false; - } - return true; - } catch (SQLException e) { - throw new StorageQueryException(e); - } - } - - @Override - public boolean deleteMfaInfoForUser_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId) - throws StorageQueryException { - try { - int deletedCount = MfaQueries.deleteUser_Transaction(this, (Connection) con.getConnection(), appIdentifier, userId); - if (deletedCount == 0) { - return false; - } - return true; - } catch (SQLException e) { - throw new StorageQueryException(e); - } - } - - @Override - public boolean deleteMfaInfoForUser(TenantIdentifier tenantIdentifier, String userId) throws StorageQueryException { - try { - int deletedCount = MfaQueries.deleteUserFromTenant(this, tenantIdentifier, userId); - if (deletedCount == 0) { - return false; - } - return true; - } catch (SQLException e) { - throw new StorageQueryException(e); - } - } - @Override public Set getValidFieldsInConfig() { return SQLiteConfig.getValidFields(); diff --git a/src/main/java/io/supertokens/inmemorydb/config/SQLiteConfig.java b/src/main/java/io/supertokens/inmemorydb/config/SQLiteConfig.java index ada466d1f..25fd59c61 100644 --- a/src/main/java/io/supertokens/inmemorydb/config/SQLiteConfig.java +++ b/src/main/java/io/supertokens/inmemorydb/config/SQLiteConfig.java @@ -141,10 +141,6 @@ public String getTotpUsersTable() { return "totp_users"; } - public String getMfaUserFactorsTable() { - return "mfa_user_factors"; - } - public String getTotpUserDevicesTable() { return "totp_user_devices"; } diff --git a/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java index 3bb08ca1f..81b14e7f5 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/ActiveUsersQueries.java @@ -96,35 +96,11 @@ public static int countUsersEnabledTotpAndActiveSince(Start start, AppIdentifier } public static int countUsersEnabledMfa(Start start, AppIdentifier appIdentifier) throws SQLException, StorageQueryException { - String QUERY = "SELECT COUNT(*) as total FROM (SELECT DISTINCT user_id FROM " + Config.getConfig(start).getMfaUserFactorsTable() + " WHERE app_id = ?) AS app_mfa_users"; - - return execute(start, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - }, result -> { - if (result.next()) { - return result.getInt("total"); - } - return 0; - }); + return 0; // TODO } public static int countUsersEnabledMfaAndActiveSince(Start start, AppIdentifier appIdentifier, long sinceTime) throws SQLException, StorageQueryException { - // Find unique users from mfa_user_factors table and join with user_last_active table - String QUERY = "SELECT COUNT(*) as total FROM (SELECT DISTINCT user_id FROM " + Config.getConfig(start).getMfaUserFactorsTable() + ") AS mfa_users " - + "INNER JOIN " + Config.getConfig(start).getUserLastActiveTable() + " AS user_last_active " - + "ON mfa_users.user_id = user_last_active.user_id " - + "WHERE user_last_active.app_id = ?" - + "AND user_last_active.last_active_time >= ?"; - - return execute(start, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setLong(2, sinceTime); - }, result -> { - if (result.next()) { - return result.getInt("total"); - } - return 0; - }); + return 0; // TODO } public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId) diff --git a/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java index 0a203eef7..26b39e54b 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/GeneralQueries.java @@ -406,11 +406,6 @@ public static void createTablesIfNotExists(Start start, Main main) throws SQLExc // index: update(start, TOTPQueries.getQueryToCreateUsedCodesExpiryTimeIndex(start), NO_OP_SETTER); } - - if (!doesTableExists(start, Config.getConfig(start).getMfaUserFactorsTable())) { - getInstance(main).addState(CREATING_NEW_TABLE, null); - update(start, MfaQueries.getQueryToCreateUserFactorsTable(start), NO_OP_SETTER); - } } diff --git a/src/main/java/io/supertokens/inmemorydb/queries/MfaQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/MfaQueries.java deleted file mode 100644 index 9cca4bf53..000000000 --- a/src/main/java/io/supertokens/inmemorydb/queries/MfaQueries.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.inmemorydb.queries; - -import io.supertokens.inmemorydb.Start; -import io.supertokens.inmemorydb.config.Config; -import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifier; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import static io.supertokens.inmemorydb.QueryExecutorTemplate.execute; -import static io.supertokens.inmemorydb.QueryExecutorTemplate.update; - -public class MfaQueries { - public static String getQueryToCreateUserFactorsTable(Start start) { - return "CREATE TABLE IF NOT EXISTS " + Config.getConfig(start).getMfaUserFactorsTable() + " (" - + "app_id VARCHAR(64) DEFAULT 'public'," - + "tenant_id VARCHAR(64) DEFAULT 'public'," - + "user_id VARCHAR(128) NOT NULL," - + "factor_id VARCHAR(64) NOT NULL," - + "PRIMARY KEY (app_id, tenant_id, user_id, factor_id)," - + "FOREIGN KEY (app_id, tenant_id)" - + "REFERENCES " + Config.getConfig(start).getTenantsTable() + " (app_id, tenant_id) ON DELETE CASCADE);"; - } - - public static int enableFactor(Start start, TenantIdentifier tenantIdentifier, String userId, String factorId) - throws StorageQueryException, SQLException { - String QUERY = "INSERT INTO " + Config.getConfig(start).getMfaUserFactorsTable() + " (app_id, tenant_id, user_id, factor_id) VALUES (?, ?, ?, ?) ON CONFLICT DO NOTHING"; - - return update(start, QUERY, pst -> { - pst.setString(1, tenantIdentifier.getAppId()); - pst.setString(2, tenantIdentifier.getTenantId()); - pst.setString(3, userId); - pst.setString(4, factorId); - }); - } - - - public static String[] listFactors(Start start, TenantIdentifier tenantIdentifier, String userId) - throws StorageQueryException, SQLException { - String QUERY = "SELECT factor_id FROM " + Config.getConfig(start).getMfaUserFactorsTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?"; - - return execute(start, QUERY, pst -> { - pst.setString(1, tenantIdentifier.getAppId()); - pst.setString(2, tenantIdentifier.getTenantId()); - pst.setString(3, userId); - }, result -> { - List factors = new ArrayList<>(); - while (result.next()) { - factors.add(result.getString("factor_id")); - } - - return factors.toArray(String[]::new); - }); - } - - public static String[] listFactors(Start start, AppIdentifier appIdentifier, String userId) - throws StorageQueryException, SQLException { - String QUERY = "SELECT factor_id FROM " + Config.getConfig(start).getMfaUserFactorsTable() + " WHERE app_id = ? AND user_id = ?"; - - return execute(start, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, userId); - }, result -> { - List factors = new ArrayList<>(); - while (result.next()) { - factors.add(result.getString("factor_id")); - } - - return factors.toArray(String[]::new); - }); - } - - public static int disableFactor(Start start, TenantIdentifier tenantIdentifier, String userId, String factorId) - throws StorageQueryException, SQLException { - String QUERY = "DELETE FROM " + Config.getConfig(start).getMfaUserFactorsTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ? AND factor_id = ?"; - - return update(start, QUERY, pst -> { - pst.setString(1, tenantIdentifier.getAppId()); - pst.setString(2, tenantIdentifier.getTenantId()); - pst.setString(3, userId); - pst.setString(4, factorId); - }); - } - - public static int deleteUser_Transaction(Start start, Connection sqlCon, AppIdentifier appIdentifier, String userId) throws StorageQueryException, SQLException { - String QUERY = "DELETE FROM " + Config.getConfig(start).getMfaUserFactorsTable() + " WHERE app_id = ? AND user_id = ?"; - - return update(sqlCon, QUERY, pst -> { - pst.setString(1, appIdentifier.getAppId()); - pst.setString(2, userId); - }); - } - - public static int deleteUserFromTenant(Start start, TenantIdentifier tenantIdentifier, String userId) - throws StorageQueryException, SQLException { - String QUERY = "DELETE FROM " + Config.getConfig(start).getMfaUserFactorsTable() + " WHERE app_id = ? AND tenant_id = ? AND user_id = ?"; - - return update(start, QUERY, pst -> { - pst.setString(1, tenantIdentifier.getAppId()); - pst.setString(2, tenantIdentifier.getTenantId()); - pst.setString(3, userId); - }); - } -} diff --git a/src/main/java/io/supertokens/mfa/Mfa.java b/src/main/java/io/supertokens/mfa/Mfa.java index 968d49f5e..a93f7b7c2 100644 --- a/src/main/java/io/supertokens/mfa/Mfa.java +++ b/src/main/java/io/supertokens/mfa/Mfa.java @@ -5,60 +5,20 @@ import io.supertokens.featureflag.FeatureFlag; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.mfa.MfaStorage; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; public class Mfa { - private static boolean isMfaEnabled(AppIdentifier appIdentifier, Main main) - throws StorageQueryException, TenantOrAppNotFoundException { + public static void checkForMFAFeature(AppIdentifier appIdentifier, Main main) + throws StorageQueryException, TenantOrAppNotFoundException, FeatureNotEnabledException { EE_FEATURES[] features = FeatureFlag.getInstance(main, appIdentifier).getEnabledFeatures(); for (EE_FEATURES f : features) { if (f == EE_FEATURES.MFA) { - return true; + return; } } - return false; - } - - public static boolean enableFactor(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String userId, String factorId) - throws - StorageQueryException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (!isMfaEnabled(tenantIdentifierWithStorage.toAppIdentifier(), main)) { - throw new FeatureNotEnabledException( - "MFA feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + - "feature."); - } - - MfaStorage mfaStorage = tenantIdentifierWithStorage.getMfaStorage(); - return mfaStorage.enableFactor(tenantIdentifierWithStorage, userId, factorId); - } - - public static String[] listFactors(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String userId) - throws - StorageQueryException, TenantOrAppNotFoundException, FeatureNotEnabledException { - if (!isMfaEnabled(tenantIdentifierWithStorage.toAppIdentifier(), main)) { - throw new FeatureNotEnabledException( - "MFA feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + - "feature."); - } - - MfaStorage mfaStorage = tenantIdentifierWithStorage.getMfaStorage(); - return mfaStorage.listFactors(tenantIdentifierWithStorage, userId); - } - - public static boolean disableFactor(TenantIdentifierWithStorage tenantIdentifierWithStorage, Main main, String userId, String factorId) - throws - StorageQueryException, TenantOrAppNotFoundException, FeatureNotEnabledException { - - if (!isMfaEnabled(tenantIdentifierWithStorage.toAppIdentifier(), main)) { - throw new FeatureNotEnabledException( - "MFA feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + - "feature."); - } - - MfaStorage mfaStorage = tenantIdentifierWithStorage.getMfaStorage(); - return mfaStorage.disableFactor(tenantIdentifierWithStorage, userId, factorId); + throw new FeatureNotEnabledException( + "MFA feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + + "feature."); } } diff --git a/src/main/java/io/supertokens/totp/Totp.java b/src/main/java/io/supertokens/totp/Totp.java index e5f715c3b..0c2ae63a9 100644 --- a/src/main/java/io/supertokens/totp/Totp.java +++ b/src/main/java/io/supertokens/totp/Totp.java @@ -3,12 +3,10 @@ import com.eatthepath.otp.TimeBasedOneTimePasswordGenerator; import io.supertokens.Main; import io.supertokens.config.Config; -import io.supertokens.featureflag.EE_FEATURES; -import io.supertokens.featureflag.FeatureFlag; import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; +import io.supertokens.mfa.Mfa; 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.exceptions.TenantOrAppNotFoundException; @@ -70,17 +68,6 @@ private static boolean checkCode(TOTPDevice device, String code) { return false; } - private static boolean isTotpEnabled(AppIdentifier appIdentifier, Main main) - throws StorageQueryException, TenantOrAppNotFoundException { - EE_FEATURES[] features = FeatureFlag.getInstance(main, appIdentifier).getEnabledFeatures(); - for (EE_FEATURES f : features) { - if (f == EE_FEATURES.TOTP) { - return true; - } - } - return false; - } - @TestOnly public static TOTPDevice registerDevice(Main main, String userId, String deviceName, int skew, int period) @@ -126,11 +113,7 @@ public static TOTPDevice registerDevice(AppIdentifierWithStorage appIdentifierWi throws StorageQueryException, DeviceAlreadyExistsException, NoSuchAlgorithmException, FeatureNotEnabledException, TenantOrAppNotFoundException, StorageTransactionLogicException { - if (!isTotpEnabled(appIdentifierWithStorage, main)) { - throw new FeatureNotEnabledException( - "TOTP feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + - "feature."); - } + Mfa.checkForMFAFeature(appIdentifierWithStorage, main); String secret = generateSecret(); TOTPDevice device = new TOTPDevice(userId, deviceName, secret, period, skew, false); @@ -403,11 +386,7 @@ public static void verifyCode(TenantIdentifierWithStorage tenantIdentifierWithSt StorageQueryException, StorageTransactionLogicException, FeatureNotEnabledException, TenantOrAppNotFoundException { - if (!isTotpEnabled(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), main)) { - throw new FeatureNotEnabledException( - "TOTP feature is not enabled. Please subscribe to a SuperTokens core license key to enable this " + - "feature."); - } + Mfa.checkForMFAFeature(tenantIdentifierWithStorage.toAppIdentifierWithStorage(), main); TOTPSQLStorage totpStorage = tenantIdentifierWithStorage.getTOTPStorage(); diff --git a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java index 4bd304811..687e8fea2 100644 --- a/src/main/java/io/supertokens/useridmapping/UserIdMapping.java +++ b/src/main/java/io/supertokens/useridmapping/UserIdMapping.java @@ -27,7 +27,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.exceptions.StorageTransactionLogicException; import io.supertokens.pluginInterface.jwt.JWTRecipeStorage; -import io.supertokens.pluginInterface.mfa.MfaStorage; import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -343,14 +342,6 @@ public static void assertThatUserIdIsNotBeingUsedInNonAuthRecipes( new WebserverAPI.BadRequestException("UserId is already in use in EmailVerification recipe")); } } - { - if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, - MfaStorage.class.getName(), - userId)) { - throw new ServletException( - new WebserverAPI.BadRequestException("UserId is already in use in MFA recipe")); - } - } { if (storage.isUserIdBeingUsedInNonAuthRecipe(appIdentifierWithStorage, JWTRecipeStorage.class.getName(), diff --git a/src/main/java/io/supertokens/webserver/Webserver.java b/src/main/java/io/supertokens/webserver/Webserver.java index b418d5e4a..5e4a4ff8c 100644 --- a/src/main/java/io/supertokens/webserver/Webserver.java +++ b/src/main/java/io/supertokens/webserver/Webserver.java @@ -37,9 +37,6 @@ import io.supertokens.webserver.api.emailverification.VerifyEmailAPI; import io.supertokens.webserver.api.jwt.JWKSAPI; import io.supertokens.webserver.api.jwt.JWTSigningAPI; -import io.supertokens.webserver.api.mfa.DisableFactorAPI; -import io.supertokens.webserver.api.mfa.EnableFactorAPI; -import io.supertokens.webserver.api.mfa.ListFactorsAPI; import io.supertokens.webserver.api.multitenancy.*; import io.supertokens.webserver.api.multitenancy.thirdparty.CreateOrUpdateThirdPartyConfigAPI; import io.supertokens.webserver.api.multitenancy.thirdparty.RemoveThirdPartyConfigAPI; @@ -232,10 +229,6 @@ private void setupRoutes() { addAPI(new GetDashboardSessionsForUserAPI(main)); addAPI(new SearchTagsAPI(main)); - addAPI(new ListFactorsAPI(main)); - addAPI(new EnableFactorAPI(main)); - addAPI(new DisableFactorAPI(main)); - addAPI(new CreateOrUpdateConnectionUriDomainAPI(main)); addAPI(new RemoveConnectionUriDomainAPI(main)); addAPI(new ListConnectionUriDomainsAPI(main)); diff --git a/src/main/java/io/supertokens/webserver/api/mfa/DisableFactorAPI.java b/src/main/java/io/supertokens/webserver/api/mfa/DisableFactorAPI.java deleted file mode 100644 index 92acecacb..000000000 --- a/src/main/java/io/supertokens/webserver/api/mfa/DisableFactorAPI.java +++ /dev/null @@ -1,81 +0,0 @@ -package io.supertokens.webserver.api.mfa; - -import com.google.gson.JsonObject; -import io.supertokens.Main; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; -import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; -import io.supertokens.mfa.Mfa; -import io.supertokens.pluginInterface.RECIPE_ID; -import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; -import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.useridmapping.UserIdType; -import io.supertokens.webserver.InputParser; -import io.supertokens.webserver.WebserverAPI; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import java.io.IOException; - -public class DisableFactorAPI extends WebserverAPI { - private static final long serialVersionUID = -4641988458637882374L; - - public DisableFactorAPI(Main main) { - super(main, RECIPE_ID.MFA.toString()); - } - - @Override - public String getPath() { - return "/recipe/mfa/factors/disable"; - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific - JsonObject input = InputParser.parseJsonObjectOrThrowError(req); - - String userId = InputParser.parseStringOrThrowError(input, "userId", false); - String factor = InputParser.parseStringOrThrowError(input, "factor", false).trim().toLowerCase(); - - if (userId.isEmpty()) { - throw new ServletException(new BadRequestException("userId cannot be empty")); - } - if (factor.isEmpty()) { - throw new ServletException(new BadRequestException("factor cannot be empty")); - } - - JsonObject result = new JsonObject(); - - try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; - 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 mfa tables must also use internal user id. - - // Try to find the tenantIdentifier with right storage based on the userId - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getTenantIdentifierWithStorageAndUserIdMappingFromRequest( - req, userId, UserIdType.ANY); - - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; - } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; - } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); - } - - boolean actuallyDeleted = Mfa.disableFactor(tenantIdentifierWithStorage, main, userId, factor); - - result.addProperty("status", "OK"); - result.addProperty("didExist", actuallyDeleted); - super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | FeatureNotEnabledException | TenantOrAppNotFoundException e) { - throw new ServletException(e); - } - } - -} diff --git a/src/main/java/io/supertokens/webserver/api/mfa/EnableFactorAPI.java b/src/main/java/io/supertokens/webserver/api/mfa/EnableFactorAPI.java deleted file mode 100644 index 34d35509e..000000000 --- a/src/main/java/io/supertokens/webserver/api/mfa/EnableFactorAPI.java +++ /dev/null @@ -1,81 +0,0 @@ -package io.supertokens.webserver.api.mfa; - -import com.google.gson.JsonObject; -import io.supertokens.Main; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; -import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; -import io.supertokens.mfa.Mfa; -import io.supertokens.pluginInterface.RECIPE_ID; -import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; -import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.useridmapping.UserIdType; -import io.supertokens.webserver.InputParser; -import io.supertokens.webserver.WebserverAPI; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import java.io.IOException; - -public class EnableFactorAPI extends WebserverAPI { - private static final long serialVersionUID = -4641988458637882374L; - - public EnableFactorAPI(Main main) { - super(main, RECIPE_ID.MFA.toString()); - } - - @Override - public String getPath() { - return "/recipe/mfa/factors/enable"; - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific - JsonObject input = InputParser.parseJsonObjectOrThrowError(req); - - String userId = InputParser.parseStringOrThrowError(input, "userId", false); - String factor = InputParser.parseStringOrThrowError(input, "factor", false).trim().toLowerCase(); - - if (userId.isEmpty()) { - throw new ServletException(new BadRequestException("userId cannot be empty")); - } - if (factor.isEmpty()) { - throw new ServletException(new BadRequestException("factor cannot be empty")); - } - - JsonObject result = new JsonObject(); - - try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; - 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 mfa tables must also use internal user id. - - // Try to find the tenantIdentifier with right storage based on the userId - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getTenantIdentifierWithStorageAndUserIdMappingFromRequest( - req, userId, UserIdType.ANY); - - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; - } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; - } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); - } - - boolean actuallyInserted = Mfa.enableFactor(tenantIdentifierWithStorage, main, userId, factor); - - result.addProperty("status", "OK"); - result.addProperty("didExist", !actuallyInserted); - super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | FeatureNotEnabledException | TenantOrAppNotFoundException e) { - throw new ServletException(e); - } - } - -} diff --git a/src/main/java/io/supertokens/webserver/api/mfa/ListFactorsAPI.java b/src/main/java/io/supertokens/webserver/api/mfa/ListFactorsAPI.java deleted file mode 100644 index 06ed4729b..000000000 --- a/src/main/java/io/supertokens/webserver/api/mfa/ListFactorsAPI.java +++ /dev/null @@ -1,83 +0,0 @@ -package io.supertokens.webserver.api.mfa; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import io.supertokens.Main; -import io.supertokens.TenantIdentifierWithStorageAndUserIdMapping; -import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; -import io.supertokens.mfa.Mfa; -import io.supertokens.pluginInterface.RECIPE_ID; -import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; -import io.supertokens.pluginInterface.exceptions.StorageQueryException; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; -import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.useridmapping.UserIdType; -import io.supertokens.webserver.InputParser; -import io.supertokens.webserver.WebserverAPI; -import jakarta.servlet.ServletException; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import java.io.IOException; - -public class ListFactorsAPI extends WebserverAPI { - private static final long serialVersionUID = -4641988458637882374L; - - public ListFactorsAPI(Main main) { - super(main, RECIPE_ID.MFA.toString()); - } - - @Override - public String getPath() { - return "/recipe/mfa/factors/list"; - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { - // API is tenant specific - String userId = InputParser.getQueryParamOrThrowError(req, "userId", false); - - if (userId.isEmpty()) { - throw new ServletException(new BadRequestException("userId cannot be empty")); - } - - JsonObject result = new JsonObject(); - - try { - TenantIdentifierWithStorage tenantIdentifierWithStorage; - 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 mfa tables must also use internal user id. - - // Try to find the tenantIdentifier with right storage based on the userId - TenantIdentifierWithStorageAndUserIdMapping mappingAndStorage = - getTenantIdentifierWithStorageAndUserIdMappingFromRequest( - req, userId, UserIdType.ANY); - - if (mappingAndStorage.userIdMapping != null) { - userId = mappingAndStorage.userIdMapping.superTokensUserId; - } - tenantIdentifierWithStorage = mappingAndStorage.tenantIdentifierWithStorage; - } catch (UnknownUserIdException e) { - // if the user is not found, just use the storage of the tenant of interest - tenantIdentifierWithStorage = getTenantIdentifierWithStorageFromRequest(req); - } - - String[] factors = Mfa.listFactors(tenantIdentifierWithStorage, main, userId); - - JsonArray factorsJson = new JsonArray(); - - for (String factor : factors) { - factorsJson.add(new JsonPrimitive(factor)); - } - - result.addProperty("status", "OK"); - result.add("factors", factorsJson); - super.sendJsonResponse(200, result, resp); - } catch (StorageQueryException | FeatureNotEnabledException | TenantOrAppNotFoundException e) { - throw new ServletException(e); - } - } - -} diff --git a/src/test/java/io/supertokens/test/FeatureFlagTest.java b/src/test/java/io/supertokens/test/FeatureFlagTest.java index 8c249464b..2c52f5d53 100644 --- a/src/test/java/io/supertokens/test/FeatureFlagTest.java +++ b/src/test/java/io/supertokens/test/FeatureFlagTest.java @@ -21,10 +21,6 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.supertokens.ProcessState; -import io.supertokens.cronjobs.CronTask; -import io.supertokens.cronjobs.CronTaskTest; -import io.supertokens.cronjobs.Cronjobs; -import io.supertokens.cronjobs.syncCoreConfigWithDb.SyncCoreConfigWithDb; import io.supertokens.emailpassword.EmailPassword; import io.supertokens.featureflag.EE_FEATURES; import io.supertokens.featureflag.FeatureFlag; @@ -32,9 +28,7 @@ import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; import io.supertokens.featureflag.exceptions.NoLicenseKeyFoundException; import io.supertokens.multitenancy.Multitenancy; -import io.supertokens.multitenancy.MultitenancyHelper; import io.supertokens.pluginInterface.STORAGE_TYPE; -import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.*; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; @@ -159,9 +153,6 @@ public void testThatCallingGetFeatureFlagAPIReturnsEmptyArray() throws Exception Assert.assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); } - private final String OPAQUE_KEY_WITH_TOTP_FEATURE = "pXhNK=nYiEsb6gJEOYP2kIR6M0kn4XLvNqcwT1XbX8xHtm44K" + - "-lQfGCbaeN0Ieeza39fxkXr=tiiUU=DXxDH40Y=4FLT4CE-rG1ETjkXxO4yucLpJvw3uSegPayoISGL"; - @Test public void testThatCallingGetFeatureFlagAPIReturnsTotpStats() throws Exception { String[] args = {"../"}; @@ -173,7 +164,7 @@ public void testThatCallingGetFeatureFlagAPIReturnsTotpStats() throws Exception return; } - FeatureFlag.getInstance(process.main).setLicenseKeyAndSyncFeatures(OPAQUE_KEY_WITH_TOTP_FEATURE); + FeatureFlag.getInstance(process.main).setLicenseKeyAndSyncFeatures(OPAQUE_KEY_WITH_MFA_FEATURE); // Get the stats without any users/activity { @@ -191,12 +182,12 @@ public void testThatCallingGetFeatureFlagAPIReturnsTotpStats() throws Exception } else { assert features.size() == 1; } - assert features.contains(new JsonPrimitive("totp")); + assert features.contains(new JsonPrimitive("mfa")); assert maus.size() == 30; assert maus.get(0).getAsInt() == 0; assert maus.get(29).getAsInt() == 0; - JsonObject totpStats = usageStats.get("totp").getAsJsonObject(); + JsonObject totpStats = usageStats.get("mfa").getAsJsonObject().get("totp").getAsJsonObject(); JsonArray totpMaus = totpStats.get("maus").getAsJsonArray(); int totalTotpUsers = totpStats.get("total_users").getAsInt(); @@ -250,12 +241,12 @@ public void testThatCallingGetFeatureFlagAPIReturnsTotpStats() throws Exception assert features.size() == 1; } - assert features.contains(new JsonPrimitive("totp")); + assert features.contains(new JsonPrimitive("mfa")); assert maus.size() == 30; assert maus.get(0).getAsInt() == 2; // 2 users have signed up assert maus.get(29).getAsInt() == 2; - JsonObject totpStats = usageStats.get("totp").getAsJsonObject(); + JsonObject totpStats = usageStats.get("mfa").getAsJsonObject().get("totp").getAsJsonObject(); JsonArray totpMaus = totpStats.get("maus").getAsJsonArray(); int totalTotpUsers = totpStats.get("total_users").getAsInt(); @@ -273,107 +264,6 @@ public void testThatCallingGetFeatureFlagAPIReturnsTotpStats() throws Exception private final static String OPAQUE_KEY_WITH_MFA_FEATURE = "Qk8olVa=v-9PU=snnUFMF4ihMCx4zVBOO6Jd7Nrg6Cg5YyFliEj252ADgpwEpDLfFowA0U5OyVo3XL=U4FMft2HDHCDGg9hWD4iwQQiyjMRi6Mu03CVbAxIkNGaXtJ53"; - @Test - public void testThatCallingGetFeatureFlagAPIReturnsMfaStats() throws Exception { - String[] args = {"../"}; - - TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); - Assert.assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); - - if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { - return; - } - - FeatureFlag.getInstance(process.main).setLicenseKeyAndSyncFeatures(OPAQUE_KEY_WITH_MFA_FEATURE); - - // Get the stats without any users/activity - { - JsonObject response = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", - "http://localhost:3567/ee/featureflag", - null, 1000, 1000, null, WebserverAPI.getLatestCDIVersion().get(), ""); - Assert.assertEquals("OK", response.get("status").getAsString()); - - JsonArray features = response.get("features").getAsJsonArray(); - JsonObject usageStats = response.get("usageStats").getAsJsonObject(); - JsonArray maus = usageStats.get("maus").getAsJsonArray(); - - if (!StorageLayer.isInMemDb(process.getProcess())) { - assert features.size() == 1; - assert features.get(0).getAsString().equals("mfa"); - } - assert maus.size() == 30; - assert maus.get(0).getAsInt() == 0; - assert maus.get(29).getAsInt() == 0; - - JsonObject mfaStats = usageStats.get("mfa").getAsJsonObject(); - JsonArray mfaMaus = mfaStats.get("maus").getAsJsonArray(); - int totaMfaUsers = mfaStats.get("total_users").getAsInt(); - - assert mfaMaus.size() == 30; - assert mfaMaus.get(0).getAsInt() == 0; - assert mfaMaus.get(29).getAsInt() == 0; - - assert totaMfaUsers == 0; - } - - // First register 2 users for emailpassword recipe. - // This also marks them as active. - JsonObject signUpResponse = Utils.signUpRequest_2_5(process, "random@gmail.com", "validPass123"); - assert signUpResponse.get("status").getAsString().equals("OK"); - - JsonObject signUpResponse2 = Utils.signUpRequest_2_5(process, "random2@gmail.com", "validPass123"); - assert signUpResponse2.get("status").getAsString().equals("OK"); - - // Now enable MFA for the first user by enabling a factor. - JsonObject body = new JsonObject(); - body.addProperty("userId", signUpResponse.get("user").getAsJsonObject().get("id").getAsString()); - body.addProperty("factor", "f1"); - JsonObject res = HttpRequestForTesting.sendJsonPOSTRequest( - process.getProcess(), - "", - "http://localhost:3567/recipe/mfa/factors/enable", - body, - 1000, - 1000, - null, - Utils.getCdiVersionStringLatestForTests(), - "mfa"); - assert res.get("status").getAsString().equals("OK"); - - // Now check the stats again: - { - JsonObject response = HttpRequestForTesting.sendGETRequest(process.getProcess(), "", - "http://localhost:3567/ee/featureflag", - null, 1000, 1000, null, WebserverAPI.getLatestCDIVersion().get(), ""); - Assert.assertEquals("OK", response.get("status").getAsString()); - - JsonArray features = response.get("features").getAsJsonArray(); - JsonObject usageStats = response.get("usageStats").getAsJsonObject(); - JsonArray maus = usageStats.get("maus").getAsJsonArray(); - - if (!StorageLayer.isInMemDb(process.getProcess())) { - assert features.size() == 1; - assert features.get(0).getAsString().equals("mfa"); - } - assert maus.size() == 30; - assert maus.get(0).getAsInt() == 2; // 2 users have signed up - assert maus.get(29).getAsInt() == 2; - - JsonObject mfaStats = usageStats.get("mfa").getAsJsonObject(); - JsonArray mfaMaus = mfaStats.get("maus").getAsJsonArray(); - int totalMfaUsers = mfaStats.get("total_users").getAsInt(); - - assert mfaMaus.size() == 30; - assert mfaMaus.get(0).getAsInt() == 1; // only 1 user has MFA factor enabled - assert mfaMaus.get(29).getAsInt() == 1; - - assert totalMfaUsers == 1; - } - - process.kill(); - Assert.assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED)); - } - private final String OPAQUE_KEY_WITH_MULTITENANCY_FEATURE = "ijaleljUd2kU9XXWLiqFYv5br8nutTxbyBqWypQdv2N-" + "BocoNriPrnYQd0NXPm8rVkeEocN9ayq0B7c3Pv-BTBIhAZSclXMlgyfXtlwAOJk=9BfESEleW6LyTov47dXu"; @@ -871,10 +761,9 @@ public void testPaidStatsContainsAllEnabledFeatures() throws Exception { String[] licenses = new String[]{ OPAQUE_KEY_WITH_MULTITENANCY_FEATURE, - OPAQUE_KEY_WITH_TOTP_FEATURE, + OPAQUE_KEY_WITH_MFA_FEATURE, OPAQUE_KEY_WITH_DASHBOARD_FEATURE, - OPAQUE_KEY_WITH_ACCOUNT_LINKING_FEATURE, - OPAQUE_KEY_WTIH_MFA_FEATURE + OPAQUE_KEY_WITH_ACCOUNT_LINKING_FEATURE }; Set requiredFeatures = new HashSet<>(); diff --git a/src/test/java/io/supertokens/test/mfa/MfaLicenseTest.java b/src/test/java/io/supertokens/test/mfa/MfaLicenseTest.java deleted file mode 100644 index 96d32a3f6..000000000 --- a/src/test/java/io/supertokens/test/mfa/MfaLicenseTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa; - -import com.google.gson.JsonObject; -import io.supertokens.Main; -import io.supertokens.featureflag.exceptions.FeatureNotEnabledException; -import io.supertokens.mfa.Mfa; -import io.supertokens.pluginInterface.mfa.MfaStorage; -import io.supertokens.pluginInterface.multitenancy.TenantIdentifierWithStorage; -import io.supertokens.storageLayer.StorageLayer; -import io.supertokens.test.httpRequest.HttpResponseException; -import org.junit.Test; - -import java.util.HashMap; - -import static org.junit.Assert.assertThrows; - -public class MfaLicenseTest extends MfaTestBase { - @Test - public void testTotpWithoutLicense() throws Exception { - TestSetupResult result = initSteps(false); - if (result == null) { - return; - } - - if (StorageLayer.isInMemDb(result.process.getProcess())) { - return; - } - - Main main = result.process.getProcess(); - MfaStorage storage = result.storage; - TenantIdentifierWithStorage tid = new TenantIdentifierWithStorage(null, null, null, storage); - - // Enable factor - assertThrows(FeatureNotEnabledException.class, () -> { - Mfa.enableFactor(tid, main, "userId", "f1"); - }); - // List factors - assertThrows(FeatureNotEnabledException.class, () -> { - Mfa.listFactors(tid, main, "user"); - }); - // Disable factor - assertThrows(FeatureNotEnabledException.class, () -> { - Mfa.disableFactor(tid, main, "userId", "f1"); - }); - - // Try to create device via API: - JsonObject body = new JsonObject(); - body.addProperty("userId", "user-id"); - body.addProperty("factor", "f1"); - - HttpResponseException e = assertThrows( - HttpResponseException.class, - () -> { - enableFactorRequest(result.process, body); - } - ); - assert e.statusCode == 402; - assert e.getMessage().contains("MFA feature is not enabled"); - - - // Try to list devices via API: - HashMap params = new HashMap<>(); - params.put("userId", "user-id"); - - HttpResponseException e2 = assertThrows( - HttpResponseException.class, - () -> { - listFactorsRequest(result.process, params); - } - ); - assert e2.statusCode == 402; - assert e2.getMessage().contains("MFA feature is not enabled"); - - // Try to disable factor via API: - body.addProperty("userId", "user-id"); - body.addProperty("factor", "f1"); - - HttpResponseException e3 = assertThrows( - HttpResponseException.class, - () -> { - disableFactorRequest(result.process, body); - } - ); - assert e3.statusCode == 402; - assert e3.getMessage().contains("MFA feature is not enabled"); - } - - - @Test - public void testTotpWithLicense() throws Exception { - TestSetupResult result = initSteps(true); - if (result == null) { - return; - } - Main main = result.process.getProcess(); - MfaStorage storage = result.storage; - TenantIdentifierWithStorage tid = new TenantIdentifierWithStorage(null, null, null, storage); - - // Enable factor - boolean insertedFactor = Mfa.enableFactor(tid, main, "userId", "f1"); - assert insertedFactor; - // List factors - String[] factors = Mfa.listFactors(tid, main, "userId"); - assert factors.length == 1; - assert factors[0].equals("f1"); - // Disable factor - boolean removedFactor = Mfa.disableFactor(tid, main, "userId", "f1"); - assert removedFactor; - - // Try to enable factor via API: - JsonObject body = new JsonObject(); - body.addProperty("userId", "user-id"); - body.addProperty("factor", "f1"); - - JsonObject res = enableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == false; - - // Try to list factors via API: - HashMap params = new HashMap<>(); - params.put("userId", "user-id"); - - JsonObject res2 = listFactorsRequest(result.process, params); - assert res2.get("status").getAsString().equals("OK"); - assert res2.get("factors").getAsJsonArray().size() == 1; - assert res2.get("factors").getAsJsonArray().get(0).getAsString().equals("f1"); - - // Try to disable factor via API: - body.addProperty("userId", "user-id"); - body.addProperty("factor", "f1"); - - JsonObject res3 = disableFactorRequest(result.process, body); - assert res3.get("status").getAsString().equals("OK"); - assert res3.get("didExist").getAsBoolean() == true; - } -} diff --git a/src/test/java/io/supertokens/test/mfa/MfaRecipeTest.java b/src/test/java/io/supertokens/test/mfa/MfaRecipeTest.java deleted file mode 100644 index 1182e71a5..000000000 --- a/src/test/java/io/supertokens/test/mfa/MfaRecipeTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa; - -import com.google.gson.JsonObject; -import io.supertokens.Main; -import io.supertokens.emailpassword.EmailPassword; -import io.supertokens.featureflag.EE_FEATURES; -import io.supertokens.featureflag.FeatureFlagTestContent; -import io.supertokens.mfa.Mfa; -import io.supertokens.multitenancy.Multitenancy; -import io.supertokens.pluginInterface.mfa.MfaStorage; -import io.supertokens.pluginInterface.multitenancy.*; -import org.junit.Test; - -import static org.junit.Assert.assertNotNull; - -public class MfaRecipeTest extends MfaTestBase { - @Test - public void enableFactorTests() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaStorage storage = result.storage; - Main main = result.process.main; - TenantIdentifierWithStorage tid = new TenantIdentifierWithStorage(null, null, null, storage); - - boolean insertedF1 = Mfa.enableFactor(tid, main, "userId", "f1"); - assert insertedF1; - - String[] factors = Mfa.listFactors(tid, main, "userId"); - - assert factors != null; - assert factors.length == 1; - assert factors[0].equals("f1"); - - boolean insertedF1Again = Mfa.enableFactor(tid, main, "userId", "f1"); - boolean insertedF2 = Mfa.enableFactor(tid, main, "userId", "f2"); - - assert !insertedF1Again; - assert insertedF2; - } - - @Test - public void listFactorsTest() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaStorage storage = result.storage; - Main main = result.process.main; - TenantIdentifierWithStorage tid = new TenantIdentifierWithStorage(null, null, null, storage); - - assert Mfa.enableFactor(tid, main, "userId", "f3") == true; - assert Mfa.enableFactor(tid, main, "userId", "f1") == true; - assert Mfa.enableFactor(tid, main, "userId", "f2") == true; - - assert Mfa.disableFactor(tid, main, "userId", "f2") == true; - - String[] factors = Mfa.listFactors(tid, main, "userId"); - - assert factors != null; - assert factors.length == 2; - assert factors[0].equals("f1"); - assert factors[1].equals("f3"); - } - - @Test - public void disableFactorsTest() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaStorage storage = result.storage; - Main main = result.process.main; - TenantIdentifierWithStorage tid = new TenantIdentifierWithStorage(null, null, null, storage); - - assert Mfa.enableFactor(tid, main, "userId", "f1") == true; - assert Mfa.enableFactor(tid, main, "userId", "f2") == true; - - assert Mfa.disableFactor(tid, main, "non-existent-userId", "f1") == false; // userId does not exist - assert Mfa.disableFactor(tid, main, "userId", "f2") == true; // f2 was enabled - assert Mfa.disableFactor(tid, main, "userId", "f3") == false; // f3 was never enabled - - String[] factors = storage.listFactors(tid, "userId"); - - assert factors != null; - assert factors.length == 1; - assert factors[0].equals("f1"); - - factors = Mfa.listFactors(tid, main, "non-existent-user"); - assert factors.length == 0; - } -} diff --git a/src/test/java/io/supertokens/test/mfa/MfaStorageTest.java b/src/test/java/io/supertokens/test/mfa/MfaStorageTest.java deleted file mode 100644 index 6af701819..000000000 --- a/src/test/java/io/supertokens/test/mfa/MfaStorageTest.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa; - -import com.google.gson.JsonObject; -import io.supertokens.emailpassword.EmailPassword; -import io.supertokens.featureflag.EE_FEATURES; -import io.supertokens.featureflag.FeatureFlagTestContent; -import io.supertokens.multitenancy.Multitenancy; -import io.supertokens.pluginInterface.mfa.MfaStorage; -import io.supertokens.pluginInterface.mfa.sqlStorage.MfaSQLStorage; -import io.supertokens.pluginInterface.multitenancy.*; -import io.supertokens.pluginInterface.sqlStorage.SQLStorage; -import org.junit.Test; - -import static org.junit.Assert.assertNotNull; - -public class MfaStorageTest extends MfaTestBase { - - @Test - public void enableFactorTests() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaStorage storage = result.storage; - TenantIdentifier tid = new TenantIdentifier(null, null, null); - - boolean insertedF1 = storage.enableFactor(tid, "userId", "f1"); - assert insertedF1; - - String[] factors = storage.listFactors(tid, "userId"); - - assert factors != null; - assert factors.length == 1; - assert factors[0].equals("f1"); - - boolean insertedF1Again = storage.enableFactor(tid, "userId", "f1"); - boolean insertedF2 = storage.enableFactor(tid, "userId", "f2"); - - assert !insertedF1Again; - assert insertedF2; - } - - @Test - public void listFactorsTest() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaStorage storage = result.storage; - TenantIdentifier tid = new TenantIdentifier(null, null, null); - - assert storage.enableFactor(tid, "userId", "f1") == true; - assert storage.enableFactor(tid, "userId", "f2") == true; - assert storage.enableFactor(tid, "userId", "f3") == true; - - assert storage.disableFactor(tid, "userId", "f2") == true; - - String[] factors = storage.listFactors(tid, "userId"); - - assert factors != null; - assert factors.length == 2; - assert factors[0].equals("f1"); - assert factors[1].equals("f3"); - } - - @Test - public void disableFactorsTest() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaStorage storage = result.storage; - TenantIdentifier tid = new TenantIdentifier(null, null, null); - - assert storage.enableFactor(tid, "userId", "f1") == true; - assert storage.enableFactor(tid, "userId", "f2") == true; - - assert storage.disableFactor(tid, "non-existent-userId", "f1") == false; // userId does not exist - assert storage.disableFactor(tid, "userId", "f2") == true; // f2 was enabled - assert storage.disableFactor(tid, "userId", "f3") == false; // f3 was never enabled - - String[] factors = storage.listFactors(tid, "userId"); - - assert factors != null; - assert factors.length == 1; - assert factors[0].equals("f1"); - - factors = storage.listFactors(tid, "non-existent-user"); - assert factors.length == 0; - } - - - @Test - public void deleteUserTest() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - MfaSQLStorage storage = result.storage; - TenantIdentifier tid = new TenantIdentifier(null, null, null); - - assert storage.enableFactor(tid, "user1", "f1") == true; - assert storage.enableFactor(tid, "user1", "f2") == true; - - assert storage.enableFactor(tid, "user2", "f1") == true; - assert storage.enableFactor(tid, "user2", "f3") == true; - - ((SQLStorage) storage).startTransaction(con -> { - assert storage.deleteMfaInfoForUser_Transaction(con, tid.toAppIdentifier(), "non-existent-user") == false; - assert storage.deleteMfaInfoForUser_Transaction(con, tid.toAppIdentifier(), "user2") == true; - return null; - }); - - String[] factors = storage.listFactors(tid, "user2"); - assert factors.length == 0; - - factors = storage.listFactors(tid, "user1"); - - assert factors.length == 2; - assert factors[0].equals("f1"); - assert factors[1].equals("f2"); - } - - - @Test - public void deleteUserFromTenantTest() throws Exception { - TestSetupResult result = initSteps(); - if (result == null) { - return; - } - - FeatureFlagTestContent.getInstance(result.process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA, EE_FEATURES.MULTI_TENANCY}); - - MfaStorage mfaStorage = result.storage; - - TenantIdentifierWithStorage publicTenant = new TenantIdentifierWithStorage(null, null, null, result.storage); - TenantIdentifierWithStorage privateTenant = new TenantIdentifierWithStorage(null, null, "t1", result.storage); - - TenantConfig privateTenantConfig = new TenantConfig(privateTenant, new EmailPasswordConfig(true), new ThirdPartyConfig(true, null), new PasswordlessConfig(true), new JsonObject()); - - Multitenancy.addNewOrUpdateAppOrTenant( - result.process.main, - privateTenantConfig, - false - ); - - // we will use the same userId for both tenants - String userId = EmailPassword.signUp( - privateTenant, - result.process.main, - "user@example.com", - "password" - ).getSupertokensUserId(); - - // Iterate over all both tenants and enable the same set of factors for the same user ID - for (TenantIdentifierWithStorage tid : new TenantIdentifierWithStorage[]{publicTenant, privateTenant}) { - assert mfaStorage.enableFactor(tid, userId, "f1") == true; - assert mfaStorage.enableFactor(tid, userId, "f2") == true; - } - - // Delete private tenant user - assert mfaStorage.deleteMfaInfoForUser(privateTenant, userId) == true; - - // Deleting user from one tenant shouldn't affect others: - assert mfaStorage.listFactors(privateTenant, userId).length == 0; - assert mfaStorage.listFactors(publicTenant, userId).length == 2; - - String userEmail = EmailPassword.signIn(privateTenant, result.process.main, "user@example.com", "password").loginMethods[0].email; - assert userEmail.equals("user@example.com"); // Use should still exist in the private tenant since we have only disabled MFA related info - - // Deleting from non existent user should return false: - assert mfaStorage.deleteMfaInfoForUser(privateTenant, "non-existent-user") == false; - } - -} diff --git a/src/test/java/io/supertokens/test/mfa/MfaTestBase.java b/src/test/java/io/supertokens/test/mfa/MfaTestBase.java deleted file mode 100644 index 1d9b236d5..000000000 --- a/src/test/java/io/supertokens/test/mfa/MfaTestBase.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa; - -import com.google.gson.JsonObject; -import io.supertokens.ProcessState; -import io.supertokens.featureflag.EE_FEATURES; -import io.supertokens.featureflag.FeatureFlagTestContent; -import io.supertokens.pluginInterface.STORAGE_TYPE; -import io.supertokens.pluginInterface.mfa.sqlStorage.MfaSQLStorage; -import io.supertokens.storageLayer.StorageLayer; -import io.supertokens.test.TestingProcessManager; -import io.supertokens.test.Utils; -import io.supertokens.test.httpRequest.HttpRequestForTesting; -import io.supertokens.test.httpRequest.HttpResponseException; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.TestRule; - -import java.io.IOException; -import java.util.HashMap; - -import static org.junit.Assert.*; - -public class MfaTestBase { - @Rule - public TestRule watchman = Utils.getOnFailure(); - - @AfterClass - public static void afterTesting() { - Utils.afterTesting(); - } - - @Before - public void beforeEach() { - Utils.reset(); - } - - - public class TestSetupResult { - public MfaSQLStorage storage; - public TestingProcessManager.TestingProcess process; - - public TestSetupResult(MfaSQLStorage storage, TestingProcessManager.TestingProcess process) { - this.storage = storage; - this.process = process; - } - } - - public TestSetupResult initSteps(boolean enableMfaFeature) - throws InterruptedException { - String[] args = {"../"}; - - TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); - assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); - - if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { - return null; - } - - MfaSQLStorage storage = (MfaSQLStorage) StorageLayer.getStorage(process.getProcess()); - - if (enableMfaFeature) { - FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); - } - - return new TestSetupResult(storage, process); - } - - public TestSetupResult initSteps() - throws InterruptedException { - return initSteps(true); - } - - public void checkFieldMissingErrorResponse(Exception ex, String fieldName) { - assert ex instanceof HttpResponseException; - HttpResponseException e = (HttpResponseException) ex; - assert e.statusCode == 400; - assertTrue(e.getMessage().contains( - "Http error. Status Code: 400. Message: Field name '" + fieldName + "' is invalid in JSON input")); - } - - public void checkResponseErrorContains(Exception ex, String msg) { - assert ex instanceof HttpResponseException; - HttpResponseException e = (HttpResponseException) ex; - assert e.statusCode == 400; - assertTrue(e.getMessage().contains(msg)); - } - - - public JsonObject enableFactorRequest(TestingProcessManager.TestingProcess process, JsonObject body) - throws HttpResponseException, IOException { - return HttpRequestForTesting.sendJsonPOSTRequest( - process.getProcess(), - "", - "http://localhost:3567/recipe/mfa/factors/enable", - body, - 1000, - 1000, - null, - Utils.getCdiVersionStringLatestForTests(), - "mfa"); - } - - public JsonObject listFactorsRequest(TestingProcessManager.TestingProcess process, HashMap params) - throws HttpResponseException, IOException { - return HttpRequestForTesting.sendGETRequest( - process.getProcess(), - "", - "http://localhost:3567/recipe/mfa/factors/list", - params, - 1000, - 1000, - null, - Utils.getCdiVersionStringLatestForTests(), - "mfa"); - } - - public JsonObject disableFactorRequest(TestingProcessManager.TestingProcess process, JsonObject body) - throws HttpResponseException, IOException { - return HttpRequestForTesting.sendJsonPOSTRequest( - process.getProcess(), - "", - "http://localhost:3567/recipe/mfa/factors/disable", - body, - 1000, - 1000, - null, - Utils.getCdiVersionStringLatestForTests(), - "mfa"); - } -} diff --git a/src/test/java/io/supertokens/test/mfa/api/DisableFactorAPITest.java b/src/test/java/io/supertokens/test/mfa/api/DisableFactorAPITest.java deleted file mode 100644 index 946bc73c2..000000000 --- a/src/test/java/io/supertokens/test/mfa/api/DisableFactorAPITest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa.api; - -import com.google.gson.JsonObject; -import io.supertokens.test.TestingProcessManager; -import io.supertokens.test.httpRequest.HttpResponseException; -import io.supertokens.test.mfa.MfaTestBase; -import org.junit.Test; - -import java.util.HashMap; - -import static org.junit.Assert.assertThrows; - -public class DisableFactorAPITest extends MfaTestBase { - private HttpResponseException disableFactorRequestAndReturnException(TestingProcessManager.TestingProcess process, JsonObject body) { - return assertThrows( - HttpResponseException.class, - () -> disableFactorRequest(process, body)); - } - - @Test - public void testApi() throws Exception { - TestSetupResult result = initSteps(); - assert result != null; - - // Prepare by enabling 2 factors for a user - { - JsonObject body = new JsonObject(); - body.addProperty("userId", "userId"); - body.addProperty("factor", "f1"); - enableFactorRequest(result.process, body); - - body.addProperty("factor", "f2"); - enableFactorRequest(result.process, body); - } - - JsonObject body = new JsonObject(); - // Missing userId/factor - { - Exception e = disableFactorRequestAndReturnException(result.process, body); - checkFieldMissingErrorResponse(e, "userId"); - - body.addProperty("userId", ""); - e = disableFactorRequestAndReturnException(result.process, body); - checkFieldMissingErrorResponse(e, "factor"); - } - // Invalid userId/factor - { - body.addProperty("factor", ""); - Exception e = disableFactorRequestAndReturnException(result.process, body); - checkResponseErrorContains(e, "userId cannot be empty"); - - body.addProperty("userId", "userId"); - e = disableFactorRequestAndReturnException(result.process, body); - checkResponseErrorContains(e, "factor cannot be empty"); - } - - body.addProperty("factor", "f1"); - // Should pass now: - JsonObject res = disableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == true; - - // Repeat the same request, should pass but wasAlreadyEnabled should be true - res = disableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == false; - - HashMap params = new HashMap<>(); - params.put("userId", "userId"); - - // Check that the factor was actually disabled - res = listFactorsRequest(result.process, params); - assert res.get("status").getAsString().equals("OK"); - assert res.get("factors").getAsJsonArray().size() == 1; - assert res.get("factors").getAsJsonArray().get(0).getAsString().equals("f2"); - } -} diff --git a/src/test/java/io/supertokens/test/mfa/api/EnableFactorAPITest.java b/src/test/java/io/supertokens/test/mfa/api/EnableFactorAPITest.java deleted file mode 100644 index 3ee31052d..000000000 --- a/src/test/java/io/supertokens/test/mfa/api/EnableFactorAPITest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa.api; - -import com.google.gson.JsonObject; -import io.supertokens.test.TestingProcessManager; -import io.supertokens.test.httpRequest.HttpResponseException; -import io.supertokens.test.mfa.MfaTestBase; -import org.junit.Test; - -import java.util.HashMap; - -import static org.junit.Assert.assertThrows; - -public class EnableFactorAPITest extends MfaTestBase { - private HttpResponseException enableFactorRequestAndReturnException(TestingProcessManager.TestingProcess process, JsonObject body) { - return assertThrows( - HttpResponseException.class, - () -> enableFactorRequest(process, body)); - } - - @Test - public void testApi() throws Exception { - TestSetupResult result = initSteps(); - assert result != null; - - JsonObject body = new JsonObject(); - // Missing userId/factor - { - Exception e = enableFactorRequestAndReturnException(result.process, body); - checkFieldMissingErrorResponse(e, "userId"); - - body.addProperty("userId", ""); - e = enableFactorRequestAndReturnException(result.process, body); - checkFieldMissingErrorResponse(e, "factor"); - } - // Invalid userId/factor - { - body.addProperty("factor", ""); - Exception e = enableFactorRequestAndReturnException(result.process, body); - checkResponseErrorContains(e, "userId cannot be empty"); - - body.addProperty("userId", "userId"); - e = enableFactorRequestAndReturnException(result.process, body); - checkResponseErrorContains(e, "factor cannot be empty"); - } - - body.addProperty("factor", "f1"); - // Should pass now: - JsonObject res = enableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == false; - - // Repeat the same request, should pass but didExist should be true - res = enableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == true; - - // Check that the factors were actually enabled - { - HashMap params = new HashMap<>(); - params.put("userId", "userId"); - res = listFactorsRequest(result.process, params); - assert res.get("status").getAsString().equals("OK"); - assert res.get("factors").getAsJsonArray().size() == 1; - assert res.get("factors").getAsJsonArray().get(0).getAsString().equals("f1"); - } - - } -} diff --git a/src/test/java/io/supertokens/test/mfa/api/ListFactorsAPITest.java b/src/test/java/io/supertokens/test/mfa/api/ListFactorsAPITest.java deleted file mode 100644 index 0a629627a..000000000 --- a/src/test/java/io/supertokens/test/mfa/api/ListFactorsAPITest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa.api; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import io.supertokens.Main; -import io.supertokens.pluginInterface.mfa.MfaStorage; -import io.supertokens.test.TestingProcessManager; -import io.supertokens.test.httpRequest.HttpResponseException; -import io.supertokens.test.mfa.MfaTestBase; -import org.junit.Test; - -import java.util.HashMap; - -import static org.junit.Assert.assertThrows; - -public class ListFactorsAPITest extends MfaTestBase { - - private HttpResponseException listFactorsRequestAndReturnException(TestingProcessManager.TestingProcess process, HashMap params) { - return assertThrows( - HttpResponseException.class, - () -> listFactorsRequest(process, params)); - } - @Test - public void testApi() throws Exception { - TestSetupResult result = initSteps(); - assert result != null; - - MfaStorage storage = result.storage; - Main main = result.process.main; - - // Prepare by enabling a factor for a user: - { - JsonObject body = new JsonObject(); - body.addProperty("userId", "userId"); - body.addProperty("factor", "f1"); - enableFactorRequest(result.process, body); - } - - HashMap params = new HashMap<>(); - - // Missing userId - { - Exception e = listFactorsRequestAndReturnException(result.process, params); - checkResponseErrorContains(e, "Field name 'userId' is missing in GET request"); - } - // Invalid userId - { - params.put("userId", ""); - Exception e = listFactorsRequestAndReturnException(result.process, params); - checkResponseErrorContains(e, "userId cannot be empty"); - } - - params.put("userId", "userId"); - JsonObject res = listFactorsRequest(result.process, params); - assert res.get("status").getAsString().equals("OK"); - - JsonArray factors = res.get("factors").getAsJsonArray(); - String factor = factors.get(0).getAsString(); - - assert factors.size() == 1; - assert factor.equals("f1"); - - // Try for a non-existing user: - { - params.put("userId", "userId2"); - res = listFactorsRequest(result.process, params); - assert res.get("status").getAsString().equals("OK"); - - factors = res.get("factors").getAsJsonArray(); - assert factors.size() == 0; - } - } -} diff --git a/src/test/java/io/supertokens/test/mfa/api/MfaUserIdMappingTest.java b/src/test/java/io/supertokens/test/mfa/api/MfaUserIdMappingTest.java deleted file mode 100644 index ec60ff654..000000000 --- a/src/test/java/io/supertokens/test/mfa/api/MfaUserIdMappingTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.test.mfa.api; - -import com.google.gson.JsonObject; -import io.supertokens.Main; -import io.supertokens.emailpassword.EmailPassword; -import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; -import io.supertokens.test.mfa.MfaTestBase; -import io.supertokens.useridmapping.UserIdMapping; -import org.junit.Test; - -import java.util.HashMap; - -public class MfaUserIdMappingTest extends MfaTestBase { - @Test - public void testExternalUserIdTranslation() throws Exception { - TestSetupResult result = initSteps(true); - Main main = result.process.getProcess(); - - JsonObject body = new JsonObject(); - AuthRecipeUserInfo user = EmailPassword.signUp(main, "test@example.com", "testPass123"); - String superTokensUserId = user.getSupertokensUserId(); - String externalUserId = "external-user-id"; - - // Create user id mapping first: - UserIdMapping.createUserIdMapping(main, superTokensUserId, externalUserId, null, false); - - body.addProperty("userId", superTokensUserId); - body.addProperty("factor", "f1"); - - // Enable factor f1 for user (use superTokensUserId for this): - JsonObject res = enableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == false; - - // Now use external user for all requests instead of superTokensUserId: - body.addProperty("userId", externalUserId); - - // Enable factor f2 for user: - body.addProperty("factor", "f2"); - res = enableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == false; - - // List factors for user: - HashMap params = new HashMap<>(); - params.put("userId", externalUserId); - res = listFactorsRequest(result.process, params); - assert res.get("status").getAsString().equals("OK"); - assert res.get("factors").getAsJsonArray().size() == 2; - assert res.get("factors").getAsJsonArray().get(0).getAsString().equals("f1"); - assert res.get("factors").getAsJsonArray().get(1).getAsString().equals("f2"); - - // Disable factor f1 for user: - body.addProperty("factor", "f1"); - res = disableFactorRequest(result.process, body); - assert res.get("status").getAsString().equals("OK"); - assert res.get("didExist").getAsBoolean() == true; - - // List factors for user: - res = listFactorsRequest(result.process, params); - assert res.get("status").getAsString().equals("OK"); - assert res.get("factors").getAsJsonArray().size() == 1; - assert res.get("factors").getAsJsonArray().get(0).getAsString().equals("f2"); - } -} diff --git a/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java b/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java index e1c7f9e0c..4203b8778 100644 --- a/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java +++ b/src/test/java/io/supertokens/test/multitenant/AppTenantUserTest.java @@ -66,7 +66,7 @@ public void testDeletingAppDeleteNonAuthRecipeData() throws Exception { TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); FeatureFlagTestContent.getInstance(process.getProcess()) .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ - EE_FEATURES.MULTI_TENANCY, EE_FEATURES.TOTP}); + EE_FEATURES.MULTI_TENANCY, EE_FEATURES.MFA}); process.startProcess(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -171,7 +171,7 @@ public void testDisassociationOfUserDeletesNonAuthRecipeData() throws Exception TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); FeatureFlagTestContent.getInstance(process.getProcess()) .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ - EE_FEATURES.MULTI_TENANCY, EE_FEATURES.TOTP}); + EE_FEATURES.MULTI_TENANCY, EE_FEATURES.MFA}); process.startProcess(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -258,7 +258,7 @@ public void deletingTenantKeepsTheUserInTheApp() throws Exception { TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); FeatureFlagTestContent.getInstance(process.getProcess()) .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ - EE_FEATURES.MULTI_TENANCY, EE_FEATURES.TOTP}); + EE_FEATURES.MULTI_TENANCY, EE_FEATURES.MFA}); process.startProcess(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); diff --git a/src/test/java/io/supertokens/test/multitenant/TestAppData.java b/src/test/java/io/supertokens/test/multitenant/TestAppData.java index 225df2491..cf69c38f9 100644 --- a/src/test/java/io/supertokens/test/multitenant/TestAppData.java +++ b/src/test/java/io/supertokens/test/multitenant/TestAppData.java @@ -96,7 +96,7 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { TestingProcessManager.TestingProcess process = TestingProcessManager.start(args, false); FeatureFlagTestContent.getInstance(process.getProcess()) .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, - new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY, EE_FEATURES.TOTP, EE_FEATURES.MFA}); + new EE_FEATURES[]{EE_FEATURES.MULTI_TENANCY, EE_FEATURES.MFA}); process.startProcess(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); @@ -167,9 +167,6 @@ public void testThatDeletingAppDeleteDataFromAllTables() throws Exception { UserIdMapping.createUserIdMapping(process.getProcess(), appWithStorage.toAppIdentifierWithStorage(), plUser.user.getSupertokensUserId(), "externalid", null, false); - Mfa.enableFactor(appWithStorage, process.getProcess(), - epUser.getSupertokensUserId(), "emailpassword"); - String[] tablesThatHaveData = appWithStorage.getStorage() .getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); tablesThatHaveData = removeStrings(tablesThatHaveData, tablesToIgnore); diff --git a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java index 9c86c127e..0b2dcc3a7 100644 --- a/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java +++ b/src/test/java/io/supertokens/test/multitenant/api/TestTenantUserAssociation.java @@ -197,8 +197,9 @@ public void testUserDisassociationForNotAuthRecipes() throws Exception { } if (name.equals(UserMetadataStorage.class.getName()) - || name.equals(JWTRecipeStorage.class.getName()) || - name.equals(ActiveUsersStorage.class.getName())) { + || name.equals(JWTRecipeStorage.class.getName()) + || name.equals(ActiveUsersStorage.class.getName()) + ) { // user metadata is app specific and does not have any tenant specific data // JWT storage does not have any user specific data // Active users storage does not have tenant specific data diff --git a/src/test/java/io/supertokens/test/totp/TOTPRecipeTest.java b/src/test/java/io/supertokens/test/totp/TOTPRecipeTest.java index 0b589bec9..f926d2267 100644 --- a/src/test/java/io/supertokens/test/totp/TOTPRecipeTest.java +++ b/src/test/java/io/supertokens/test/totp/TOTPRecipeTest.java @@ -98,7 +98,7 @@ public TestSetupResult defaultInit() TOTPStorage storage = (TOTPStorage) StorageLayer.getStorage(process.getProcess()); FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); return new TestSetupResult(storage, process); } @@ -325,7 +325,7 @@ public void rateLimitCooldownTest() throws Exception { } FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); Main main = process.getProcess(); diff --git a/src/test/java/io/supertokens/test/totp/TOTPStorageTest.java b/src/test/java/io/supertokens/test/totp/TOTPStorageTest.java index e03169d2a..38297710a 100644 --- a/src/test/java/io/supertokens/test/totp/TOTPStorageTest.java +++ b/src/test/java/io/supertokens/test/totp/TOTPStorageTest.java @@ -68,7 +68,7 @@ public TestSetupResult initSteps() TOTPSQLStorage storage = (TOTPSQLStorage) StorageLayer.getStorage(process.getProcess()); FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); return new TestSetupResult(storage, process); } diff --git a/src/test/java/io/supertokens/test/totp/TotpLicenseTest.java b/src/test/java/io/supertokens/test/totp/TotpLicenseTest.java index d612bd40e..889eb02f6 100644 --- a/src/test/java/io/supertokens/test/totp/TotpLicenseTest.java +++ b/src/test/java/io/supertokens/test/totp/TotpLicenseTest.java @@ -42,8 +42,7 @@ import static org.junit.Assert.assertThrows; public class TotpLicenseTest { - public final static String OPAQUE_KEY_WITH_TOTP_FEATURE = "pXhNK=nYiEsb6gJEOYP2kIR6M0kn4XLvNqcwT1XbX8xHtm44K" + - "-lQfGCbaeN0Ieeza39fxkXr=tiiUU=DXxDH40Y=4FLT4CE-rG1ETjkXxO4yucLpJvw3uSegPayoISGL"; + public final static String OPAQUE_KEY_WITH_MFA_FEATURE = "Qk8olVa=v-9PU=snnUFMF4ihMCx4zVBOO6Jd7Nrg6Cg5YyFliEj252ADgpwEpDLfFowA0U5OyVo3XL=U4FMft2HDHCDGg9hWD4iwQQiyjMRi6Mu03CVbAxIkNGaXtJ53"; @Rule public TestRule watchman = Utils.getOnFailure(); @@ -126,7 +125,7 @@ public void testTotpWithoutLicense() throws Exception { } ); assert e.statusCode == 402; - assert e.getMessage().contains("TOTP feature is not enabled"); + assert e.getMessage().contains("MFA feature is not enabled"); // Try to verify code via API: @@ -151,7 +150,7 @@ public void testTotpWithoutLicense() throws Exception { } ); assert e2.statusCode == 402; - assert e2.getMessage().contains("TOTP feature is not enabled"); + assert e2.getMessage().contains("MFA feature is not enabled"); } @@ -162,7 +161,7 @@ public void testTotpWithLicense() throws Exception { return; } FeatureFlagTestContent.getInstance(result.process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); Main main = result.process.getProcess(); diff --git a/src/test/java/io/supertokens/test/totp/api/CreateTotpDeviceAPITest.java b/src/test/java/io/supertokens/test/totp/api/CreateTotpDeviceAPITest.java index 4aa922e2d..17e6fe29e 100644 --- a/src/test/java/io/supertokens/test/totp/api/CreateTotpDeviceAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/CreateTotpDeviceAPITest.java @@ -81,9 +81,9 @@ public void testApi() throws Exception { } FeatureFlag.getInstance(process.main) - .setLicenseKeyAndSyncFeatures(TotpLicenseTest.OPAQUE_KEY_WITH_TOTP_FEATURE); + .setLicenseKeyAndSyncFeatures(TotpLicenseTest.OPAQUE_KEY_WITH_MFA_FEATURE); FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { return; diff --git a/src/test/java/io/supertokens/test/totp/api/GetTotpDevicesAPITest.java b/src/test/java/io/supertokens/test/totp/api/GetTotpDevicesAPITest.java index 0ea0f8387..e48ba2b29 100644 --- a/src/test/java/io/supertokens/test/totp/api/GetTotpDevicesAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/GetTotpDevicesAPITest.java @@ -77,7 +77,7 @@ public void testApi() throws Exception { TestingProcessManager.TestingProcess process = TestingProcessManager.start(args); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); - FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.TOTP }); + FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.MFA }); if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) { return; diff --git a/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java b/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java index df8cac9fb..51c3549c2 100644 --- a/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/MultitenantAPITest.java @@ -75,7 +75,7 @@ public void beforeEach() throws InterruptedException, InvalidProviderConfigExcep this.process = TestingProcessManager.start(args); FeatureFlagTestContent.getInstance(process.getProcess()) .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{ - EE_FEATURES.MULTI_TENANCY, EE_FEATURES.TOTP}); + EE_FEATURES.MULTI_TENANCY, EE_FEATURES.MFA}); process.startProcess(); assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED)); diff --git a/src/test/java/io/supertokens/test/totp/api/RemoveTotpDeviceAPITest.java b/src/test/java/io/supertokens/test/totp/api/RemoveTotpDeviceAPITest.java index bb4a13a53..aa92e4ad0 100644 --- a/src/test/java/io/supertokens/test/totp/api/RemoveTotpDeviceAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/RemoveTotpDeviceAPITest.java @@ -78,7 +78,7 @@ public void testApi() throws Exception { } FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); // Setup user and devices: JsonObject createDeviceReq = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java b/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java index 112cd0c14..f3b0d0ad6 100644 --- a/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java +++ b/src/test/java/io/supertokens/test/totp/api/TotpUserIdMappingTest.java @@ -48,7 +48,7 @@ public void testExternalUserIdTranslation() throws Exception { return; } - FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.TOTP }); + FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.MFA }); JsonObject body = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/totp/api/UpdateTotpDeviceAPITest.java b/src/test/java/io/supertokens/test/totp/api/UpdateTotpDeviceAPITest.java index 29be8c12c..27c5f9fea 100644 --- a/src/test/java/io/supertokens/test/totp/api/UpdateTotpDeviceAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/UpdateTotpDeviceAPITest.java @@ -76,7 +76,7 @@ public void testApi() throws Exception { return; } - FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.TOTP }); + FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.MFA }); // Setup user and devices: JsonObject createDeviceReq = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/totp/api/VerifyTotpAPITest.java b/src/test/java/io/supertokens/test/totp/api/VerifyTotpAPITest.java index 08c836586..a17eee38b 100644 --- a/src/test/java/io/supertokens/test/totp/api/VerifyTotpAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/VerifyTotpAPITest.java @@ -88,7 +88,7 @@ public void testApi() throws Exception { } FeatureFlagTestContent.getInstance(process.main) - .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.TOTP}); + .setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[]{EE_FEATURES.MFA}); // Setup user and devices: JsonObject createDeviceReq = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/totp/api/VerifyTotpDeviceAPITest.java b/src/test/java/io/supertokens/test/totp/api/VerifyTotpDeviceAPITest.java index ca5e1c43b..b29f187fe 100644 --- a/src/test/java/io/supertokens/test/totp/api/VerifyTotpDeviceAPITest.java +++ b/src/test/java/io/supertokens/test/totp/api/VerifyTotpDeviceAPITest.java @@ -84,7 +84,7 @@ public void testApi() throws Exception { return; } - FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.TOTP }); + FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.MFA }); // Setup user and devices: JsonObject createDeviceReq = new JsonObject(); diff --git a/src/test/java/io/supertokens/test/userIdMapping/UserIdMappingTest.java b/src/test/java/io/supertokens/test/userIdMapping/UserIdMappingTest.java index 9a6cfb33a..cfc9e6db2 100644 --- a/src/test/java/io/supertokens/test/userIdMapping/UserIdMappingTest.java +++ b/src/test/java/io/supertokens/test/userIdMapping/UserIdMappingTest.java @@ -791,7 +791,7 @@ public void checkThatCreateUserIdMappingHasAllNonAuthRecipeChecks() throws Excep return; } - FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.TOTP }); + FeatureFlagTestContent.getInstance(process.main).setKeyValue(FeatureFlagTestContent.ENABLED_FEATURES, new EE_FEATURES[] { EE_FEATURES.MFA }); // this list contains the package names for recipes which dont use UserIdMapping ArrayList nonAuthRecipesWhichDontNeedUserIdMapping = new ArrayList<>(