网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
@using Dpz.Core.Infrastructure
@model Dpz.Core.Public.Entity.Auth.DpzApplication?

@{
    ViewBag.Title = Model != null && Model.Id != default ? "编辑客户端" : "创建客户端";
    Layout = "_AdminLayout";
    var isEdit = Model != null && Model.Id != default;
    var selectedPermissions = (Model?.Permissions ?? new List<string>()).ToHashSet();
    var groups = AuthHelper.OpenIddictPermissionCache.Value;
}


<div class="page-header mb-3">
    <h1 class="mb-1">@(isEdit ? "编辑客户端" : "创建客户端")</h1>
    <p class="text-body-secondary">配置 OpenIddict 客户端的基础信息与回调地址</p>
    <div class="mt-2">
        <a class="btn btn-secondary btn-sm" href="@Url.Action("Index")">返回列表</a>
    </div>
    </div>

@if (TempData["message"] is string message)
{
    <div class="alert alert-danger" role="alert">@message</div>
}

<form method="post" asp-action="@(isEdit ? "Update" : "Create")" autocomplete="off" data-submit-loading="true" data-loading-target=".container-xxl">
    @if (isEdit)
    {
        <input type="hidden" name="Id" value="@Model!.Id"/>
    }

    <div class="row g-3">
        <div class="col-md-6">
            <label class="form-label" for="DisplayName">显示名称<span class="text-danger">*</span></label>
            <input id="DisplayName" name="DisplayName" class="form-control" value="@Model?.DisplayName" placeholder="用于展示的友好名称" required />
        </div>

        <div class="col-md-6">
            <label class="form-label" for="ClientId">ClientId<span class="text-danger">*</span></label>
            <input id="ClientId" name="ClientId" class="form-control" value="@Model?.ClientId" placeholder="唯一客户端标识" required @(isEdit ? "readonly" : null) />
            <div class="form-text">创建后不可修改</div>
        </div>

        @if (!isEdit)
        {
            <div class="col-md-6">
                <label class="form-label" for="ClientSecret">ClientSecret<span class="text-danger">*</span></label>
                <input id="ClientSecret" name="ClientSecret" class="form-control" placeholder="仅在创建时设置" value="@ApplicationTools.GenerateSecret()" />
                <div class="form-text">编辑时不允许修改</div>
            </div>
        }

        <div class="col-md-6">
            <label class="form-label" for="ApplicationType">应用类型</label>
            <input id="ApplicationType" name="ApplicationType" class="form-control" value="@Model?.ApplicationType" placeholder="如 web/native/spa" />
        </div>

        <div class="col-md-6">
            <label class="form-label" for="ClientType">客户端类型<span class="text-danger">*</span></label>
            @{
                var current = Model?.ClientType;
                var confidential = OpenIddict.Abstractions.OpenIddictConstants.ClientTypes.Confidential;
                var publicValue = OpenIddict.Abstractions.OpenIddictConstants.ClientTypes.Public;
            }
            <select id="ClientType" name="ClientType" class="form-select">
                @if (string.Equals(current, confidential, StringComparison.OrdinalIgnoreCase))
                {
                    <option value="@confidential" selected>@confidential</option>
                }
                else
                {
                    <option value="@confidential">@confidential</option>
                }

                @if (string.Equals(current, publicValue, StringComparison.OrdinalIgnoreCase))
                {
                    <option value="@publicValue" selected>@publicValue</option>
                }
                else
                {
                    <option value="@publicValue">@publicValue</option>
                }
            </select>
        </div>

        <div class="col-12">
            <label class="form-label" for="RedirectUris">重定向地址(分号;分隔)</label>
            <textarea id="RedirectUris" name="RedirectUris" class="form-control" placeholder="例如:https://example.com/callback;https://example.com/other">@Model?.RedirectUris</textarea>
            <div class="form-text">多个地址以分号分隔;将用于授权完成后的回调</div>
        </div>

        <div class="col-12">
            <label class="form-label" for="PostLogoutRedirectUri">登出重定向地址</label>
            <input id="PostLogoutRedirectUri" name="PostLogoutRedirectUri" class="form-control" value="@Model?.PostLogoutRedirectUri" placeholder="例如:https://example.com/logout-callback" />
        </div>

        <div class="col-12">
            <label class="form-label" for="Logo">客户端 Logo(URL)</label>
            <input id="Logo" name="logo" class="form-control" value="@(Model?.Properties?["Logo"]?.AsString)" placeholder="https://.../logo.png" />
            <div class="form-text">用于展示在授权页与列表页的图标</div>
        </div>

        <div class="col-12">
            <label class="form-label">权限</label>
            <div class="chip-groups">
                @foreach (var group in groups.OrderBy(g => g.Key, StringComparer.Ordinal))
                {
                    <div>
                        <div class="chip-group-title">@group.Key</div>
                        <div class="chips">
                            @foreach (var permission in group.Value)
                            {
                                var inputId = $"perm_{Math.Abs(permission.GetHashCode())}";
                                var isChecked = selectedPermissions.Contains(permission);
                                <label class="chip" for="@inputId">
                                    <input type="checkbox" id="@inputId" name="PermissionsSelection" value="@permission" @(isChecked ? "checked" : null) />
                                    <span class="chip-text">@permission</span>
                                </label>
                            }
                        </div>
                    </div>
                }
            </div>
            <div class="form-text">从内置 OpenIddict 权限中选择需要的项,可多选</div>
        </div>

        <div class="col-md-4">
            <label class="form-label" for="pinCode">2FA PIN<span class="text-danger">*</span></label>
            <input id="pinCode" name="pinCode" class="form-control" placeholder="6位验证码" inputmode="numeric" pattern="[0-9]{6}" maxlength="6" required />
        </div>
    </div>

    <div class="d-flex justify-content-end gap-2 mt-3">
        <a class="btn btn-secondary" href="@Url.Action("Index")">返回</a>
        <button type="submit" class="btn btn-primary" data-loading-text="正在保存...">@(isEdit ? "保存修改" : "创建客户端")</button>
    </div>
</form>

<div class="footer">
    <p>请合理配置回调地址与权限,避免泄露敏感信息</p>
</div>


@section Scripts {
    <script src="@Url.Content("~/js/ui-components.js")" asp-append-version="true"></script>
    <script src="@Url.Content("~/js/application-upsert.js")" asp-append-version="true"></script>
}
loading