Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenId UI Enhancements #16467

Merged
merged 15 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/OrchardCore.Modules/OrchardCore.Media/Assets.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
"inputs": [
"./node_modules/blueimp-file-upload/js/jquery.fileupload.js",
"./node_modules/blueimp-file-upload/js/jquery.iframe-transport.js",
"Assets/js/helpers.js",
"Assets/js/app/**/*.js"
],
"watch": [
"Assets/js/helpers.js",
"Assets/js/app/**/*.js"
],
"output": "wwwroot/Scripts/media.js"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static ResourceManagementOptionsConfiguration()
_manifest
.DefineScript("media")
.SetUrl("~/OrchardCore.Media/Scripts/media.min.js", "~/OrchardCore.Media/Scripts/media.js")
.SetDependencies("vuejs", "sortable", "vuedraggable", "jQuery-ui")
.SetDependencies("vuejs", "sortable", "vuedraggable", "jQuery-ui", "credential-helpers")
.SetVersion("1.0.0");

_manifest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1558,15 +1558,6 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
});
});
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function randomUUID() {
if ((typeof crypto === "undefined" ? "undefined" : _typeof(crypto)) === 'object' && typeof crypto.randomUUID === 'function') {
return crypto.randomUUID();
}
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, function (c) {
return (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16);
});
}
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -71,20 +72,25 @@ public async Task<ActionResult> Index(PagerParameters pagerParameters)
var pager = new Pager(pagerParameters, _pagerOptions.GetPageSize());
var count = await _applicationManager.CountAsync();

var model = new OpenIdApplicationsIndexViewModel
{
Pager = await _shapeFactory.PagerAsync(pager, (int)count),
};
var applications = new List<OpenIdApplicationEntry>();

