Add project files.

This commit is contained in:
Khwezi Mngoma
2026-06-05 22:07:25 +02:00
parent 59ea7de742
commit 437e8c5c08
978 changed files with 151911 additions and 0 deletions
@@ -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>
}
@@ -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>
}