Initial commit
This commit is contained in:
40
Areas/console/Views/Authenticate/Index.cshtml
Normal file
40
Areas/console/Views/Authenticate/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
1
Areas/console/Views/_ViewImports.cshtml
Normal file
1
Areas/console/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
132
Areas/mobile/Views/Authenticate/Index.cshtml
Normal file
132
Areas/mobile/Views/Authenticate/Index.cshtml
Normal file
@@ -0,0 +1,132 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@using System.Text.Json
|
||||
@using System.Text.Json.Nodes
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
var makeAssertionsOptionsUrl = Url.Action("MakeAssertionOptions", "Authenticate", new { area = "mobile" });
|
||||
var authenticateUrl = Url.Action("Index", "Authenticate", new { area = "mobile" });
|
||||
var jsonObj = JsonSerializer.Deserialize<JsonObject>(Model.Input.ToString());
|
||||
var beginLoginUrl = Model.Input["BeginLoginUrl"].ToString();
|
||||
var loginStatusUrl = Model.Input["LoginStatusUrl"].ToString();
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
let csharpReference;
|
||||
var isInitialized = false;
|
||||
var init = function() {
|
||||
var beginLoginUrl = "@beginLoginUrl";
|
||||
var loginStatusUrl = "@loginStatusUrl";
|
||||
|
||||
var displayError = function (errorJson) {
|
||||
csharpReference.invokeMethodAsync("SetErrorMessage", errorJson["error_description"]);
|
||||
}
|
||||
|
||||
var displayQRCode = function (img) {
|
||||
$("#generateQrCodeForm").css("display", "none");
|
||||
$("#qrCodeContainer").css("display", "");
|
||||
$("#qrCodeContainer img").attr("src", img);
|
||||
}
|
||||
|
||||
async function checkStatus(sessionId) {
|
||||
setTimeout(async function () {
|
||||
let response = await fetch(loginStatusUrl + "/" + sessionId, {
|
||||
method: 'GET'
|
||||
});
|
||||
if (!response.ok) {
|
||||
let responseJson = await response.json();
|
||||
displayError(responseJson);
|
||||
await checkStatus(sessionId);
|
||||
} else {
|
||||
$("#generateQrCodeForm").unbind("submit");
|
||||
$("#generateQrCodeForm input[name='Login']").removeAttr('disabled');
|
||||
$("#generateQrCodeForm input[name='SessionId']").val(sessionId);
|
||||
$("#generateQrCodeForm").trigger("submit");
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
async function makeAssertionOptions(form) {
|
||||
let response = await fetch(beginLoginUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ login: form.Login, credential_type: 'mobile' }),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
const json = await response.json();
|
||||
displayError(json);
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionId = response.headers.get('SessionId');
|
||||
const qrCode = response.headers.get('QRCode');
|
||||
const blob = await response.blob();
|
||||
const img = URL.createObjectURL(blob);
|
||||
|
||||
displayQRCode(img);
|
||||
await checkStatus(sessionId);
|
||||
}
|
||||
|
||||
var tryListenForm = function () {
|
||||
const elt = $("#generateQrCodeForm");
|
||||
if (isInitialized === true) return;
|
||||
if (elt.length === 0) {
|
||||
setTimeout(() => tryListenForm(), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
elt.submit(function (e) {
|
||||
e.preventDefault();
|
||||
makeAssertionOptions(convertFormToJSON($(e.target)));
|
||||
});
|
||||
}
|
||||
|
||||
tryListenForm();
|
||||
}
|
||||
|
||||
setCsharpReference = function (ref) {
|
||||
csharpReference = ref;
|
||||
init();
|
||||
};
|
||||
</script>
|
||||
}
|
||||
144
Areas/mobile/Views/Register/Index.cshtml
Normal file
144
Areas/mobile/Views/Register/Index.cshtml
Normal file
@@ -0,0 +1,144 @@
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options;
|
||||
@using SimpleIdServer.IdServer.Options;
|
||||
@using System.Text.Json
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
var beginRegisterUrl = Model.Input["BeginRegisterUrl"].ToString();
|
||||
var registerStatusUrl = Model.Input["RegisterStatusUrl"].ToString();
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
let csharpReference;
|
||||
|
||||
var init = function() {
|
||||
var beginRegisterUrl = "@beginRegisterUrl";
|
||||
var registerStatusUrl = "@registerStatusUrl";
|
||||
var isCreated = "IsCreated";
|
||||
var isInitialized = false;
|
||||
|
||||
var displayError = function(errorJson) {
|
||||
csharpReference.invokeMethodAsync("SetErrorMessage", errorJson["error_description"]);
|
||||
}
|
||||
|
||||
var displaySuccessMessage = function () {
|
||||
csharpReference.invokeMethodAsync("SetSuccessMessage", "User is created");
|
||||
csharpReference.invokeMethodAsync("ClearErrorMessages");
|
||||
csharpReference.invokeMethodAsync("SetInputData", isCreated, "true");
|
||||
$("#generateQrCodeForm").attr("style", "display: none !important");
|
||||
$("#qrCodeContainer").attr("style", "display: none !important");
|
||||
}
|
||||
|
||||
var displayQRCode = function (img, qrCode) {
|
||||
$("#generateQrCodeForm").attr("style", "display: none !important");
|
||||
$("#qrCodeContainer").css("display", "");
|
||||
$("#qrCodeContainer img").attr("src", img);
|
||||
}
|
||||
|
||||
async function checkStatus(sessionId, nextRegistrationRedirectUrl) {
|
||||
setTimeout(async function(){
|
||||
let response = await fetch(registerStatusUrl + "/" + sessionId, {
|
||||
method: 'GET'
|
||||
});
|
||||
if (!response.ok) {
|
||||
let responseJson = await response.json();
|
||||
displayError(responseJson);
|
||||
await checkStatus(sessionId, nextRegistrationRedirectUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
if(nextRegistrationRedirectUrl) {
|
||||
window.location.href = nextRegistrationRedirectUrl;
|
||||
} else {
|
||||
displaySuccessMessage();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
async function makeCredential(login, displayName, form) {
|
||||
let response = await fetch(beginRegisterUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ login: login, display_name: displayName, credential_type: 'mobile' }),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
let responseJson = await response.json();
|
||||
displayError(responseJson);
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionId = response.headers.get('SessionId');
|
||||
const qrCode = response.headers.get('QRCode');
|
||||
let nextRegistrationRedirectUrl = response.headers.get('NextRegistrationRedirectUrl');
|
||||
const blob = await response.blob();
|
||||
const img = URL.createObjectURL(blob);
|
||||
displayQRCode(img, qrCode);
|
||||
await checkStatus(sessionId, nextRegistrationRedirectUrl);
|
||||
};
|
||||
|
||||
var tryListenForm = function () {
|
||||
const elt = $("#generateQrCodeForm");
|
||||
if (isInitialized === true) return;
|
||||
if (elt.length === 0) {
|
||||
setTimeout(() => tryListenForm(), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
elt.submit(function (e) {
|
||||
e.preventDefault();
|
||||
var login = $("#generateQrCodeForm input[name='Login']").val();
|
||||
var displayName = $("#generateQrCodeForm input[name='DisplayName']").val();
|
||||
makeCredential(login, displayName, convertFormToJSON($(e.target)));
|
||||
});
|
||||
}
|
||||
|
||||
tryListenForm();
|
||||
};
|
||||
|
||||
setCsharpReference = function (ref) {
|
||||
csharpReference = ref;
|
||||
init();
|
||||
};
|
||||
</script>
|
||||
}
|
||||
1
Areas/mobile/Views/_ViewImports.cshtml
Normal file
1
Areas/mobile/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
40
Areas/otp/Views/Authenticate/Index.cshtml
Normal file
40
Areas/otp/Views/Authenticate/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
1
Areas/otp/Views/_ViewImports.cshtml
Normal file
1
Areas/otp/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
40
Areas/pwd/Views/Authenticate/Index.cshtml
Normal file
40
Areas/pwd/Views/Authenticate/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
40
Areas/pwd/Views/Register/Index.cshtml
Normal file
40
Areas/pwd/Views/Register/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
40
Areas/pwd/Views/Reset/Confirm.cshtml
Normal file
40
Areas/pwd/Views/Reset/Confirm.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
40
Areas/pwd/Views/Reset/Index.cshtml
Normal file
40
Areas/pwd/Views/Reset/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
1
Areas/pwd/Views/_ViewImports.cshtml
Normal file
1
Areas/pwd/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
40
Areas/sms/Views/Authenticate/Index.cshtml
Normal file
40
Areas/sms/Views/Authenticate/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
40
Areas/sms/Views/Register/Index.cshtml
Normal file
40
Areas/sms/Views/Register/Index.cshtml
Normal file
@@ -0,0 +1,40 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
1
Areas/sms/Views/_ViewImports.cshtml
Normal file
1
Areas/sms/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
154
Areas/vp/Views/Register/Index.cshtml
Normal file
154
Areas/vp/Views/Register/Index.cshtml
Normal file
@@ -0,0 +1,154 @@
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options;
|
||||
@using SimpleIdServer.IdServer.Options;
|
||||
@using System.Text.Json
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
var qrCodeUrl = Model.Input["QrCodeUrl"].ToString();
|
||||
var statusUrl = Model.Input["StatusUrl"].ToString();
|
||||
var endRegisterUrl = Model.Input["EndRegisterUrl"].ToString();
|
||||
var isCreated = Model.Input["IsCreated"].ToString();
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
let csharpReference;
|
||||
var isInitialized = false;
|
||||
|
||||
var init = function () {
|
||||
var getQrCodeUrl = "@qrCodeUrl";
|
||||
var statusUrl = "@statusUrl";
|
||||
var endRegisterURL = "@endRegisterUrl";
|
||||
var isCreated = "@isCreated";
|
||||
|
||||
var displayError = function (errorJson) {
|
||||
csharpReference.invokeMethodAsync("SetErrorMessage", errorJson["error_description"]);
|
||||
}
|
||||
|
||||
var viewQrCode = function (img) {
|
||||
$("#generateQrCodeForm").attr("style", "display: none !important");
|
||||
$("#qrCodeContainer").css("display", "");
|
||||
$("#qrCodeContainer img").attr("src", img);
|
||||
}
|
||||
|
||||
var displaySuccessMessage = function () {
|
||||
csharpReference.invokeMethodAsync("SetSuccessMessage", "User is created");
|
||||
csharpReference.invokeMethodAsync("ClearErrorMessages");
|
||||
csharpReference.invokeMethodAsync("SetInputData", isCreated, "true");
|
||||
$("#generateQrCodeForm").attr("style", "display: none !important");
|
||||
$("#qrCodeContainer").attr("style", "display: none !important");
|
||||
}
|
||||
|
||||
async function register(state) {
|
||||
let response = await fetch(endRegisterURL, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
state: state
|
||||
}),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
let responseJson = await response.json();
|
||||
if (!responseJson.next_registration_url) {
|
||||
displaySuccessMessage();
|
||||
} else {
|
||||
window.location.href = responseJson.next_registration_url;
|
||||
}
|
||||
}
|
||||
|
||||
async function checkStatus(state) {
|
||||
setTimeout(async function () {
|
||||
let response = await fetch(statusUrl + "/" + state, {
|
||||
method: 'GET'
|
||||
});
|
||||
if (!response.ok) {
|
||||
let responseJson = await response.json();
|
||||
displayError(responseJson);
|
||||
await checkStatus(state);
|
||||
return;
|
||||
}
|
||||
|
||||
register(state);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
async function displayQrCode(id) {
|
||||
let response = await fetch(getQrCodeUrl + "/" + id, {
|
||||
method: 'GET'
|
||||
});
|
||||
if (!response.ok) {
|
||||
const json = await response.json();
|
||||
displayError(json);
|
||||
return;
|
||||
}
|
||||
|
||||
const state = response.headers.get('state');
|
||||
const blob = await response.blob();
|
||||
const img = URL.createObjectURL(blob);
|
||||
viewQrCode(img);
|
||||
await checkStatus(state);
|
||||
}
|
||||
|
||||
var tryListenForm = function () {
|
||||
const elt = $(".vpRegister");
|
||||
if (isInitialized === true) return;
|
||||
if (elt.length === 0) {
|
||||
setTimeout(() => tryListenForm(), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
elt.submit(function (e) {
|
||||
e.preventDefault();
|
||||
var id = $(e.target).serializeArray()[0].value;
|
||||
displayQrCode(id);
|
||||
});
|
||||
}
|
||||
|
||||
tryListenForm();
|
||||
}
|
||||
|
||||
setCsharpReference = function (ref) {
|
||||
csharpReference = ref;
|
||||
init();
|
||||
};
|
||||
</script>
|
||||
}
|
||||
1
Areas/vp/Views/_ViewImports.cshtml
Normal file
1
Areas/vp/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
166
Areas/webauthn/Views/Authenticate/Index.cshtml
Normal file
166
Areas/webauthn/Views/Authenticate/Index.cshtml
Normal file
@@ -0,0 +1,166 @@
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options
|
||||
@using System.Text.Json
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
var makeAssertionsOptionsUrl = Url.Action("MakeAssertionOptions", "Authenticate", new { area = "webauthn" });
|
||||
var authenticateUrl = Url.Action("Index", "Authenticate", new { area = "webauthn" });
|
||||
var beginLoginUrl = Model.Input["BeginLoginUrl"].ToString();
|
||||
var endLoginUrl = Model.Input["EndLoginUrl"].ToString();
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
let csharpReference;
|
||||
|
||||
var init = function () {
|
||||
var beginLoginUrl = "@beginLoginUrl";
|
||||
var endLoginUrl = "@endLoginUrl";
|
||||
var makeAssertionsUrl = "@makeAssertionsOptionsUrl";
|
||||
var authenticateUrl = "@authenticateUrl";
|
||||
var isInitialized = false;
|
||||
|
||||
var toggleBtn = function (isDisabled) {
|
||||
$("#fido2Auth button[type='submit']").attr('disabled', isDisabled);
|
||||
}
|
||||
|
||||
var displayError = function (errorJson) {
|
||||
csharpReference.invokeMethodAsync("SetErrorMessage", errorJson["error_description"]);
|
||||
}
|
||||
|
||||
var tryListenForm = function () {
|
||||
const elt = $("#webauthForm");
|
||||
if (isInitialized === true) return;
|
||||
if (elt.length === 0) {
|
||||
setTimeout(() => tryListenForm(), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
elt.submit(function (e) {
|
||||
e.preventDefault();
|
||||
makeAssertionOptions(convertFormToJSON($(e.target)));
|
||||
});
|
||||
}
|
||||
|
||||
async function makeAssertion(credential, form, sessionId) {
|
||||
let authData = new Uint8Array(credential.response.authenticatorData);
|
||||
let clientDataJSON = new Uint8Array(credential.response.clientDataJSON);
|
||||
let rawId = new Uint8Array(credential.rawId);
|
||||
let sig = new Uint8Array(credential.response.signature);
|
||||
const assertion = {
|
||||
id: credential.id,
|
||||
rawId: coerceToBase64Url(rawId),
|
||||
type: credential.type,
|
||||
extensions: credential.getClientExtensionResults(),
|
||||
response: {
|
||||
authenticatorData: coerceToBase64Url(authData),
|
||||
clientDataJSON: coerceToBase64Url(clientDataJSON),
|
||||
signature: coerceToBase64Url(sig)
|
||||
}
|
||||
};
|
||||
let response = await fetch(endLoginUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ login: form.Login, session_id: sessionId, assertion: assertion }),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const json = await response.json();
|
||||
toggleBtn(false);
|
||||
displayError(json);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$("#webauthForm").unbind("submit");
|
||||
$("#webauthForm input[name='SessionId']").val(sessionId);
|
||||
$("#webauthForm input[name='Login']").removeAttr('disabled');
|
||||
$("#webauthForm").trigger("submit");
|
||||
}
|
||||
|
||||
async function makeAssertionOptions(form) {
|
||||
toggleBtn(true);
|
||||
let response = await fetch(beginLoginUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ login: form.Login, credential_type: 'webauthn' }),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
const json = await response.json();
|
||||
if (!response.ok) {
|
||||
toggleBtn(false);
|
||||
displayError(json);
|
||||
return;
|
||||
}
|
||||
|
||||
const makeAssertionOptions = json["assertion"];
|
||||
const sessionId = json["session_id"];
|
||||
const challenge = makeAssertionOptions.challenge.replace(/-/g, "+").replace(/_/g, "/");
|
||||
makeAssertionOptions.challenge = Uint8Array.from(atob(challenge), c => c.charCodeAt(0));
|
||||
makeAssertionOptions.allowCredentials.forEach(function (listItem) {
|
||||
var fixedId = listItem.id.replace(/\_/g, "/").replace(/\-/g, "+");
|
||||
listItem.id = Uint8Array.from(atob(fixedId), c => c.charCodeAt(0));
|
||||
});
|
||||
let credential;
|
||||
try {
|
||||
credential = await navigator.credentials.get({ publicKey: makeAssertionOptions })
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
toggleBtn(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await makeAssertion(credential, form, sessionId);
|
||||
}
|
||||
|
||||
tryListenForm();
|
||||
};
|
||||
|
||||
setCsharpReference = function(ref) {
|
||||
console.log(ref);
|
||||
csharpReference = ref;
|
||||
init();
|
||||
};
|
||||
</script>
|
||||
}
|
||||
179
Areas/webauthn/Views/Register/Index.cshtml
Normal file
179
Areas/webauthn/Views/Register/Index.cshtml
Normal file
@@ -0,0 +1,179 @@
|
||||
@using FormBuilder.Components.Workflow
|
||||
@using FormBuilder
|
||||
@using FormBuilder.Helpers
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@using Microsoft.Extensions.Options;
|
||||
@using SimpleIdServer.IdServer.Options;
|
||||
@using System.Text.Json
|
||||
@model SimpleIdServer.IdServer.UI.ViewModels.SidWorkflowViewModel
|
||||
@inject IOptions<FormBuilderOptions> options
|
||||
@inject IUriProvider uriProvider
|
||||
@inject IHttpContextAccessor HttpContextAccessor;
|
||||
|
||||
@{
|
||||
Layout = "~/Views/Shared/_FormBuilderLayout.cshtml";
|
||||
var antiforgeryToken = HttpContextAccessor.HttpContext.Request.Cookies[options.Value.AntiforgeryCookieName];
|
||||
Model.AntiforgeryToken.CookieValue = antiforgeryToken;
|
||||
var step = Model.Workflow?.Steps?.SingleOrDefault(s => s.Id == Model.CurrentStepId);
|
||||
var beginRegisterUrl = Model.Input["BeginRegisterUrl"].ToString();
|
||||
var endRegisterUrl = Model.Input["EndRegisterUrl"].ToString();
|
||||
var returnUrl = Model.Input["ReturnUrl"].ToString();
|
||||
var isCreated = Model.Input["IsCreated"].ToString();
|
||||
}
|
||||
|
||||
<component type="typeof(WorkflowViewer)"
|
||||
render-mode="ServerPrerendered"
|
||||
param-Input="@Model.Input"
|
||||
param-Workflow="@Model.Workflow"
|
||||
param-FormRecords="@Model.FormRecords"
|
||||
param-CurrentStepId="@Model.CurrentStepId"
|
||||
param-ErrorMessages="@Model.ErrorMessages"
|
||||
param-SuccessMessages="@Model.SuccessMessages"
|
||||
param-AntiforgeryToken="@Model.AntiforgeryToken"
|
||||
param-SupportedLanguageCodes="@Model.SupportedLanguageCodes"
|
||||
param-Template="@Model.Template" />
|
||||
|
||||
@section Header {
|
||||
@foreach (var cssStyle in Model.Template.CssStyles)
|
||||
{
|
||||
<link rel="stylesheet" href="@uriProvider.GetCssUrl(Model.Template.Id, cssStyle)" />
|
||||
}
|
||||
|
||||
@foreach (var jsStyle in Model.Template.JsStyles)
|
||||
{
|
||||
<script src="@uriProvider.GetJsUrl(Model.Template.Id, jsStyle)" type="text/javascript"></script>
|
||||
}
|
||||
}
|
||||
|
||||
@section Scripts {
|
||||
<script type="text/javascript">
|
||||
let csharpReference;
|
||||
|
||||
var init = function () {
|
||||
var beginRegisterUrl = "@beginRegisterUrl";
|
||||
var endRegisterUrl = "@endRegisterUrl";
|
||||
var redirectUrl = "@returnUrl";
|
||||
var isCreated = "@isCreated";
|
||||
var isInitialized = false;
|
||||
|
||||
var displayError = function (errorJson) {
|
||||
csharpReference.invokeMethodAsync("SetErrorMessage", errorJson["error_description"]);
|
||||
}
|
||||
|
||||
var displaySuccessMessage = function () {
|
||||
csharpReference.invokeMethodAsync("SetSuccessMessage", "User is created");
|
||||
csharpReference.invokeMethodAsync("ClearErrorMessages");
|
||||
csharpReference.invokeMethodAsync("SetInputData", isCreated, "true");
|
||||
$("#webauthForm").hide();
|
||||
}
|
||||
|
||||
async function registerCredential(newCredential, sessionId, login, nextRegistrationRedirectUrl) {
|
||||
let attestationObject = new Uint8Array(newCredential.response.attestationObject);
|
||||
let clientDataJSON = new Uint8Array(newCredential.response.clientDataJSON);
|
||||
let rawId = new Uint8Array(newCredential.rawId);
|
||||
const serializedAuthenticatorAttestationRawResponse = {
|
||||
id: newCredential.id,
|
||||
rawId: coerceToBase64Url(rawId),
|
||||
type: newCredential.type,
|
||||
extensions: newCredential.getClientExtensionResults(),
|
||||
response: {
|
||||
attestationObject: coerceToBase64Url(attestationObject),
|
||||
clientDataJSON: coerceToBase64Url(clientDataJSON)
|
||||
}
|
||||
};
|
||||
|
||||
let response = await fetch(endRegisterUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
attestation: serializedAuthenticatorAttestationRawResponse,
|
||||
login: login,
|
||||
session_id: sessionId
|
||||
}),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
let responseJson = await response.json();
|
||||
if (!response.ok) {
|
||||
displayError(responseJson);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nextRegistrationRedirectUrl) {
|
||||
window.location.href = nextRegistrationRedirectUrl;
|
||||
return;
|
||||
}
|
||||
|
||||
displaySuccessMessage();
|
||||
}
|
||||
|
||||
async function makeCredential(login, displayName) {
|
||||
let response = await fetch(beginRegisterUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ login: login, display_name: displayName, credential_type: 'webauthn' }),
|
||||
headers: {
|
||||
"Accept": "application/json",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
});
|
||||
let responseJson = await response.json();
|
||||
if (!response.ok) {
|
||||
displayError(responseJson);
|
||||
return;
|
||||
}
|
||||
|
||||
let makeCredentialOptions = responseJson["credential_create_options"];
|
||||
let sessionId = responseJson["session_id"];
|
||||
let nextRegistrationRedirectUrl = null;
|
||||
if (responseJson['next_registration_redirect_url']) {
|
||||
nextRegistrationRedirectUrl = responseJson['next_registration_redirect_url'];
|
||||
}
|
||||
|
||||
makeCredentialOptions.challenge = coerceToArrayBuffer(makeCredentialOptions.challenge);
|
||||
makeCredentialOptions.user.id = coerceToArrayBuffer(makeCredentialOptions.user.id);
|
||||
makeCredentialOptions.excludeCredentials = makeCredentialOptions.excludeCredentials.map((c) => {
|
||||
c.id = coerceToArrayBuffer(c.id);
|
||||
return c;
|
||||
});
|
||||
if (makeCredentialOptions.authenticatorSelection.authenticatorAttachment === null) makeCredentialOptions.authenticatorSelection.authenticatorAttachment = undefined;
|
||||
let newCredential;
|
||||
try {
|
||||
newCredential = await navigator.credentials.create({
|
||||
publicKey: makeCredentialOptions
|
||||
});
|
||||
} catch (e) {
|
||||
var msg = "Could not create credentials in browser. Probably because the username is already registered with your authenticator. Please change username or authenticator."
|
||||
console.error(msg, e);
|
||||
return;
|
||||
}
|
||||
|
||||
await registerCredential(newCredential, sessionId, login, nextRegistrationRedirectUrl);
|
||||
};
|
||||
|
||||
var tryListenForm = function () {
|
||||
const elt = $("#webauthForm");
|
||||
if (isInitialized === true) return;
|
||||
if (elt.length === 0) {
|
||||
setTimeout(() => tryListenForm(), 500);
|
||||
return;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
elt.submit(function (e) {
|
||||
e.preventDefault();
|
||||
var login = $("#webauthForm input[name='Login']").val();
|
||||
var displayName = $("#webauthForm input[name='DisplayName']").val();
|
||||
makeCredential(login, displayName);
|
||||
});
|
||||
}
|
||||
|
||||
tryListenForm();
|
||||
};
|
||||
|
||||
setCsharpReference = function (ref) {
|
||||
csharpReference = ref;
|
||||
init();
|
||||
};
|
||||
</script>
|
||||
}
|
||||
1
Areas/webauthn/Views/_ViewImports.cshtml
Normal file
1
Areas/webauthn/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1 @@
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
Reference in New Issue
Block a user