Add project files.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
@using System.Reflection
|
||||
@using LiteCharmsSecurity.STS.Identity
|
||||
|
||||
@{
|
||||
var runtimeVersion = typeof(Startup)
|
||||
.GetTypeInfo()
|
||||
.Assembly
|
||||
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
}
|
||||
|
||||
@runtimeVersion
|
||||
@@ -0,0 +1,27 @@
|
||||
@using Microsoft.AspNetCore.Builder
|
||||
@using Microsoft.AspNetCore.Localization
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@using Microsoft.Extensions.Options
|
||||
@inject IViewLocalizer Localizer
|
||||
@inject IOptions<RequestLocalizationOptions> LocOptions
|
||||
@{
|
||||
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
|
||||
var cultureItems = LocOptions.Value.SupportedUICultures
|
||||
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
|
||||
.ToList();
|
||||
var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}{Context.Request.QueryString}";
|
||||
}
|
||||
@if (cultureItems.Count > 1)
|
||||
{
|
||||
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name" class="w-full md:w-auto">
|
||||
<form id="selectLanguageForm" asp-controller="Home"
|
||||
asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
|
||||
method="post" class="flex items-center gap-3" role="form">
|
||||
<label asp-for="@requestCulture.RequestCulture.UICulture.Name" class="text-sm font-medium text-muted-foreground whitespace-nowrap">
|
||||
<lucideicon name="languages" class="inline-block h-4 w-4 mr-1" />
|
||||
@Localizer["Language:"]
|
||||
</label>
|
||||
<select name="culture" id="cultureSelect" class="select min-w-[150px]" asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems"></select>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@model string
|
||||
@inject IViewLocalizer Localizer
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using LiteCharmsSecurity.STS.Identity.Configuration.Constants
|
||||
@inject IAuthorizationService AuthorizationService
|
||||
|
||||
@if ((await AuthorizationService.AuthorizeAsync(User, AuthorizationConsts.AdministrationPolicy)).Succeeded)
|
||||
{
|
||||
<a class="btn-outline my-2 inline-flex items-center gap-2" href="@Model">@Localizer["IdentityServerAdmin"]</a>
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
@using Microsoft.AspNetCore.Hosting
|
||||
@using Microsoft.Extensions.Hosting
|
||||
@model LiteCharmsSecurity.STS.Identity.ViewModels.Home.ErrorViewModel
|
||||
@inject IWebHostEnvironment Host
|
||||
|
||||
@{
|
||||
var error = Model?.Error?.Error;
|
||||
var errorDescription = Host.IsDevelopment() ? Model?.Error?.ErrorDescription : null;
|
||||
var request_id = Model?.Error?.RequestId;
|
||||
}
|
||||
|
||||
<div class="py-8">
|
||||
<h1 class="text-4xl font-bold mb-6">@Localizer["Title"]</h1>
|
||||
|
||||
<div class="max-w-2xl">
|
||||
<div class="alert-destructive">
|
||||
<lucideicon name="alert-circle" class="h-4 w-4" />
|
||||
<div>
|
||||
<h5 class="alert-title">@Localizer["Message"]</h5>
|
||||
<div class="alert-description">
|
||||
@if (error != null)
|
||||
{
|
||||
<strong>
|
||||
<em>
|
||||
: @error
|
||||
</em>
|
||||
</strong>
|
||||
|
||||
if (errorDescription != null)
|
||||
{
|
||||
<div class="mt-2">@errorDescription</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (request_id != null)
|
||||
{
|
||||
<div class="mt-4 text-sm text-muted-foreground">@Localizer["Request"] @request_id</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,9 @@
|
||||
@model LiteCharmsSecurity.STS.Identity.ViewModels.Account.RedirectViewModel
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
<div class="py-8 text-center">
|
||||
<h1 class="text-4xl font-bold mb-2">@Localizer["Title"]</h1>
|
||||
<p class="text-lg text-muted-foreground">@Localizer["SubTitle"]</p>
|
||||
</div>
|
||||
<meta http-equiv="refresh" content="0;url=@Model.RedirectUrl" data-url="@Model.RedirectUrl">
|
||||
<script src="~/js/signin-redirect.js"></script>
|
||||
@@ -0,0 +1,253 @@
|
||||
@using Duende.IdentityServer.Extensions
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@using LiteCharmsSecurity.Admin.EntityFramework.Shared.Entities.Identity
|
||||
@using LiteCharmsSecurity.STS.Identity.Configuration.Interfaces
|
||||
@using LiteCharmsSecurity.STS.Identity.Configuration
|
||||
@using Duende.IdentityServer
|
||||
@using Microsoft.Extensions.Options
|
||||
@inject IRootConfiguration RootConfiguration
|
||||
@inject IViewLocalizer Localizer
|
||||
@inject IOptions<ServerSideSessionsConfiguration> ServerSideSessionsOptions
|
||||
@{
|
||||
string name = null;
|
||||
if (!true.Equals(ViewData["signed-out"]))
|
||||
{
|
||||
name = Context.User?.GetDisplayName();
|
||||
}
|
||||
}
|
||||
@inject SignInManager<UserIdentity> SignInManager
|
||||
@{
|
||||
var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
|
||||
}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@RootConfiguration.AdminConfiguration.PageTitle</title>
|
||||
<link rel="icon" type="image/x-icon" href="@UrlHelper.Content(RootConfiguration.AdminConfiguration.FaviconUri)" />
|
||||
<link rel="shortcut icon" type="image/x-icon"
|
||||
href="@UrlHelper.Content(@RootConfiguration.AdminConfiguration.FaviconUri)" />
|
||||
<script src="~/js/theme-init.js" asp-append-version="true"></script>
|
||||
<link href="~/css/app.css" asp-append-version="true" rel="stylesheet" />
|
||||
@if (!string.IsNullOrEmpty(RootConfiguration.AdminConfiguration.CustomThemeCss))
|
||||
{
|
||||
<link href="@UrlHelper.Content(RootConfiguration.AdminConfiguration.CustomThemeCss)" asp-append-version="true"
|
||||
rel="stylesheet" />
|
||||
}
|
||||
@await RenderSectionAsync("styles", required: false)
|
||||
</head>
|
||||
|
||||
<body class="flex min-h-screen flex-col bg-background text-foreground">
|
||||
<header
|
||||
class="sticky top-0 z-50 border-b bg-background/80 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||
<nav class="container flex h-16 items-center">
|
||||
<a class="text-lg font-semibold tracking-tight hover:opacity-90" asp-area="" asp-controller="Home"
|
||||
asp-action="Index">
|
||||
@RootConfiguration.AdminConfiguration.PageTitle
|
||||
</a>
|
||||
<div class="ml-auto hidden items-center gap-4 md:flex">
|
||||
@if (User.Identity.IsAuthenticated && !string.IsNullOrEmpty(name))
|
||||
{
|
||||
<vc:identity-server-admin-link></vc:identity-server-admin-link>
|
||||
<details class="relative group">
|
||||
<summary class="list-none cursor-pointer select-none">
|
||||
<span class="btn-outline inline-flex items-center gap-2">
|
||||
<lucideicon name="cog" class="h-4 w-4" />
|
||||
<span>@Localizer["Settings"] - @name</span>
|
||||
<lucideicon name="chevron-down" class="h-4 w-4" />
|
||||
</span>
|
||||
</summary>
|
||||
<div class="card absolute right-0 mt-2 w-64 overflow-hidden">
|
||||
<div class="p-1">
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="Index">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="user" class="h-4 w-4" />
|
||||
@Localizer["ManageProfile"]
|
||||
</span>
|
||||
</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="PersonalData">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="id-card" class="h-4 w-4" />
|
||||
@Localizer["ManagePersonalData"]
|
||||
</span>
|
||||
</a>
|
||||
@if (hasExternalLogins)
|
||||
{
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="ExternalLogins">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="link-2" class="h-4 w-4" />
|
||||
@Localizer["ExternalLogins"]
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="TwoFactorAuthentication">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="shield-check" class="h-4 w-4" />
|
||||
@Localizer["2FA"]
|
||||
</span>
|
||||
</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="Passkeys">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="fingerprint" class="h-4 w-4" />
|
||||
@Localizer["Passkeys"]
|
||||
</span>
|
||||
</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="ChangePassword">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="key-round" class="h-4 w-4" />
|
||||
@Localizer["ChangePassword"]
|
||||
</span>
|
||||
</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Grants" asp-action="Index">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="badge-check" class="h-4 w-4" />
|
||||
@Localizer["Grants"]
|
||||
</span>
|
||||
</a>
|
||||
@if (ServerSideSessionsOptions.Value.Enabled)
|
||||
{
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="ServerSideSessions" asp-action="Index">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="box" class="h-4 w-4" />
|
||||
@Localizer["ServerSessionsMenu"]
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
<div class="my-1 h-px bg-border"></div>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-action="Logout" asp-controller="Account">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<lucideicon name="log-out" class="h-4 w-4" />
|
||||
@Localizer["Signout"]
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="btn-outline inline-flex items-center gap-2" asp-action="Login" asp-controller="Account">
|
||||
<lucideicon name="log-in" class="h-4 w-4" />
|
||||
@Localizer["Login"]
|
||||
</a>
|
||||
@if (RootConfiguration.RegisterConfiguration.Enabled)
|
||||
{
|
||||
<a class="btn-outline inline-flex items-center gap-2" asp-action="Register" asp-controller="Account">
|
||||
<lucideicon name="user-plus" class="h-4 w-4" />
|
||||
@Localizer["Register"]
|
||||
</a>
|
||||
}
|
||||
}
|
||||
<button id="theme-toggle" class="btn-ghost btn-icon" aria-label="Toggle theme">
|
||||
<span id="theme-toggle-dark-icon" class="hidden">
|
||||
<lucideicon name="moon" class="h-5 w-5" />
|
||||
</span>
|
||||
<span id="theme-toggle-light-icon" class="hidden">
|
||||
<lucideicon name="sun" class="h-5 w-5" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<details class="ml-auto md:hidden">
|
||||
<summary class="list-none">
|
||||
<button class="btn-outline inline-flex items-center gap-2">
|
||||
<lucideicon name="menu" class="h-5 w-5" />
|
||||
@Localizer["Menu"]
|
||||
</button>
|
||||
</summary>
|
||||
<div class="mt-3 space-y-2">
|
||||
@if (User.Identity.IsAuthenticated && !string.IsNullOrEmpty(name))
|
||||
{
|
||||
<vc:identity-server-admin-link></vc:identity-server-admin-link>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="Index">@Localizer["ManageProfile"]</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="PersonalData">@Localizer["ManagePersonalData"]</a>
|
||||
@if (hasExternalLogins)
|
||||
{
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="ExternalLogins">@Localizer["ExternalLogins"]</a>
|
||||
}
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="TwoFactorAuthentication">@Localizer["2FA"]</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="Passkeys">@Localizer["Passkeys"]</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Manage" asp-action="ChangePassword">@Localizer["ChangePassword"]</a>
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="Grants" asp-action="Index">@Localizer["Grants"]</a>
|
||||
@if (ServerSideSessionsOptions.Value.Enabled)
|
||||
{
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-controller="ServerSideSessions" asp-action="Index">@Localizer["ServerSessionsMenu"]</a>
|
||||
}
|
||||
<a class="block rounded-md px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||
asp-action="Logout" asp-controller="Account">@Localizer["Signout"]</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="btn-outline inline-flex items-center gap-2" asp-action="Login" asp-controller="Account">
|
||||
<lucideicon name="log-in" class="h-4 w-4" />
|
||||
@Localizer["Login"]
|
||||
</a>
|
||||
@if (RootConfiguration.RegisterConfiguration.Enabled)
|
||||
{
|
||||
<a class="btn-outline inline-flex items-center gap-2" asp-action="Register" asp-controller="Account">
|
||||
<lucideicon name="user-plus" class="h-4 w-4" />
|
||||
@Localizer["Register"]
|
||||
</a>
|
||||
}
|
||||
}
|
||||
<button id="theme-toggle-mobile" class="btn-ghost btn-icon" aria-label="Toggle theme">
|
||||
<span id="theme-toggle-dark-icon-mobile" class="hidden">
|
||||
<lucideicon name="moon" class="h-5 w-5" />
|
||||
</span>
|
||||
<span id="theme-toggle-light-icon-mobile" class="hidden">
|
||||
<lucideicon name="sun" class="h-5 w-5" />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</details>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div class="container flex-1 px-4 md:px-6">
|
||||
<main role="main" class="py-6">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="mt-auto border-t">
|
||||
<div class="container px-4 py-6 md:px-6">
|
||||
<div class="grid gap-6 md:grid-cols-3 md:items-center">
|
||||
<div class="space-y-1">
|
||||
<div class="font-semibold">@RootConfiguration.AdminConfiguration.PageTitle</div>
|
||||
<small class="text-muted-foreground">@Localizer["FooterCopyright"] @DateTime.Now.Year - @(await Html.PartialAsync("Common/ApplicationVersion"))</small>
|
||||
</div>
|
||||
<div></div>
|
||||
<div class="flex justify-center md:justify-end">
|
||||
@await Html.PartialAsync("Common/SelectLanguage")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="~/js/layout.js" asp-append-version="true"></script>
|
||||
<script src="~/js/language.js" asp-append-version="true"></script>
|
||||
@await RenderSectionAsync("scripts", required: false)
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,47 @@
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
@model LiteCharmsSecurity.STS.Identity.ViewModels.Consent.ScopeViewModel
|
||||
|
||||
<li class="border-b last:border-0 pb-4 last:pb-0">
|
||||
<div class="flex items-start justify-between gap-4">
|
||||
<div class="flex-1">
|
||||
@if (Model.Required)
|
||||
{
|
||||
<input type="hidden"
|
||||
name="ScopesConsented"
|
||||
value="@Model.Value" />
|
||||
}
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<strong class="font-semibold">@Model.DisplayName</strong>
|
||||
@if (Model.Emphasize)
|
||||
{
|
||||
<lucideicon name="alert-circle" class="h-4 w-4 text-destructive" />
|
||||
}
|
||||
</div>
|
||||
@if (Model.Required)
|
||||
{
|
||||
<div class="text-sm text-muted-foreground italic mb-1">
|
||||
@Localizer["Required"]
|
||||
</div>
|
||||
}
|
||||
@if (Model.Description != null)
|
||||
{
|
||||
<label for="scopes_@Model.Value" class="text-sm text-muted-foreground cursor-pointer">
|
||||
@Model.Description
|
||||
</label>
|
||||
}
|
||||
</div>
|
||||
<div class="flex items-center pt-1">
|
||||
<label class="switch">
|
||||
<input class="consent-scopecheck"
|
||||
type="checkbox"
|
||||
name="ScopesConsented"
|
||||
id="scopes_@Model.Value"
|
||||
value="@Model.Value"
|
||||
checked="@Model.Checked"
|
||||
disabled="@Model.Required" />
|
||||
<span class="switch-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -0,0 +1,14 @@
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@inject IViewLocalizer Localizer
|
||||
@if (ViewContext.ModelState.IsValid == false)
|
||||
{
|
||||
<div class="alert-destructive mb-6">
|
||||
<lucideicon name="alert-circle" class="h-4 w-4" />
|
||||
<div>
|
||||
<h5 class="alert-title">@Localizer["Title"]</h5>
|
||||
<div class="alert-description">
|
||||
<div asp-validation-summary="All"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
Reference in New Issue
Block a user