Push changes
This commit is contained in:
@@ -1,15 +1,107 @@
|
||||
using Prospect.Server.Api.Services.CloudScript.Models;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Prospect.Server.Api.Services.CloudScript.Functions;
|
||||
|
||||
public class TokenGenerator
|
||||
{
|
||||
public static int TokenSequenceId = 0;
|
||||
// Header is static - base64url encoded {}
|
||||
private static readonly string Header = "e30";
|
||||
|
||||
public static string vxGenerateToken(string key, string issuer, int exp, string vxa, string f, string t)
|
||||
{
|
||||
TokenSequenceId++;
|
||||
var claims = new Claims
|
||||
{
|
||||
iss = issuer,
|
||||
exp = exp,
|
||||
vxa = vxa,
|
||||
vxi = TokenSequenceId,
|
||||
f = f,
|
||||
t = t
|
||||
};
|
||||
|
||||
List<string> segments = new List<string>();
|
||||
segments.Add(Header);
|
||||
|
||||
// Encode payload
|
||||
var claimsString = JsonSerializer.Serialize(claims);
|
||||
var encodedClaims = Base64URLEncode(claimsString);
|
||||
|
||||
// Join segments to prepare for signing
|
||||
segments.Add(encodedClaims);
|
||||
string toSign = String.Join(".", segments);
|
||||
|
||||
// Sign token with key and SHA256
|
||||
string sig = SHA256Hash(key, toSign);
|
||||
segments.Add(sig);
|
||||
|
||||
// Join all 3 parts of token with . and return
|
||||
string token = String.Join(".", segments);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
private static string Base64URLEncode(string plainText)
|
||||
{
|
||||
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
|
||||
// Remove padding at the end
|
||||
var encodedString = Convert.ToBase64String(plainTextBytes).TrimEnd('=');
|
||||
// Substitute URL-safe characters
|
||||
string urlEncoded = encodedString.Replace("+", "-").Replace("/", "_");
|
||||
|
||||
return urlEncoded;
|
||||
}
|
||||
|
||||
private static string SHA256Hash(string secret, string message)
|
||||
{
|
||||
var encoding = new System.Text.ASCIIEncoding();
|
||||
byte[] keyByte = encoding.GetBytes(secret);
|
||||
byte[] messageBytes = encoding.GetBytes(message);
|
||||
// The instance of HMACSHA256 is constructed and disposed in this method because it is not thread safe
|
||||
using var hmacsha256 = new HMACSHA256(keyByte);
|
||||
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
|
||||
var hashString = Convert.ToBase64String(hashmessage).TrimEnd('=');
|
||||
string urlEncoded = hashString.Replace("+", "-").Replace("/", "_");
|
||||
|
||||
return urlEncoded;
|
||||
}
|
||||
|
||||
public class Claims
|
||||
{
|
||||
public string iss { get; set; }
|
||||
public int exp { get; set; }
|
||||
public string vxa { get; set; }
|
||||
public int vxi { get; set; }
|
||||
public string f { get; set; }
|
||||
public string t { get; set; }
|
||||
public string sub { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
[CloudScriptFunction("VivoxLogin")]
|
||||
public class VivoxLogin : ICloudScriptFunction<FYVivoxLoginTokenRequest, FYVivoxJoinData>
|
||||
{
|
||||
public Task<FYVivoxJoinData> ExecuteAsync(FYVivoxLoginTokenRequest request)
|
||||
public async Task<FYVivoxJoinData> ExecuteAsync(FYVivoxLoginTokenRequest request)
|
||||
{
|
||||
return Task.FromResult(new FYVivoxJoinData
|
||||
// TODO: Replace with app configuration
|
||||
var channel = "sip:confctl-g-<issuer>.testchannel@mtu1xp.vivox.com"; // e - echo channel, g - global, p - positional
|
||||
var exp = (int)DateTimeOffset.UtcNow.AddSeconds(90).ToUnixTimeSeconds();
|
||||
var token = TokenGenerator.vxGenerateToken("key", "issuer", exp, "login", request.Username, channel);
|
||||
|
||||
return new FYVivoxJoinData
|
||||
{
|
||||
|
||||
});
|
||||
Request = new Models.Data.FYVivoxJoinTokenRequest{
|
||||
Username = request.Username,
|
||||
Channel = channel,
|
||||
HasAudio = false,
|
||||
HasText = true,
|
||||
ChannelType = 2,
|
||||
ChannelID = "testchannel",
|
||||
},
|
||||
Token = token
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user