Skip to content

Commit

Permalink
fix: pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
sattvikc committed Jan 23, 2024
1 parent b6bb08d commit 3ad63d3
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 16 deletions.
9 changes: 6 additions & 3 deletions src/main/java/io/supertokens/passwordless/Passwordless.java
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant
}
}

return new ConsumeCodeResponse(true, user, consumedDevice.email, consumedDevice.phoneNumber);
return new ConsumeCodeResponse(true, user, consumedDevice.email, consumedDevice.phoneNumber, consumedDevice);
} catch (DuplicateEmailException | DuplicatePhoneNumberException e) {
// Getting these would mean that between getting the user and trying creating it:
// 1. the user managed to do a full create+consume flow
Expand Down Expand Up @@ -523,7 +523,7 @@ public static ConsumeCodeResponse consumeCode(TenantIdentifierWithStorage tenant
removeCodesByPhoneNumber(tenantIdentifierWithStorage, loginMethod.phoneNumber);
}
}
return new ConsumeCodeResponse(false, user, consumedDevice.email, consumedDevice.phoneNumber);
return new ConsumeCodeResponse(false, user, consumedDevice.email, consumedDevice.phoneNumber, consumedDevice);
}

@TestOnly
Expand Down Expand Up @@ -870,11 +870,14 @@ public static class ConsumeCodeResponse {
public String email;
public String phoneNumber;

public ConsumeCodeResponse(boolean createdNewUser, @Nullable AuthRecipeUserInfo user, String email, String phoneNumber) {
public PasswordlessDevice consumedDevice;

public ConsumeCodeResponse(boolean createdNewUser, @Nullable AuthRecipeUserInfo user, String email, String phoneNumber, PasswordlessDevice consumedDevice) {
this.createdNewUser = createdNewUser;
this.user = user;
this.email = email;
this.phoneNumber = phoneNumber;
this.consumedDevice = consumedDevice;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,20 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
}
}

String factorId;
if (linkCode != null) {
factorId = "link-";
} else {
factorId = "otp-";
}
if (consumeCodeResponse.email != null) {
factorId += "email";
} else {
factorId += "phone";
if (getVersionFromRequest(req).greaterThanOrEqualTo(SemVer.v5_0)) {
JsonObject jsonDevice = new JsonObject();
jsonDevice.addProperty("preAuthSessionId", consumeCodeResponse.consumedDevice.deviceIdHash);
jsonDevice.addProperty("failedCodeInputAttemptCount", consumeCodeResponse.consumedDevice.failedAttempts);

if (consumeCodeResponse.consumedDevice.email != null) {
jsonDevice.addProperty("email", consumeCodeResponse.consumedDevice.email);
}

if (consumeCodeResponse.consumedDevice.phoneNumber != null) {
jsonDevice.addProperty("phoneNumber", consumeCodeResponse.consumedDevice.phoneNumber);
}

result.add("consumedDevice", jsonDevice);
}

super.sendJsonResponse(200, result, resp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,9 +490,12 @@ public void testConsumeCodeWithoutCreatingUser() throws Exception {
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

assertEquals(1, response.entrySet().size());
assertEquals(2, response.entrySet().size());
assertEquals("OK", response.get("status").getAsString());

JsonObject consumedDevice = response.get("consumedDevice").getAsJsonObject();
assertEquals("[email protected]", consumedDevice.get("email").getAsString());

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

Expand Down Expand Up @@ -784,15 +787,193 @@ public void testBadInputWithoutCreatingUser() throws Exception {
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

@Test
public void testLinkCodeWithoutCreatingUser() throws Exception {
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;
}

long startTs = System.currentTimeMillis();

String email = "[email protected]";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);

JsonObject consumeCodeRequestBody = new JsonObject();
consumeCodeRequestBody.addProperty("preAuthSessionId", createResp.deviceIdHash);
consumeCodeRequestBody.addProperty("linkCode", createResp.linkCode);

JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

checkResponse(response, true, email, null);

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 1);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

@Test
public void testExpiredLinkCodeWithoutCreatingUser() throws Exception {
String[] args = { "../" };

Utils.setValueInConfig("passwordless_code_lifetime", "100");

TestingProcessManager.TestingProcess process = TestingProcessManager.start(args);
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED));

if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
return;
}

long startTs = System.currentTimeMillis();

String email = "[email protected]";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);
Thread.sleep(150);
JsonObject consumeCodeRequestBody = new JsonObject();
consumeCodeRequestBody.addProperty("preAuthSessionId", createResp.deviceIdHash);
consumeCodeRequestBody.addProperty("linkCode", createResp.linkCode);
consumeCodeRequestBody.addProperty("createRecipeUserIfNotExists", false);

JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

assertEquals("RESTART_FLOW_ERROR", response.get("status").getAsString());

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

@Test
public void testExpiredUserInputCodeWithoutCreatingUser() throws Exception {
String[] args = { "../" };

Utils.setValueInConfig("passwordless_code_lifetime", "100");
TestingProcessManager.TestingProcess process = TestingProcessManager.start(args);
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED));

if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
return;
}

long startTs = System.currentTimeMillis();

String email = "[email protected]";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);
Thread.sleep(150);

JsonObject consumeCodeRequestBody = new JsonObject();
consumeCodeRequestBody.addProperty("deviceId", createResp.deviceId);
consumeCodeRequestBody.addProperty("preAuthSessionId", createResp.deviceIdHash);
consumeCodeRequestBody.addProperty("userInputCode", createResp.userInputCode);
consumeCodeRequestBody.addProperty("createRecipeUserIfNotExists", false);

JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

assertEquals("EXPIRED_USER_INPUT_CODE_ERROR", response.get("status").getAsString());

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 0);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

@Test
public void testIncorrectUserInputCodeWithoutCreatingUser() throws Exception {
String[] args = { "../" };

Utils.setValueInConfig("passwordless_max_code_input_attempts", "2"); // Only 2 code entries permitted (1 retry)

TestingProcessManager.TestingProcess process = TestingProcessManager.start(args);
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STARTED));

if (StorageLayer.getStorage(process.getProcess()).getType() != STORAGE_TYPE.SQL) {
return;
}

String email = "[email protected]";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);

JsonObject consumeCodeRequestBody = new JsonObject();
consumeCodeRequestBody.addProperty("deviceId", createResp.deviceId);
consumeCodeRequestBody.addProperty("preAuthSessionId", createResp.deviceIdHash);
consumeCodeRequestBody.addProperty("userInputCode", createResp.userInputCode + "nope");
consumeCodeRequestBody.addProperty("createRecipeUserIfNotExists", false);

{
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

assertEquals("INCORRECT_USER_INPUT_CODE_ERROR", response.get("status").getAsString());
}

{
JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

assertEquals("RESTART_FLOW_ERROR", response.get("status").getAsString());
}
process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

@Test
public void testLinkCodeWithCreateUserSetToTrue() throws Exception {
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;
}

long startTs = System.currentTimeMillis();

String email = "[email protected]";
CreateCodeResponse createResp = Passwordless.createCode(process.getProcess(), email, null, null, null);

JsonObject consumeCodeRequestBody = new JsonObject();
consumeCodeRequestBody.addProperty("preAuthSessionId", createResp.deviceIdHash);
consumeCodeRequestBody.addProperty("linkCode", createResp.linkCode);
consumeCodeRequestBody.addProperty("createRecipeUserIfNotExists", true);

JsonObject response = HttpRequestForTesting.sendJsonPOSTRequest(process.getProcess(), "",
"http://localhost:3567/recipe/signinup/code/consume", consumeCodeRequestBody, 1000, 1000, null,
SemVer.v5_0.get(), "passwordless");

checkResponse(response, true, email, null);

int activeUsers = ActiveUsers.countUsersActiveSince(process.getProcess(), startTs);
assert (activeUsers == 1);

process.kill();
assertNotNull(process.checkOrWaitForEvent(ProcessState.PROCESS_STATE.STOPPED));
}

private void checkResponse(JsonObject response, Boolean isNewUser, String email, String phoneNumber) {
assertEquals("OK", response.get("status").getAsString());
assertEquals(isNewUser, response.get("createdNewUser").getAsBoolean());
assert (response.has("user"));

assertEquals(4, response.entrySet().size());

assertEquals(5, response.entrySet().size());

JsonObject userJson = response.getAsJsonObject("user");
if (email == null) {
Expand All @@ -806,7 +987,17 @@ private void checkResponse(JsonObject response, Boolean isNewUser, String email,
} else if (phoneNumber != null) {
assertEquals(phoneNumber, userJson.get("phoneNumbers").getAsJsonArray().get(0).getAsString());
}

assertEquals(8, userJson.entrySet().size());
assertEquals(response.get("recipeUserId").getAsString(), userJson.get("id").getAsString());

JsonObject consumedDevice = response.getAsJsonObject("consumedDevice");
if (email != null) {
assertEquals(email, consumedDevice.get("email").getAsString());
}

if (phoneNumber != null) {
assertEquals(phoneNumber, consumedDevice.get("phoneNumber").getAsString());
}
}
}

0 comments on commit 3ad63d3

Please sign in to comment.