Skip to content

Commit

Permalink
added clear history & history encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
adrum committed Dec 21, 2024
1 parent 77473d6 commit fbdd13d
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 5 deletions.
1 change: 1 addition & 0 deletions InertiaCore/Models/InertiaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public class InertiaOptions

public bool SsrEnabled { get; set; } = false;
public string SsrUrl { get; set; } = "http://127.0.0.1:13714/render";
public bool EncryptHistory { get; set; } = false;
}
2 changes: 2 additions & 0 deletions InertiaCore/Models/Page.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ internal class Page
public string Component { get; set; } = default!;
public string? Version { get; set; }
public string Url { get; set; } = default!;
public bool EncryptHistory { get; set; } = false;
public bool ClearHistory { get; set; } = false;
}
13 changes: 9 additions & 4 deletions InertiaCore/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using InertiaCore.Extensions;
using InertiaCore.Models;
using InertiaCore.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
Expand All @@ -15,13 +16,15 @@ public class Response : IActionResult
private readonly object _props;
private readonly string _rootView;
private readonly string? _version;
private readonly bool _encryptHistory;
private readonly bool _clearHistory;

private ActionContext? _context;
private Page? _page;
private IDictionary<string, object>? _viewData;

public Response(string component, object props, string rootView, string? version)
=> (_component, _props, _rootView, _version) = (component, props, rootView, version);
public Response(string component, object props, string rootView, string? version, bool encryptHistory, bool clearHistory)
=> (_component, _props, _rootView, _version, _encryptHistory, _clearHistory) = (component, props, rootView, version, encryptHistory, clearHistory);

public async Task ExecuteResultAsync(ActionContext context)
{
Expand All @@ -38,7 +41,9 @@ protected internal void ProcessResponse()
Component = _component,
Version = _version,
Url = _context!.RequestedUri(),
Props = ResolveProperties(_props.GetType().GetProperties().ToDictionary(o => o.Name.ToCamelCase(), o => o.GetValue(_props)))
Props = ResolveProperties(_props.GetType().GetProperties().ToDictionary(o => o.Name.ToCamelCase(), o => o.GetValue(_props))),
EncryptHistory = _encryptHistory,
ClearHistory = _clearHistory,
};

var shared = _context!.HttpContext.Features.Get<InertiaSharedData>();
Expand All @@ -64,7 +69,7 @@ protected internal void ProcessResponse()
protected internal JsonResult GetJson()
{
_context!.HttpContext.Response.Headers.Add(Header.Inertia, "true");
_context!.HttpContext.Response.Headers.Add("Vary", "Accept");
_context!.HttpContext.Response.Headers.Add("Vary", Header.Inertia);
_context!.HttpContext.Response.StatusCode = 200;

return new JsonResult(_page, new JsonSerializerOptions
Expand Down
18 changes: 17 additions & 1 deletion InertiaCore/ResponseFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ internal interface IResponseFactory
public LocationResult Location(string url);
public void Share(string key, object? value);
public void Share(IDictionary<string, object?> data);
public void ClearHistory(bool clear = true);
public void EncryptHistory(bool encrypt = true);
public AlwaysProp Always(object? value);
public AlwaysProp Always(Func<object?> callback);
public AlwaysProp Always(Func<Task<object?>> callback);
Expand All @@ -36,14 +38,18 @@ internal class ResponseFactory : IResponseFactory

private object? _version;

protected bool clearHistory = false;

protected bool? encryptHistory;

public ResponseFactory(IHttpContextAccessor contextAccessor, IGateway gateway, IOptions<InertiaOptions> options) =>
(_contextAccessor, _gateway, _options) = (contextAccessor, gateway, options);

public Response Render(string component, object? props = null)
{
props ??= new { };

return new Response(component, props, _options.Value.RootView, GetVersion());
return new Response(component, props, _options.Value.RootView, GetVersion(), encryptHistory ?? _options.Value.EncryptHistory, clearHistory);
}

public async Task<IHtmlContent> Head(dynamic model)
Expand Down Expand Up @@ -122,6 +128,16 @@ public void Share(IDictionary<string, object?> data)
context.Features.Set(sharedData);
}

public void ClearHistory(bool clear = true)
{
clearHistory = clear;
}

public void EncryptHistory(bool encrypt = true)
{
encryptHistory = encrypt;
}

public LazyProp Lazy(Func<object?> callback) => new LazyProp(callback);
public LazyProp Lazy(Func<Task<object?>> callback) => new LazyProp(callback);
public AlwaysProp Always(object? value) => new AlwaysProp(value);
Expand Down
90 changes: 90 additions & 0 deletions InertiaCoreTests/UnitTestHistory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using InertiaCore.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace InertiaCoreTests;

public partial class Tests
{
[Test]
[Description("Test if history encryption is sent correctly.")]
public void TestHistoryEncryptionResult()
{
_factory.EncryptHistory();

var response = _factory.Render("Test/Page", new
{
Test = "Test"
});

var headers = new HeaderDictionary
{
{ "X-Inertia", "true" }
};

var context = PrepareContext(headers);

response.SetContext(context);
response.ProcessResponse();

var result = response.GetResult();

Assert.Multiple(() =>
{
Assert.That(result, Is.InstanceOf(typeof(JsonResult)));

var json = (result as JsonResult)?.Value;
Assert.That(json, Is.InstanceOf(typeof(Page)));

Assert.That((json as Page)?.ClearHistory, Is.EqualTo(false));
Assert.That((json as Page)?.EncryptHistory, Is.EqualTo(true));
Assert.That((json as Page)?.Component, Is.EqualTo("Test/Page"));
Assert.That((json as Page)?.Props, Is.EqualTo(new Dictionary<string, object?>
{
{ "test", "Test" },
{ "errors", new Dictionary<string, string>(0) }
}));
});
}

[Test]
[Description("Test if clear history is sent correctly.")]
public void TestClearHistoryResult()
{
_factory.ClearHistory();

var response = _factory.Render("Test/Page", new
{
Test = "Test"
});

var headers = new HeaderDictionary
{
{ "X-Inertia", "true" }
};

var context = PrepareContext(headers);

response.SetContext(context);
response.ProcessResponse();

var result = response.GetResult();

Assert.Multiple(() =>
{
Assert.That(result, Is.InstanceOf(typeof(JsonResult)));

var json = (result as JsonResult)?.Value;
Assert.That(json, Is.InstanceOf(typeof(Page)));

Assert.That((json as Page)?.ClearHistory, Is.EqualTo(true));
Assert.That((json as Page)?.EncryptHistory, Is.EqualTo(false));
Assert.That((json as Page)?.Component, Is.EqualTo("Test/Page"));
Assert.That((json as Page)?.Props, Is.EqualTo(new Dictionary<string, object?>
{
{ "test", "Test" },
{ "errors", new Dictionary<string, string>(0) }
}));
});
}
}

0 comments on commit fbdd13d

Please sign in to comment.