Skip to content

Commit

Permalink
Initial CS to handle SIGNIFY_AUTHORIZE working, replying to Page with…
Browse files Browse the repository at this point in the history
… faux credential
  • Loading branch information
edeykholt committed Sep 6, 2024
1 parent f7b9a05 commit 135ac8e
Show file tree
Hide file tree
Showing 15 changed files with 520 additions and 171 deletions.
28 changes: 28 additions & 0 deletions KeriAuth.BrowserExtension/Models/AuthorizeResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Text.Json.Serialization;

namespace KeriAuth.BrowserExtension.Models
{
public record AuthorizeResult
{
[JsonConstructor]
public AuthorizeResult(

Check warning on line 8 in KeriAuth.BrowserExtension/Models/AuthorizeResult.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'arc' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.

Check warning on line 8 in KeriAuth.BrowserExtension/Models/AuthorizeResult.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'ari' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
AuthorizeResultCredential? arc,
AuthorizeResultIdentifier? ari
)
{
if (arc is null && ari is null)
{
throw new ArgumentException("Either arc or ari must be non-null");
}

this.arc = arc;

Check warning on line 18 in KeriAuth.BrowserExtension/Models/AuthorizeResult.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference assignment.
this.ari = ari;

Check warning on line 19 in KeriAuth.BrowserExtension/Models/AuthorizeResult.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference assignment.
}

[JsonPropertyName("credential")]
public AuthorizeResultCredential arc { get; }

[JsonPropertyName("identifier")]
public AuthorizeResultIdentifier ari { get; }
}
}
21 changes: 21 additions & 0 deletions KeriAuth.BrowserExtension/Models/AuthorizeResultCredential.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Text.Json.Serialization;

namespace KeriAuth.BrowserExtension.Models
{
public record AuthorizeResultCredential : IEquatable<AuthorizeResultCredential>
{
[JsonConstructor]
public AuthorizeResultCredential(string raw, string cesr)
{
this.raw = raw;
this.cesr = cesr;
}

[JsonPropertyName("raw")]
public string raw { get; }


[JsonPropertyName("cesr")]
public string cesr { get; }
}
}
19 changes: 19 additions & 0 deletions KeriAuth.BrowserExtension/Models/AuthorizeResultIdentifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Text.Json.Serialization;
using KeriAuth.BrowserExtension.Models;

namespace KeriAuth.BrowserExtension.Models
{
public record AuthorizeResultIdentifier : IEquatable<AuthorizeResultIdentifier>
{
[JsonConstructor]
public AuthorizeResultIdentifier(
string prefix
)
{
this.prefix = prefix;
}

[JsonPropertyName("prefix")]
public string prefix { get; }
}
}
42 changes: 42 additions & 0 deletions KeriAuth.BrowserExtension/Models/ReplyMessageData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Text.Json.Serialization;

namespace KeriAuth.BrowserExtension.Models
{
public record ReplyMessageData<T>
{
[JsonConstructor]
public ReplyMessageData(
string type,
T payload,
string typeHint,
string? requestId = null,
string? error = null,
string? source = null)
{
this.type = type;
this.payloadTypeName = typeof(T).Name;
this.requestId = requestId;
this.payload = payload;
this.error = error;
this.source = source;
}

[JsonPropertyName("type")]
public string type { get; }

[JsonPropertyName("payloadTypeName")]
public string payloadTypeName { get; }

[JsonPropertyName("requestId")]
public string? requestId { get; }

[JsonPropertyName("payload")]
public T payload { get; }

[JsonPropertyName("error")]
public string? error { get; }

[JsonPropertyName("source")]
public string? source { get; }
}
}
46 changes: 27 additions & 19 deletions KeriAuth.BrowserExtension/Services/AppSwMessagingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.JSInterop;
using System.Threading.Tasks;
using System.Text.Json.Serialization;
using System;
using KeriAuth.BrowserExtension.Models;

