identity: handle errors when sending/verifying sms otp codes

This commit is contained in:
Abdullah Atta
2026-05-08 11:08:55 +05:00
parent 30fdaae36c
commit 159fe0e376
3 changed files with 36 additions and 14 deletions
@@ -24,7 +24,7 @@ namespace Streetwriters.Identity.Interfaces
{
public interface ISMSSender
{
Task<string> SendOTPAsync(string number, IClient client);
Task<string?> SendOTPAsync(string number, IClient client);
Task<bool> VerifyOTPAsync(string id, string code);
}
}
@@ -186,6 +186,8 @@ namespace Streetwriters.Identity.Services
ArgumentNullException.ThrowIfNull(form.PhoneNumber);
await UserManager.SetPhoneNumberAsync(user, form.PhoneNumber);
var id = await SMSSender.SendOTPAsync(form.PhoneNumber, client);
if (string.IsNullOrEmpty(id)) throw new Exception("Failed to send SMS. Please try again.");
logger.LogInformation("SMS OTP sent for user: {UserId}, SMS ID: {SmsId}", user.Id, id);
await this.ReplaceClaimAsync(user, MFAService.SMS_ID_CLAIM, id);
break;
+33 -13
View File
@@ -23,36 +23,56 @@ using Streetwriters.Common;
using Twilio.Rest.Verify.V2.Service;
using Twilio;
using System.Threading.Tasks;
using System;
using Microsoft.Extensions.Logging;
namespace Streetwriters.Identity.Services
{
public class SMSSender : ISMSSender
{
public SMSSender()
private readonly ILogger<SMSSender> Logger;
public SMSSender(ILogger<SMSSender> logger)
{
Logger = logger;
if (!string.IsNullOrEmpty(Constants.TWILIO_ACCOUNT_SID) && !string.IsNullOrEmpty(Constants.TWILIO_AUTH_TOKEN))
{
TwilioClient.Init(Constants.TWILIO_ACCOUNT_SID, Constants.TWILIO_AUTH_TOKEN);
}
}
public async Task<string> SendOTPAsync(string number, IClient app)
public async Task<string?> SendOTPAsync(string number, IClient app)
{
var verification = await VerificationResource.CreateAsync(
to: number,
channel: "sms",
pathServiceSid: Constants.TWILIO_SERVICE_SID
);
return verification.Sid;
try
{
var verification = await VerificationResource.CreateAsync(
to: number,
channel: "sms",
pathServiceSid: Constants.TWILIO_SERVICE_SID
);
return verification.Sid;
}
catch (Exception ex)
{
Logger.LogError(ex, "Error sending OTP with Twilio");
return null;
}
}
public async Task<bool> VerifyOTPAsync(string id, string code)
{
return (await VerificationCheckResource.CreateAsync(
verificationSid: id,
pathServiceSid: Constants.TWILIO_SERVICE_SID,
code: code
)).Status == "approved";
try
{
return (await VerificationCheckResource.CreateAsync(
verificationSid: id,
pathServiceSid: Constants.TWILIO_SERVICE_SID,
code: code
)).Status == "approved";
}
catch (Exception ex)
{
Logger.LogError(ex, "Error verifying OTP with Twilio");
return false;
}
}
}
}