mirror of
https://github.com/streetwriters/notesnook-sync-server.git
synced 2026-02-12 11:12:44 +00:00
identity: move to twilio verify for SMS 2FA
This commit is contained in:
@@ -45,8 +45,9 @@ namespace Streetwriters.Common
|
||||
public static string NOTESNOOK_API_SECRET => Environment.GetEnvironmentVariable("NOTESNOOK_API_SECRET");
|
||||
|
||||
// MessageBird is used for SMS sending
|
||||
public static string MESSAGEBIRD_ACCESS_KEY => Environment.GetEnvironmentVariable("MESSAGEBIRD_ACCESS_KEY");
|
||||
|
||||
public static string TWILIO_ACCOUNT_SID => Environment.GetEnvironmentVariable("TWILIO_ACCOUNT_SID");
|
||||
public static string TWILIO_AUTH_TOKEN => Environment.GetEnvironmentVariable("TWILIO_AUTH_TOKEN");
|
||||
public static string TWILIO_SERVICE_SID => Environment.GetEnvironmentVariable("TWILIO_SERVICE_SID");
|
||||
// Server discovery
|
||||
public static int NOTESNOOK_SERVER_PORT => int.Parse(Environment.GetEnvironmentVariable("NOTESNOOK_SERVER_PORT"));
|
||||
public static string NOTESNOOK_SERVER_HOST => Environment.GetEnvironmentVariable("NOTESNOOK_SERVER_HOST");
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Streetwriters.Identity.Interfaces
|
||||
{
|
||||
public interface ISMSSender
|
||||
{
|
||||
string SendOTP(string number, IClient client);
|
||||
bool VerifyOTP(string id, string code);
|
||||
Task<string> SendOTPAsync(string number, IClient client);
|
||||
Task<bool> VerifyOTPAsync(string id, string code);
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ namespace Streetwriters.Identity.Services
|
||||
break;
|
||||
case "sms":
|
||||
await UserManager.SetPhoneNumberAsync(user, form.PhoneNumber);
|
||||
var id = SMSSender.SendOTP(form.PhoneNumber, client);
|
||||
var id = await SMSSender.SendOTPAsync(form.PhoneNumber, client);
|
||||
await this.ReplaceClaimAsync(user, MFAService.SMS_ID_CLAIM, id);
|
||||
break;
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Streetwriters.Identity.Services
|
||||
{
|
||||
var id = this.GetClaimValue(user, MFAService.SMS_ID_CLAIM);
|
||||
if (string.IsNullOrEmpty(id)) throw new Exception("Could not find associated SMS verify id. Please try sending the code again.");
|
||||
if (SMSSender.VerifyOTP(id, code))
|
||||
if (await SMSSender.VerifyOTPAsync(id, code))
|
||||
{
|
||||
// Auto confirm user phone number if not confirmed
|
||||
if (!await UserManager.IsPhoneNumberConfirmedAsync(user))
|
||||
|
||||
@@ -24,6 +24,10 @@ using MessageBird.Objects;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Streetwriters.Identity.Models;
|
||||
using Streetwriters.Common;
|
||||
using Twilio.Rest.Verify.V2.Service;
|
||||
using Twilio;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
|
||||
namespace Streetwriters.Identity.Services
|
||||
{
|
||||
@@ -34,28 +38,39 @@ namespace Streetwriters.Identity.Services
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Constants.MESSAGEBIRD_ACCESS_KEY))
|
||||
client = Client.CreateDefault(Constants.MESSAGEBIRD_ACCESS_KEY);
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(Constants.TWILIO_ACCOUNT_SID) && !string.IsNullOrEmpty(Constants.TWILIO_AUTH_TOKEN))
|
||||
{
|
||||
TwilioClient.Init(Constants.TWILIO_ACCOUNT_SID, Constants.TWILIO_AUTH_TOKEN);
|
||||
}
|
||||
}
|
||||
|
||||
public string SendOTP(string number, IClient app)
|
||||
public async Task<string> SendOTPAsync(string number, IClient app)
|
||||
{
|
||||
VerifyOptionalArguments optionalArguments = new VerifyOptionalArguments
|
||||
try
|
||||
{
|
||||
Originator = app.Name,
|
||||
Reference = app.Name,
|
||||
Type = MessageType.Sms,
|
||||
Template = $"Your {app.Name} 2FA code is: %token. Valid for 5 minutes.",
|
||||
TokenLength = 6,
|
||||
Timeout = 60 * 5
|
||||
};
|
||||
Verify verify = client.CreateVerify(number, optionalArguments);
|
||||
if (verify.Status == VerifyStatus.Sent) return verify.Id;
|
||||
var verification = await VerificationResource.CreateAsync(
|
||||
to: number,
|
||||
channel: "sms",
|
||||
pathServiceSid: Constants.TWILIO_SERVICE_SID
|
||||
);
|
||||
return verification.Sid;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool VerifyOTP(string id, string code)
|
||||
public async Task<bool> VerifyOTPAsync(string id, string code)
|
||||
{
|
||||
Verify verify = client.SendVerifyToken(id, code);
|
||||
return verify.Status == VerifyStatus.Verified;
|
||||
return (await VerificationCheckResource.CreateAsync(
|
||||
verificationSid: id,
|
||||
pathServiceSid: Constants.TWILIO_SERVICE_SID,
|
||||
code: code
|
||||
)).Status == "approved";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.DataProtection" Version="7.0.4" />
|
||||
<PackageReference Include="AspNetCore.Identity.Mongo" Version="8.3.3" />
|
||||
<PackageReference Include="Twilio" Version="6.13.0" />
|
||||
<PackageReference Include="WebMarkupMin.Core" Version="2.13.0" />
|
||||
<PackageReference Include="WebMarkupMin.NUglify" Version="2.12.0" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user