await foreach (var application in _applicationManager.ListAsync(pager.PageSize, pager.GetStartIndex()))
{
model.Applications.Add(new OpenIdApplicationEntry
applications.Add(new OpenIdApplicationEntry
{
DisplayName = await _applicationManager.GetDisplayNameAsync(application),
Id = await _applicationManager.GetPhysicalIdAsync(application)
});
}

var model = new OpenIdApplicationsIndexViewModel
{
Pager = await _shapeFactory.PagerAsync(pager, (int)count),
Applications = applications.OrderBy(x => x.DisplayName)
.ThenBy(x => x.Id)
.ToArray(),
};

return View(model);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace OrchardCore.OpenId.ViewModels
{
public class OpenIdApplicationsIndexViewModel
{
public IList<OpenIdApplicationEntry> Applications { get; } = [];
[BindNever]
public IList<OpenIdApplicationEntry> Applications { get; set; }

[BindNever]
public dynamic Pager { get; set; }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@
<zone Name="Title"><h1>@RenderTitleSegments(T["Create a new application"])</h1></zone>

<div asp-validation-summary="ModelOnly"></div>

<form asp-action="Create" method="post" class="no-multisubmit">
<div class="mb-3" asp-validation-class-for="ClientId">
<label asp-for="ClientId" class="form-label">@T["Client Id"]</label>
<input asp-for="ClientId" class="form-control" autofocus />
<span asp-validation-for="ClientId" class="text-danger"></span>
</div>

<div class="mb-3" asp-validation-class-for="DisplayName">
<label asp-for="DisplayName" class="form-label">@T["Display Name"]</label>
<input asp-for="DisplayName" class="form-control" autofocus />
<span asp-validation-for="DisplayName" class="text-danger"></span>
</div>

<div class="mb-3" asp-validation-class-for="Type">
<label asp-for="Type" class="form-label">@T["Type"]</label>
<select asp-for="Type" class="form-select">
Expand All @@ -28,13 +26,30 @@
</select>
<div class="hint">@T["Confidential applications MUST send their client secret when communicating with the token and revocation endpoints. This guarantees that only the legit client can exchange an authorization code or get a refresh token."]</div>
</div>

<div class="mb-3" asp-validation-class-for="ClientId">
<label asp-for="ClientId" class="form-label">@T["Client Id"]</label>
<div class="input-group">
<input asp-for="ClientId" class="form-control" autofocus autocomplete="new-password" />
<button tabindex="-1" class="btn btn-outline-secondary" type="button" id="copyClientId" title="@T["Click here to copy the value"]"><i class="fa-solid fa-copy"></i></button>
<button tabindex="-1" class="btn btn-outline-secondary" type="button" id="generateClientId" title="@T["Click here to generate new value"]"><i class="fa-solid fa-shuffle"></i></button>
</div>
<span asp-validation-for="ClientId" class="text-danger"></span>
</div>

<div class="mb-3" asp-validation-class-for="ClientSecret">
<label asp-for="ClientSecret" class="form-label">@T["Client Secret"]</label>
<input asp-for="ClientSecret" class="form-control" autofocus autocomplete="off" />
<div class="input-group">
<input type="password" asp-for="ClientSecret" class="form-control" autocomplete="new-password" />
<button tabindex="-1" class="btn btn-outline-secondary" type="button" id="toggleClientSecret" title="@T["Click here toggle secret visibility"]"><i class="icon fa-solid fa-eye"></i></button>
<button tabindex="-1" class="btn btn-outline-secondary" type="button" id="copyClientSecret" title="@T["Click here to copy the value"]"><i class="fa-solid fa-copy"></i></button>
<button tabindex="-1" class="btn btn-outline-secondary" type="button" id="generateClientSecret" title="@T["Click here to generate new value"]"><i class="fa-solid fa-shuffle"></i></button>
</div>
<span asp-validation-for="ClientSecret" class="text-danger"></span>
</div>

<h3>Flows</h3>
<h3>@T["Flows"]</h3>

<div id="AllowAuthorizationCodeFlowFieldSet" class="mb-3 collapse" asp-validation-class-for="AllowAuthorizationCodeFlow">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="AllowAuthorizationCodeFlow" data-bs-toggle="collapse" data-bs-target="#AllowAuthorizationCodeFlowRecommendedHint" checked="@Model.AllowAuthorizationCodeFlow">
Expand Down Expand Up @@ -90,13 +105,15 @@
</div>

<div id="RedirectSection" class="mb-3 collapse">
<div asp-validation-class-for="RedirectUris">
<label asp-for="RedirectUris" class="form-label">@T["Redirect Uris"]</label>
<input asp-for="RedirectUris" class="form-select" autofocus />
<span asp-validation-for="RedirectUris" class="text-danger"></span>
</div>
<div class="hint">
@T["Space delimited list of redirect URIs."]
<div class="mb-3">
<div asp-validation-class-for="RedirectUris">
<label asp-for="RedirectUris" class="form-label">@T["Redirect Uris"]</label>
<input asp-for="RedirectUris" class="form-select" autofocus />
<span asp-validation-for="RedirectUris" class="text-danger"></span>
</div>
<div class="hint">
@T["Space delimited list of redirect URIs."]
</div>
</div>
<div class="mb-3 collapse" id="AllowLogoutEndpointFieldSet">
<div class="mb-3">
Expand All @@ -116,16 +133,14 @@
</div>
</div>
</div>
<div class="mb-3" >
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="RequireProofKeyForCodeExchange" checked="@Model.RequireProofKeyForCodeExchange">
<label class="form-check-label" asp-for="RequireProofKeyForCodeExchange">@T["Require Proof Key for Code Exchange"]</label>
</div>
<div class="hint">
@T["Ensure that the client application and OAuth or OIDC library being used supports PKCE before enabling this option."]
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input type="checkbox" class="form-check-input" asp-for="RequireProofKeyForCodeExchange" checked="@Model.RequireProofKeyForCodeExchange">
<label class="form-check-label" asp-for="RequireProofKeyForCodeExchange">@T["Require Proof Key for Code Exchange"]</label>
</div>
<div class="hint">
@T["Ensure that the client application and OAuth or OIDC library being used supports PKCE before enabling this option."]
</div>
</div>
<div class="mb-3" asp-validation-class-for="ConsentType">
<label asp-for="ConsentType" class="form-label">@T["Consent type"]</label>
Expand Down Expand Up @@ -174,7 +189,40 @@
<a class="btn btn-secondary cancel" role="button" asp-route-action="Index">@T["Cancel"]</a>
</div>
</form>
<script at="Foot">
<script at="Foot" asp-name="credential-helpers"></script>
<script at="Foot" depends-on="credential-helpers">

document.addEventListener('DOMContentLoaded', () => {

const clientIdElement = document.getElementById('@Html.IdFor(m => m.ClientId)');
const clientSecretElement = document.getElementById('@Html.IdFor(m => m.ClientSecret)');
const toggleClientSecretElement = document.getElementById('toggleClientSecret');
const copyClientSecretElement = document.getElementById('copyClientSecret');
const copyClientIdElement = document.getElementById('copyClientId');
const generateClientIdElement = document.getElementById('generateClientId');
const generateClientSecretElement = document.getElementById('generateClientSecret');

toggleClientSecretElement.addEventListener('click', (e) => {
togglePasswordVisibility(clientSecretElement, toggleClientSecretElement)
});

copyClientIdElement.addEventListener('click', (e) => {
copyToClipboard(clientIdElement.value);
});

copyClientSecretElement.addEventListener('click', (e) => {
copyToClipboard(clientSecretElement.value);
});

generateClientIdElement.addEventListener('click', (e) => {
clientIdElement.value = randomUUID({ includeHyphens: false });
});

generateClientSecretElement.addEventListener('click', (e) => {
clientSecretElement.value = generateStrongPassword();
});
});

//<![CDATA[
window.onload = function () {
refreshForbiddenFlows();
Expand Down
Loading