Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/voice dedicated start verification functions #37

Merged
merged 8 commits into from
Feb 1, 2024
18 changes: 16 additions & 2 deletions src/Sinch/Verification/Common/Identity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,33 @@ namespace Sinch.Verification.Common
{
public class Identity
{
/// <summary>
/// Creates an Identity with phone number.
/// </summary>
/// <param name="phoneNumber">an E.164-compatible phone number</param>
/// <returns></returns>
public static Identity Number(string phoneNumber)
{
return new Identity()
{
Type = IdentityType.Number,
Endpoint = phoneNumber
};
}

/// <summary>
/// Currently only number type is supported.
/// </summary>
[JsonPropertyName("type")]
public IdentityType Type { get; set; }

/// <summary>
/// For type number use an E.164-compatible phone number.
/// </summary>
[JsonPropertyName("endpoint")]
public string Endpoint { get; set; }
}

[JsonConverter(typeof(EnumRecordJsonConverter<IdentityType>))]
public record IdentityType(string Value) : EnumRecord(Value)
{
Expand Down
135 changes: 122 additions & 13 deletions src/Sinch/Verification/SinchVerification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using Sinch.Core;
using Sinch.Logger;
using Sinch.Verification.Common;
using Sinch.Verification.Report.Request;
using Sinch.Verification.Report.Response;
using Sinch.Verification.Start.Request;
Expand All @@ -14,13 +15,52 @@ namespace Sinch.Verification
public interface ISinchVerification
{
/// <summary>
/// This method is used by the mobile and web Verification SDKs to start a verification.
/// It can also be used to request a verification from your backend, by making an request.
/// Starts an SMS Verification. Verification by SMS message with a PIN code.
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<IVerificationStartResponse> Start(VerificationStartRequest request,
Task<StartSmsVerificationResponse> StartSms(StartSmsVerificationRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Starts an SMS Verification for the specified E.164-compatible phone number. Verification by SMS message with a PIN
/// code.
/// </summary>
/// <param name="phoneNumber">A E.164-compatible phone number</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<StartSmsVerificationResponse> StartSms(string phoneNumber,
CancellationToken cancellationToken = default);

/// <summary>
/// Starts a Flash Call verification. Verification by placing a flashcall (missed call) and detecting the incoming
/// calling number (CLI).
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<StartFlashCallVerificationResponse> StartFlashCall(StartFlashCallVerificationRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Starts a Phone Call verification.Verification by placing a PSTN call to the user's phone and playing an
/// announcement, asking the user to press a particular digit to verify the phone number
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<StartPhoneCallVerificationResponse> StartPhoneCall(StartPhoneCallVerificationRequest request,
CancellationToken cancellationToken = default);

/// <summary>
/// Starts a Data verification. Verification by accessing internal infrastructure of mobile carriers to verify if given
/// verification attempt was originated from device with matching phone number.
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<StartDataVerificationResponse> StartSeamless(StartDataVerificationRequest request,
CancellationToken cancellationToken = default);

/// <summary>
Expand All @@ -37,7 +77,7 @@ Task<IVerificationReportResponse> ReportIdentity(string endpoint, VerifyReportRe
CancellationToken cancellationToken = default);

/// <summary>
/// Report the received verification code to verify it, using the Verification ID of the Verification request.
/// Report the received verification code to verify it, using the Verification ID of the Verification request.
/// </summary>
/// <param name="id"></param>
/// <param name="request"></param>
Expand All @@ -49,9 +89,9 @@ Task<IVerificationReportResponse> ReportId(string id, VerifyReportRequest reques

internal class SinchVerification : ISinchVerification
{
private readonly ILoggerAdapter<SinchVerification> _logger;
private readonly Uri _baseAddress;
private readonly IHttp _http;
private readonly ILoggerAdapter<SinchVerification> _logger;

public SinchVerification(ILoggerAdapter<SinchVerification> logger, Uri baseAddress, IHttp http)
{
Expand All @@ -60,16 +100,85 @@ public SinchVerification(ILoggerAdapter<SinchVerification> logger, Uri baseAddre
_http = http;
}

/// <inheritdoc />
public Task<IVerificationStartResponse> Start(VerificationStartRequest request,
private Task<IStartVerificationResponse> Start(StartVerificationRequest request,
CancellationToken cancellationToken = default)
{
var uri = new Uri(_baseAddress, $"verification/v1/verifications");
var uri = new Uri(_baseAddress, "verification/v1/verifications");
_logger?.LogDebug("Starting verification...");
return _http.Send<VerificationStartRequest, IVerificationStartResponse>(uri, HttpMethod.Post, request,
cancellationToken: cancellationToken);
return _http.Send<StartVerificationRequest, IStartVerificationResponse>(uri, HttpMethod.Post, request,
cancellationToken);
}

/// <inheritdoc />
public async Task<StartSmsVerificationResponse> StartSms(StartSmsVerificationRequest request,
CancellationToken cancellationToken = default)
{
var result = await Start(new StartVerificationRequest
{
Custom = request.Custom,
Identity = request.Identity,
Method = request.Method,
Reference = request.Reference
}, cancellationToken);
return result as StartSmsVerificationResponse;
}

/// <inheritdoc />
public async Task<StartSmsVerificationResponse> StartSms(string phoneNumber,
CancellationToken cancellationToken = default)
{
var result = await Start(new StartVerificationRequest
{
Identity = Identity.Number(phoneNumber),
Method = VerificationMethodEx.Sms
}, cancellationToken);
return result as StartSmsVerificationResponse;
}

/// <inheritdoc />
public async Task<StartFlashCallVerificationResponse> StartFlashCall(StartFlashCallVerificationRequest request,
CancellationToken cancellationToken = default)
{
var result = await Start(new StartVerificationRequest
{
Custom = request.Custom,
Identity = request.Identity,
Method = request.Method,
Reference = request.Reference,
FlashCallOptions = request.FlashCallOptions
}, cancellationToken);
return result as StartFlashCallVerificationResponse;
}

/// <inheritdoc />
public async Task<StartPhoneCallVerificationResponse> StartPhoneCall(StartPhoneCallVerificationRequest request,
CancellationToken cancellationToken = default)
{
var result = await Start(new StartVerificationRequest
{
Custom = request.Custom,
Identity = request.Identity,
Method = request.Method,
Reference = request.Reference
}, cancellationToken);
return result as StartPhoneCallVerificationResponse;
}

/// <inheritdoc />
public async Task<StartDataVerificationResponse> StartSeamless(StartDataVerificationRequest request,
CancellationToken cancellationToken = default)
{
var result = await Start(new StartVerificationRequest
{
Custom = request.Custom,
Identity = request.Identity,
Method = request.Method,
Reference = request.Reference
}, cancellationToken);
return result as StartDataVerificationResponse;
}


public Task<IVerificationReportResponse> ReportIdentity(string endpoint, VerifyReportRequest request,
CancellationToken cancellationToken = default)
{
Expand All @@ -96,16 +205,16 @@ private Task<IVerificationReportResponse> Report(VerifyReportRequest request,
FlashCallVerificationReportRequest flashCallVerificationReportRequest =>
_http.Send<FlashCallVerificationReportRequest, IVerificationReportResponse>(uri, HttpMethod.Put,
flashCallVerificationReportRequest,
cancellationToken: cancellationToken),
cancellationToken),
SmsVerificationReportRequest smsVerificationRequest => _http
.Send<SmsVerificationReportRequest, IVerificationReportResponse>(
uri, HttpMethod.Put,
smsVerificationRequest,
cancellationToken: cancellationToken),
cancellationToken),
PhoneCallVerificationReportRequest phoneRequest => _http
.Send<PhoneCallVerificationReportRequest, IVerificationReportResponse>(uri, HttpMethod.Put,
phoneRequest,
cancellationToken: cancellationToken),
cancellationToken),
_ => throw new ArgumentOutOfRangeException(nameof(request))
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
using Sinch.Verification.Common;

namespace Sinch.Verification.Start.Request
{
public class StartDataVerificationRequest : StartVerificationRequestBase
{
/// <summary>
/// The type of the verification request. Set to Seamless
/// </summary>
[JsonInclude]
public override VerificationMethodEx Method { get; } = VerificationMethodEx.Seamless;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Text.Json.Serialization;
using Sinch.Verification.Common;

namespace Sinch.Verification.Start.Request
{
public class StartFlashCallVerificationRequest : StartVerificationRequestBase
{
/// <summary>
/// The type of the verification request. Set to SMS.
/// </summary>
[JsonInclude]
public override VerificationMethodEx Method { get; } = VerificationMethodEx.FlashCall;

/// <summary>
/// An optional object for flashCall verifications.
/// It allows you to specify dial time out parameter for flashCall.
/// FlashCallOptions object can be specified optionally, and only
/// if the verification request was triggered from your backend (no SDK client)
/// through an Application signed request.
/// </summary>
public FlashCallOptions FlashCallOptions { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
using Sinch.Verification.Common;

namespace Sinch.Verification.Start.Request
{
public class StartPhoneCallVerificationRequest : StartVerificationRequestBase
{
/// <summary>
/// The type of the verification request. Set to Phone Call
/// </summary>
[JsonInclude]
public override VerificationMethodEx Method { get; } = VerificationMethodEx.Callout;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text.Json.Serialization;
using Sinch.Verification.Common;

namespace Sinch.Verification.Start.Request
{
public sealed class StartSmsVerificationRequest : StartVerificationRequestBase
{
/// <summary>
/// The type of the verification request. Set to SMS.
/// </summary>
[JsonInclude]
public override VerificationMethodEx Method { get; } = VerificationMethodEx.Sms;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Sinch.Verification.Start.Request
{
public class VerificationStartRequest
public class StartVerificationRequest
{
/// <summary>
/// Specifies the type of endpoint that will be verified and the particular endpoint.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Text.Json.Serialization;
using Sinch.Verification.Common;

namespace Sinch.Verification.Start.Request
{
public abstract class StartVerificationRequestBase
{
[JsonInclude]
public abstract VerificationMethodEx Method { get; }

/// <summary>
/// Specifies the type of endpoint that will be verified and the particular endpoint.
/// `number` is currently the only supported endpoint type.
/// </summary>
public Identity Identity { get; set; }

/// <summary>
/// Used to pass your own reference in the request for tracking purposes.
/// </summary>
public string Reference { get; set; }

/// <summary>
/// Can be used to pass custom data in the request.
/// </summary>
public string Custom { get; set; }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Sinch.Verification.Start.Response
{
public class DataVerificationStartResponse : VerificationStartResponseBase, IVerificationStartResponse
public class StartDataVerificationResponse : VerificationStartResponseBase, IStartVerificationResponse
{
/// <summary>
/// The response contains the target URI.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Sinch.Verification.Start.Response
{
public class FlashCallVerificationStartResponse : VerificationStartResponseBase, IVerificationStartResponse
public class StartFlashCallVerificationResponse : VerificationStartResponseBase, IStartVerificationResponse
{
/// <summary>
/// The response contains the cliFilter and interceptionTimeout properties.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Sinch.Verification.Start.Response
{
public class StartPhoneCallVerificationResponse : VerificationStartResponseBase, IStartVerificationResponse
{

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Sinch.Verification.Start.Response
{
public class SmsVerificationStartResponse : VerificationStartResponseBase, IVerificationStartResponse
public class StartSmsVerificationResponse : VerificationStartResponseBase, IStartVerificationResponse
{
/// <summary>
/// The response contains the template of the SMS to be expected and intercepted.
Expand Down
Loading
Loading