namespace KeriAuth.BrowserExtension.Services
{
Expand All @@ -15,30 +18,35 @@ public class AppSwMessagingService(ILogger<AppSwMessagingService> logger, IJSRun

public async Task Initialize(string tabId)
{
_objectReference = DotNetObjectReference.Create(this);
_interopModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./scripts/es6/SwAppInterop.js");
// await js.InvokeVoidAsync("registerServiceWorkerMessaging");
_port = await _interopModule.InvokeAsync<IJSObjectReference>("SwAppInteropModule.initializeMessaging", _objectReference, "tab2");
try
{
_objectReference = DotNetObjectReference.Create(this);
_interopModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./scripts/es6/SwAppInterop.js");

if (_interopModule != null)
{
logger.LogInformation("JS module SwAppInterop.js import was successful.");
await jsRuntime.InvokeVoidAsync("console.log", "test log");

_port = await _interopModule.InvokeAsync<IJSObjectReference>("SwAppInteropModule.initializeMessaging", _objectReference, "tab2");
}
}
catch (Exception ex)
{
logger.LogError($"Failed to import JS module: {ex.Message}");
}
}

public async Task SendToServiceWorkerAsync<T>(string type, string message, T payload)
public async Task SendToServiceWorkerAsync<T>(ReplyMessageData<T> replyMessageData)
{
logger.LogInformation("SendToServiceWorkerAsync type {r}{n}", typeof(T).Name, replyMessageData.payloadTypeName);

if (_port != null)
{
// TODO P2 make the message payload typed
//var messagePayload = new MessagePayload<T>
//{
// Message = message,
// Payload = payload
//};

logger.LogInformation("AppSwMessagingService to SW: sending type, message, payload: {t} {m} {p}", type, message, payload);

//var messageJson = JsonSerializer.Serialize(message);
//var messageBytes = Encoding.UTF8.GetBytes(messageJson);
await _interopModule.InvokeVoidAsync("SwAppInteropModule.sendMessageToServiceWorker", _port, type, message);
// await Task.Delay(1000); // TODO big issue here?, need to wait for the message to be sent. See mingyaulee for a better way to do this?
logger.LogInformation("AppSwMessagingService to SW: sent");
var replyJson = JsonSerializer.Serialize(replyMessageData);
logger.LogInformation("SendToServiceWorkerAsync sending payloadJson: {p}", replyJson);
await _interopModule.InvokeVoidAsync("SwAppInteropModule.sendMessageToServiceWorker", _port, replyJson);
logger.LogInformation("SendToServiceWorkerAsync to SW: sent");
}
else
{
Expand Down
3 changes: 2 additions & 1 deletion KeriAuth.BrowserExtension/Services/IAppSwMessagingService.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Microsoft.JSInterop;
using System.Text.Json;
using System.Text;
using KeriAuth.BrowserExtension.Models;

namespace KeriAuth.BrowserExtension.Services
{
public interface IAppSwMessagingService : IObservable<string>
{
public Task Initialize(string tabId);

public Task SendToServiceWorkerAsync<T>(string type, string message, T payload);
public Task SendToServiceWorkerAsync<T>(ReplyMessageData<T> replyMessageData);

[JSInvokable]
public void ReceiveMessage(string message);
Expand Down
2 changes: 1 addition & 1 deletion KeriAuth.BrowserExtension/UI/Layouts/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
<!-- background-image:linear-gradient( 135deg, HSLA(205, 45%, 44%, 0.0), HSLA(189, 100%, 50%, 0.1) );"> -->
<MudDrawer id="MudDrawer" @ref="mudDrawerRef" @bind-Open="@IsMenuDrawerOpen" Elevation="1" ClipMode="DrawerClipMode.Never" Variant="@DrawerMode" OpenMiniOnHover="true">
<MudNavMenu Style="Background: var(--mud-palette-appbar-background); height:calc(100vh - var(--mud-appbar-height)); overflow-y:auto;">
<MudNavLink Href=@(RouteToRequestSignIn + System.Web.HttpUtility.UrlEncode("https://unset.com")) Icon="@Icons.Material.Filled.Key" IconColor="Color.Surface">Request SignIn</MudNavLink>
<MudNavLink Href=@(RouteToRequestSignIn + System.Web.HttpUtility.UrlEncode("https://unset.com") + "/" + System.Web.HttpUtility.UrlEncode("1234567890")) Icon="@Icons.Material.Filled.Key" IconColor="Color.Surface">Request SignIn</MudNavLink>
<MudNavLink Href=@RouteToIdentifiers Disabled="@(!IsAuthenticated)" Icon="@Icons.Material.Filled.Key" IconColor="Color.Surface">Identifiers</MudNavLink>
<MudNavLink Href=@RouteToGroups Disabled="@(!IsAuthenticated)" Icon="@Icons.Material.Filled.Groups" IconColor="Color.Surface">Groups</MudNavLink>
<MudNavLink Href=@RouteToCredentials Disabled="@(!IsAuthenticated)" Icon="@Icons.Material.Filled.Badge" IconColor="Color.Surface">Credentials</MudNavLink>
Expand Down
74 changes: 55 additions & 19 deletions KeriAuth.BrowserExtension/UI/Pages/RequestSignInPage.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@page "/RequestSignIn/{escapedOriginStr}"
@page "/RequestSignIn/{encodedOrigin}/{requestId}"
@layout Layouts.DialogLayout

@using System.Linq
Expand Down Expand Up @@ -38,15 +38,25 @@

@code {
[Parameter]
public string escapedOriginStr { get; set; } = "";
public string encodedOrigin { get; set; } = "";

string OriginStr { get; set; } = "http://example.com";
[Parameter]
public string requestId { get; set; } = "";

string OriginStr => HttpUtility.UrlDecode(encodedOrigin).Trim().Trim('"');

Uri GetOriginUri()
Uri? GetOriginUri()
{
// TODO try-catch
var x = new Uri(OriginStr);
return x;
try
{
var x = new Uri(OriginStr);
return x;
}
catch (Exception ex)
{
logger.LogError("Error parsing OriginStr '{o}': {e}", OriginStr, ex);
return null;
}
}

string AppActivePrefix { get; set; } = string.Empty;
Expand Down Expand Up @@ -171,22 +181,28 @@
InitializeOrOnNextPrefs(await preferencesService.GetPreferences());
await GetInitialHeadlines();

logger.LogInformation("OnParametersSetAsync requestId {r}", requestId);

logger.LogInformation("EE1.1.1.1");
// TODO remove temporary code below for exploration. Will be useful when requested to sign a specific request, such as issuing a credential
var initialUriQuery = extensionEnvironmentService.InitialUriQuery;
logger.LogInformation($"URI query: {initialUriQuery}");
// TODO add try-catch?
// TODO EE! decide whether these values (requestId, type, and others) should come in page parameters, initialUriQuery, or database/service.
if (QueryHelpers.ParseQuery(initialUriQuery).TryGetValue("message", out var outterMessage))
{
var decodedMsg = HttpUtility.UrlDecode(outterMessage);
logger.LogInformation("Chrome URI query message decoded: {msg}", decodedMsg);
if (!IsJsonValid(decodedMsg))
var decodedMsg2 = HttpUtility.UrlDecode(decodedMsg);
logger.LogInformation("Chrome URI query message decoded2: {msg}", decodedMsg2);

if (!IsJsonValid(decodedMsg2))
{
logger.LogError("Invalid JSON message: {msg}", decodedMsg);
logger.LogError("Chrome URI query Invalid JSON message: {msg}", decodedMsg2);
return;
};

string jsonString = outterMessage.ToString(); // Convert StringValues to string
string jsonString = decodedMsg2.ToString(); // Convert StringValues to string
// Parse the JSON string
var jsonDocument = JsonDocument.Parse(jsonString);
Expand All @@ -196,10 +212,19 @@
if (jsonObject.TryGetProperty("type", out var typeElement))
{
string type = typeElement.GetString() ?? String.Empty;

if (jsonObject.TryGetProperty("requestId", out var requestId2))
{
string requestId3 = requestId2.GetString() ?? String.Empty;
requestId = requestId3;
logger.LogInformation("Chrome URI query requestId: '{0}'", requestId);
}


logger.LogInformation("Processing message of type: {t}", type);
switch (type)
{
case "select-=identifier":
case "/signify/authorize":
logger.LogInformation("TODO EE1.1.1.1: {0}", type);
break;
default:
Expand All @@ -213,7 +238,8 @@
return;
}

} else
}
else
{
logger.LogError("Could not find UriQuery content containing outter \"message\".");
return;
Expand Down Expand Up @@ -292,19 +318,29 @@
async Task SignIn()
{
// TODO EE! finish implementation. setting payload with the prefix, etc.
logger.LogInformation("EE2");
// TODO should type of the payload be a class or JSON?
await appSwMessagingService.SendToServiceWorkerAsync<string>("/signify/reply", "sign-in", "sign-in payload");
logger.LogInformation("EE2 SignIn");
logger.LogInformation("EE2 escapedOriginStr {e}", encodedOrigin);

ReplyMessageData<AuthorizeResult> replyMessageData = new(
"/signify/reply",
new AuthorizeResult(new AuthorizeResultCredential("rawraw", "hail cesr"), null), // new AuthorizeResultIdentifier("selectedPrefix....")),
typeHint: "AuthorizeResult",
requestId: requestId
);

await appSwMessagingService.SendToServiceWorkerAsync<AuthorizeResult>(replyMessageData);

// TODO may need to assure message makes it to the service-worker?
// Close blazor application
await Task.Delay(1000); // TODO remove this delay
// UIHelper.CloseWindow();
// TODO remove this delay
await Task.Delay(1000);
// UIHelper.CloseWindow();
}

async Task Cancel()
{
// TODO should type of the payload be a class or JSON?
await appSwMessagingService.SendToServiceWorkerAsync<string>("AppSwSignIn", "sign-in-cancel", "sign-in-cancel-payload");
// TODO Send cancel or error to SendToServiceWorkerAsync
//
// TODO may need to assure message makes it to the service-worker?
// Close blazor application
UIHelper.CloseWindow();
Expand Down
Loading

0 comments on commit 135ac8e

Please sign in to comment.