Skip to content

Commit

Permalink
refactor: Replace TOTP_NOT_ENABLED_ERROR status and make deviceName o…
Browse files Browse the repository at this point in the history
…ptional (#729)

* refactor: Dont send TOTP_NOT_ENABLED_ERROR status

* refactor: Add comments

* chores: Remove extra comments

* refactor: Completely replace totp not enabled error with unknown device error

* refactor: Remove Totp not enabled error

* feat: Make device name optional and generate it from number of existing devices

* Replace TotpNotEnabledError with UnknownUserIdTotpError

* refactor: Recursively generate device name when it already exists

* refactor: Remove redundant arguments

* feat: Remove the param to allow unverified devices from the verify totp API

* feat: Reject unverified devices

* feat: Add UNKNOWN_USER_ID_ERROR to verify totp api

* feat: Throw Unknown user id error when device gets deleted during verification

* fix: core fixes

* fix: cleanup

* fix: tests

---------

Co-authored-by: Sattvik Chakravarthy <[email protected]>
  • Loading branch information
KShivendu and sattvikc authored Sep 28, 2023
1 parent 49b6a51 commit 0387df7
Show file tree
Hide file tree
Showing 22 changed files with 431 additions and 250 deletions.
51 changes: 31 additions & 20 deletions src/main/java/io/supertokens/inmemorydb/Start.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
import io.supertokens.pluginInterface.totp.TOTPStorage;
import io.supertokens.pluginInterface.totp.TOTPUsedCode;
import io.supertokens.pluginInterface.totp.exception.DeviceAlreadyExistsException;
import io.supertokens.pluginInterface.totp.exception.TotpNotEnabledException;
import io.supertokens.pluginInterface.totp.exception.UnknownDeviceException;
import io.supertokens.pluginInterface.totp.exception.UnknownTotpUserIdException;
import io.supertokens.pluginInterface.totp.exception.UsedCodeAlreadyExistsException;
import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage;
import io.supertokens.pluginInterface.useridmapping.UserIdMapping;
Expand Down Expand Up @@ -2601,29 +2601,40 @@ public void revokeExpiredSessions() throws StorageQueryException {
// TOTP recipe:
@Override
public void createDevice(AppIdentifier appIdentifier, TOTPDevice device)
throws StorageQueryException, DeviceAlreadyExistsException, TenantOrAppNotFoundException {
throws DeviceAlreadyExistsException, TenantOrAppNotFoundException, StorageQueryException {
try {
TOTPQueries.createDevice(this, appIdentifier, device);
} catch (StorageTransactionLogicException e) {
if (e.actualException instanceof SQLiteException) {
String errMsg = e.actualException.getMessage();

if (isPrimaryKeyError(errMsg, Config.getConfig(this).getTotpUserDevicesTable(),
new String[]{"app_id", "user_id", "device_name"})) {
throw new DeviceAlreadyExistsException();
} else if (isForeignKeyConstraintError(
errMsg,
Config.getConfig(this).getAppsTable(),
new String[]{"app_id"},
new Object[]{appIdentifier.getAppId()})) {
throw new TenantOrAppNotFoundException(appIdentifier);
startTransaction(con -> {
try {
createDevice_Transaction(con, new AppIdentifier(null, null), device);
} catch (DeviceAlreadyExistsException | TenantOrAppNotFoundException e) {
throw new StorageTransactionLogicException(e);
}
return null;
});
} catch (StorageTransactionLogicException e) {
if (e.actualException instanceof DeviceAlreadyExistsException) {
throw (DeviceAlreadyExistsException) e.actualException;
} else if (e.actualException instanceof TenantOrAppNotFoundException) {
throw (TenantOrAppNotFoundException) e.actualException;
} else if (e.actualException instanceof StorageQueryException) {
throw (StorageQueryException) e.actualException;
}

throw new StorageQueryException(e.actualException);
}
}

@Override
public TOTPDevice createDevice_Transaction(TransactionConnection con, AppIdentifier appIdentifier, TOTPDevice device)
throws DeviceAlreadyExistsException, TenantOrAppNotFoundException, StorageQueryException {
// TODO
return null;
}

@Override
public TOTPDevice getDeviceByName_Transaction(TransactionConnection con, AppIdentifier appIdentifier, String userId, String deviceName) throws StorageQueryException {
// TODO
return null;
}

@Override
public void markDeviceAsVerified(AppIdentifier appIdentifier, String userId, String deviceName)
throws StorageQueryException, UnknownDeviceException {
Expand Down Expand Up @@ -2717,7 +2728,7 @@ public TOTPDevice[] getDevices_Transaction(TransactionConnection con, AppIdentif
@Override
public void insertUsedCode_Transaction(TransactionConnection con, TenantIdentifier tenantIdentifier,
TOTPUsedCode usedCodeObj)
throws StorageQueryException, TotpNotEnabledException, UsedCodeAlreadyExistsException,
throws StorageQueryException, UnknownTotpUserIdException, UsedCodeAlreadyExistsException,
TenantOrAppNotFoundException {
Connection sqlCon = (Connection) con.getConnection();
try {
Expand All @@ -2732,7 +2743,7 @@ public void insertUsedCode_Transaction(TransactionConnection con, TenantIdentifi
Config.getConfig(this).getTotpUsersTable(),
new String[]{"app_id", "user_id"},
new Object[]{tenantIdentifier.getAppId(), usedCodeObj.userId})) {
throw new TotpNotEnabledException();
throw new UnknownTotpUserIdException();

} else if (isForeignKeyConstraintError(
e.getMessage(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ 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";
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());
Expand Down Expand Up @@ -127,7 +127,8 @@ public static int countUsersEnabledMfaAndActiveSince(Start start, AppIdentifier
});
}

public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId) throws SQLException, StorageQueryException {
public static int updateUserLastActive(Start start, AppIdentifier appIdentifier, String userId)
throws SQLException, StorageQueryException {
String QUERY = "INSERT INTO " + Config.getConfig(start).getUserLastActiveTable()
+
"(app_id, user_id, last_active_time) VALUES(?, ?, ?) ON CONFLICT(app_id, user_id) DO UPDATE SET " +
Expand Down
Loading

0 comments on commit 0387df7

Please sign in to comment.