Skip to content

Commit

Permalink
1. Add voice method to OTP (#106)
Browse files Browse the repository at this point in the history
2. Add templateOptions where relevant
  • Loading branch information
slavikm authored Apr 12, 2024
1 parent 67a0fa5 commit a8fd7cc
Show file tree
Hide file tree
Showing 17 changed files with 263 additions and 9 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ For rate limiting information, please confer to the [API Rate Limits](#api-rate-

### OTP Authentication

Send a user a one-time password (OTP) using your preferred delivery method (_email / SMS_). An email address or phone number must be provided accordingly.
Send a user a one-time password (OTP) using your preferred delivery method (_email / SMS / Voice call / WhatsApp_). An email address or phone number must be provided accordingly.

The user can either `sign up`, `sign in` or `sign up or in`

Expand Down Expand Up @@ -119,7 +119,7 @@ The session and refresh JWTs should be returned to the caller, and passed with e

### Magic Link

Send a user a Magic Link using your preferred delivery method (_email / SMS_).
Send a user a Magic Link using your preferred delivery method (_email / SMS / WhatsApp_).
The Magic Link will redirect the user to page where the its token needs to be verified.
This redirection can be configured in code, or globally in the [Descope Console](https://app.descope.com/settings/authentication/magiclink)

Expand Down Expand Up @@ -1319,7 +1319,7 @@ try (MockedStatic<ApiProxyBuilder> mockedApiProxyBuilder = mockStatic(ApiProxyBu
### Utils for your end to end (e2e) tests and integration tests

To ease your e2e tests, we exposed dedicated management methods.
That way, you don't need to use 3rd party messaging services in order to receive sign-in/up Emails or SMS,
That way, you don't need to use 3rd party messaging services in order to receive sign-in/up Email, SMS, Voice call or WhatsApp,
and avoid the need of parsing the code and token from them.

```java
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/descope/enums/DeliveryMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
public enum DeliveryMethod {
EMAIL("email"),
SMS("sms"),
VOICE("voice"),
WHATSAPP("whatsapp");

@Getter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.descope.model.magiclink.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -19,4 +20,5 @@ public class UpdateEmailRequest {
@JsonProperty("addToLoginIDs")
private boolean addToLoginIds;
private boolean onMergeUseExisting;
private Map<String, String> templateOptions;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.descope.model.magiclink.request;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -19,4 +20,5 @@ public class UpdatePhoneRequest {
@JsonProperty("addToLoginIDs")
private boolean addToLoginIds;
private boolean onMergeUseExisting;
private Map<String, String> templateOptions;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.descope.model.otp;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -16,4 +17,5 @@ public class UpdateEmailRequestBody {
@JsonProperty("addToLoginIDs")
private boolean addToLoginIds;
private boolean onMergeUseExisting;
private Map<String, String> templateOptions;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.descope.model.otp;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -16,4 +17,5 @@ public class UpdatePhoneRequestBody {
@JsonProperty("addToLoginIDs")
private boolean addToLoginIds;
private boolean onMergeUseExisting;
private Map<String, String> templateOptions;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.descope.model.password;

import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -12,4 +13,5 @@
public class AuthenticationPasswordResetRequestBody {
private String loginId;
private String redirectURL;
private Map<String, String> templateOptions;
}
15 changes: 15 additions & 0 deletions src/main/java/com/descope/sdk/auth/EnchantedLinkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.descope.model.magiclink.LoginOptions;
import com.descope.model.magiclink.SignUpOptions;
import com.descope.model.user.User;
import java.util.Map;

public interface EnchantedLinkService {
/**
Expand Down Expand Up @@ -94,4 +95,18 @@ EnchantedLinkResponse signUpOrIn(String loginId, String uri)
EnchantedLinkResponse updateUserEmail(String loginId, String email, String uri, String refreshToken,
UpdateOptions updateOptions) throws DescopeException;

/**
* Use to update email and validate via enchanted link.
*
* @param loginId - User login ID
* @param email - User email
* @param uri - Base URI
* @param refreshToken - refresh token to perform the update
* @param updateOptions - update options for the update
* @return {@link EnchantedLinkResponse} including masked address where the link was sent (email),
* link to chose and link to retrieve new session from
* @throws DescopeException - error upon failure
*/
EnchantedLinkResponse updateUserEmail(String loginId, String email, String uri, String refreshToken,
UpdateOptions updateOptions, Map<String, String> templateOptions) throws DescopeException;
}
35 changes: 35 additions & 0 deletions src/main/java/com/descope/sdk/auth/MagicLinkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.descope.model.magiclink.LoginOptions;
import com.descope.model.magiclink.SignUpOptions;
import com.descope.model.user.User;
import java.util.Map;

public interface MagicLinkService {

Expand Down Expand Up @@ -99,6 +100,22 @@ String signUpOrIn(DeliveryMethod deliveryMethod, String loginId, String uri)
String updateUserEmail(String loginId, String email, String uri, String refreshToken, UpdateOptions updateOptions)
throws DescopeException;

/**
* Use to update email and validate via magiclink.
*
* @param loginId - User login ID
* @param email - User email
* @param uri - Base URI
* @param refreshToken - refresh token to perform the update
* @param updateOptions - update options for the update
* @param templateOptions - optional parameters for template
* @return masked address where the link was sent (email)
* @throws DescopeException - error upon failure
*/
String updateUserEmail(String loginId, String email, String uri, String refreshToken, UpdateOptions updateOptions,
Map<String, String> templateOptions)
throws DescopeException;

/**
* Use to update phone and validate via magiclink. Allowed methods are phone based methods -
* whatsapp and SMS
Expand All @@ -115,4 +132,22 @@ String updateUserEmail(String loginId, String email, String uri, String refreshT
String updateUserPhone(
DeliveryMethod deliveryMethod, String loginId, String phone, String uri, String refreshToken,
UpdateOptions updateOptions) throws DescopeException;

/**
* Use to update phone and validate via magiclink. Allowed methods are phone based methods -
* whatsapp and SMS
*
* @param deliveryMethod - {@link com.descope.enums.DeliveryMethod DeliveryMethod}
* @param loginId - User login ID
* @param phone - User phone
* @param uri - Base URI
* @param refreshToken - refresh token to perform the update
* @param updateOptions - update options for the update
* @param templateOptions - optional parameters for template
* @return masked address where the link was sent (whatsapp or sms)
* @throws DescopeException - error upon failure
*/
String updateUserPhone(
DeliveryMethod deliveryMethod, String loginId, String phone, String uri, String refreshToken,
UpdateOptions updateOptions, Map<String, String> templateOptions) throws DescopeException;
}
31 changes: 31 additions & 0 deletions src/main/java/com/descope/sdk/auth/OTPService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.descope.model.magiclink.LoginOptions;
import com.descope.model.magiclink.SignUpOptions;
import com.descope.model.user.User;
import java.util.Map;

public interface OTPService {
/**
Expand Down Expand Up @@ -99,6 +100,21 @@ AuthenticationInfo verifyCode(DeliveryMethod deliveryMethod, String loginId, Str
String updateUserEmail(String loginId, String email, String refreshToken, UpdateOptions updateOptions)
throws DescopeException;

/**
* Use to a update email, and verify via OTP.
*
* @param loginId - User login ID
* @param email - User email
* @param refreshToken - refresh token to perform the update
* @param updateOptions - update options for the update
* @param templateOptions - optional parameters for template
* @return - masked address where the link was sent (email or phone)
* @throws DescopeException - error upon failure
*/
String updateUserEmail(String loginId, String email, String refreshToken, UpdateOptions updateOptions,
Map<String, String> templateOptions)
throws DescopeException;

/**
* Use to update phone and validate via OTP.
*
Expand All @@ -112,4 +128,19 @@ String updateUserEmail(String loginId, String email, String refreshToken, Update
*/
String updateUserPhone(DeliveryMethod deliveryMethod, String loginId, String phone, String refreshToken,
UpdateOptions updateOptions) throws DescopeException;

/**
* Use to update phone and validate via OTP.
*
* @param deliveryMethod - {@link com.descope.enums.DeliveryMethod DeliveryMethod}
* @param loginId - User login ID
* @param phone - User Phone
* @param refreshToken - refresh token to perform the update
* @param updateOptions - update options for the update
* @param templateOptions - optional parameters for template
* @return - masked address where the link was sent (email or phone)
* @throws DescopeException - error upon failure
*/
String updateUserPhone(DeliveryMethod deliveryMethod, String loginId, String phone, String refreshToken,
UpdateOptions updateOptions, Map<String, String> templateOptions) throws DescopeException;
}
76 changes: 76 additions & 0 deletions src/main/java/com/descope/sdk/auth/PasswordService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,96 @@
import com.descope.model.auth.AuthenticationInfo;
import com.descope.model.password.PasswordPolicy;
import com.descope.model.user.User;
import java.util.Map;

public interface PasswordService {

/**
* Use to create a new user that authenticates with a password.
*
* @param loginId - new user login ID
* @param user - new user details
* @param password - new user cleartext password
* @return {@link AuthenticationInfo} the authentication info created from the sign up
* @throws DescopeException - error upon failure
*/
AuthenticationInfo signUp(String loginId, User user, String password) throws DescopeException;

/**
* Use to login a user by authenticating with a password.
*
* @param loginId - the user login ID
* @param password - the cleartext password for the user
* @return {@link AuthenticationInfo} the authentication info created from the sign in
* @throws DescopeException - error upon failure
*/
AuthenticationInfo signIn(String loginId, String password) throws DescopeException;

/**
* Sends a password reset prompt to the user with the given login ID according to the password settings
* defined in the Descope console.
* The user must be verified according to the configured password reset method.
* Once verified, use UpdateUserPassword to change the user's password.
*
* @param loginId - the user login ID
* @param redirectURL - an optional parameter that is used by Magic Link or Enchanted Link if those are the chosen
* reset methods. See the Magic Link and Enchanted Link sections for more details.
* @throws DescopeException - error upon failure
*/
void sendPasswordReset(String loginId, String redirectURL) throws DescopeException;

/**
* Sends a password reset prompt to the user with the given login ID according to the password settings
* defined in the Descope console.
* The user must be verified according to the configured password reset method.
* Once verified, use UpdateUserPassword to change the user's password.
*
* @param loginId - the user login ID
* @param redirectURL - an optional parameter that is used by Magic Link or Enchanted Link if those are the chosen
* reset methods. See the Magic Link and Enchanted Link sections for more details.
* @param templateOptions - used to pass dynamic options for the messaging (Email / SMS / Voice call / WhatsApp)
* template
* @throws DescopeException - error upon failure
*/
void sendPasswordReset(String loginId, String redirectURL, Map<String, String> templateOptions)
throws DescopeException;

/**
* Updates a user's password according to the given login ID.
* This function requires the user to have an active session.
*
* @param loginId - the user login ID
* @param newPassword - the new cleartext password that must conform to the password policy defined
* in the password settings in the Descope console.
* @param refreshToken - a valid refresh token
* @throws DescopeException - error upon failure
*/
void updateUserPassword(String loginId, String newPassword, String refreshToken)
throws DescopeException;

/**
* Updates a user's password according to the given login ID.
* This function requires the current or 'oldPassword' to be active.
* If the user can be successfully authenticated using the oldPassword, the user's
* password will be updated to newPassword.
*
* @param loginId - the user login ID
* @param oldPassword - the old valid password for the user
* @param newPassword - the new cleartext password that must conform to the password policy defined
* in the password settings in the Descope console.
* @return {@link AuthenticationInfo} the authentication info created from the sign in with the new password
* @throws DescopeException - error upon failure
*/
AuthenticationInfo replaceUserPassword(String loginId, String oldPassword, String newPassword)
throws DescopeException;

/**
* Fetch the rules for valid passwords configured in the policy in the Descope console.
* This can be used to implement client-side validation of new user passwords for a better user experience.
* Either way, the comprehensive policy is always enforced by Descope on the server side.
*
* @return {@link PasswordPolicy} the passwird policy for the project
* @throws DescopeException - error upon failure
*/
PasswordPolicy getPasswordPolicy() throws DescopeException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void verifyDeliveryMethod(DeliveryMethod deliveryMethod, String loginId, User us

switch (deliveryMethod) {
case SMS:
case VOICE:
case WHATSAPP:
String phone = user.getPhone();
if (StringUtils.isBlank(phone)) {
Expand Down Expand Up @@ -87,6 +88,7 @@ void verifyDeliveryMethod(DeliveryMethod deliveryMethod, String loginId, User us
Class<? extends Masked> getMaskedValue(DeliveryMethod deliveryMethod) {
switch (deliveryMethod) {
case SMS:
case VOICE:
case WHATSAPP:
return MaskedPhoneRes.class;
case EMAIL:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.descope.sdk.auth.EnchantedLinkService;
import com.descope.utils.JwtUtils;
import java.net.URI;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;

class EnchantedLinkServiceImpl extends AuthenticationServiceImpl implements EnchantedLinkService {
Expand Down Expand Up @@ -117,6 +118,12 @@ public void verify(String token) throws DescopeException {
@Override
public EnchantedLinkResponse updateUserEmail(String loginId, String email, String uri, String refreshToken,
UpdateOptions updateOptions) throws DescopeException {
return updateUserEmail(loginId, email, uri, refreshToken, updateOptions, null);
}

@Override
public EnchantedLinkResponse updateUserEmail(String loginId, String email, String uri, String refreshToken,
UpdateOptions updateOptions, Map<String, String> templateOptions) throws DescopeException {
if (StringUtils.isBlank(loginId)) {
throw ServerCommonException.invalidArgument("Login ID");
}
Expand All @@ -138,6 +145,7 @@ public EnchantedLinkResponse updateUserEmail(String loginId, String email, Strin
.crossDevice(false)
.addToLoginIds(updateOptions.isAddToLoginIds())
.onMergeUseExisting(updateOptions.isOnMergeUseExisting())
.templateOptions(templateOptions)
.build();

ApiProxy apiProxy = getApiProxy(refreshToken);
Expand Down
Loading

0 comments on commit a8fd7cc

Please sign in to comment.