Merge branch 'main' of https://git.azuze.fr/kawa/SharepointToolbox-Web
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Antiforgery;
|
||||
|
||||
namespace SharepointToolbox.Web.Infrastructure.Auth;
|
||||
|
||||
/// <summary>Renders the combined login page (Microsoft / Entra button + local credential form)
|
||||
/// as a self-contained static HTML response. Lives outside the interactive Blazor circuit so
|
||||
/// the POST handler can issue the auth cookie directly on the HTTP request.</summary>
|
||||
public static class LoginPageRenderer
|
||||
{
|
||||
public static string Build(
|
||||
HttpContext ctx,
|
||||
IAntiforgery antiforgery,
|
||||
string? returnUrl,
|
||||
bool showError,
|
||||
bool showEntra = true,
|
||||
bool showDevButton = false)
|
||||
{
|
||||
var tokens = antiforgery.GetAndStoreTokens(ctx);
|
||||
var ru = WebUtility.HtmlEncode(returnUrl ?? "/");
|
||||
var afField = WebUtility.HtmlEncode(tokens.FormFieldName);
|
||||
var afToken = WebUtility.HtmlEncode(tokens.RequestToken);
|
||||
|
||||
var error = showError
|
||||
? "<div class=\"alert alert-error\">Invalid email or password.</div>"
|
||||
: string.Empty;
|
||||
|
||||
var entraButton = showEntra
|
||||
? $"<a class=\"btn btn-secondary btn-block\" href=\"/account/login/entra?returnUrl={ru}\">Sign in with Microsoft</a><div class=\"login-divider\">or</div>"
|
||||
: string.Empty;
|
||||
|
||||
var devButton = showDevButton
|
||||
? $"<div class=\"login-divider\">dev</div><a class=\"btn btn-secondary btn-block\" href=\"/account/login/dev?returnUrl={ru}\">Quick sign in as Dev Admin</a>"
|
||||
: string.Empty;
|
||||
|
||||
return $$"""
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Sign in — SharePoint Toolbox</title>
|
||||
<link rel="stylesheet" href="/app.css" />
|
||||
<style>
|
||||
body { display:flex; align-items:center; justify-content:center; min-height:100vh; margin:0; background:var(--bg); }
|
||||
.login-card { width:360px; max-width:92vw; }
|
||||
.login-card h1 { font-size:20px; margin:0 0 4px; color:var(--text); }
|
||||
.login-card .sub { font-size:13px; color:var(--text-muted); margin:0 0 18px; }
|
||||
.login-divider { display:flex; align-items:center; gap:10px; color:var(--text-muted); font-size:12px; margin:18px 0; }
|
||||
.login-divider::before, .login-divider::after { content:""; flex:1; height:1px; background:var(--border); }
|
||||
.field { margin-bottom:12px; }
|
||||
.btn-block { width:100%; justify-content:center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card login-card">
|
||||
<h1>SharePoint Toolbox</h1>
|
||||
<p class="sub">Sign in to continue</p>
|
||||
{{error}}
|
||||
{{entraButton}}
|
||||
<form method="post" action="/account/local-login">
|
||||
<input type="hidden" name="returnUrl" value="{{ru}}" />
|
||||
<input type="hidden" name="{{afField}}" value="{{afToken}}" />
|
||||
<div class="field">
|
||||
<label class="form-label" for="email">Email</label>
|
||||
<input class="form-input" id="email" name="email" type="email" autocomplete="username" required autofocus />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="form-label" for="password">Password</label>
|
||||
<input class="form-input" id="password" name="password" type="password" autocomplete="current-password" required />
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" type="submit">Sign in</button>
|
||||
</form>
|
||||
{{devButton}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user