Add validation to RealmCreate
This commit is contained in:
parent
09480eb1e4
commit
ddbb1f42d7
16 changed files with 326 additions and 23 deletions
85
IdentityShroud.Core/Helpers/SlugHelper.cs
Normal file
85
IdentityShroud.Core/Helpers/SlugHelper.cs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
|
||||
namespace IdentityShroud.Core.Helpers;
|
||||
|
||||
public static class SlugHelper
|
||||
{
|
||||
public static string GenerateSlug(string text, int maxLength = 40)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return string.Empty;
|
||||
|
||||
// Normalize to decomposed form (separates accents from letters)
|
||||
string normalized = text.Normalize(NormalizationForm.FormD);
|
||||
|
||||
StringBuilder sb = new StringBuilder(normalized.Length);
|
||||
bool lastWasHyphen = false;
|
||||
|
||||
foreach (char c in normalized)
|
||||
{
|
||||
// Skip diacritics (accents)
|
||||
if (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.NonSpacingMark)
|
||||
continue;
|
||||
|
||||
char lower = char.ToLowerInvariant(c);
|
||||
|
||||
// Convert valid characters
|
||||
if ((lower >= 'a' && lower <= 'z') || (lower >= '0' && lower <= '9'))
|
||||
{
|
||||
sb.Append(lower);
|
||||
lastWasHyphen = false;
|
||||
}
|
||||
// Convert spaces, underscores, and other separators to hyphen
|
||||
else if (char.IsWhiteSpace(c) || c == '_' || c == '-')
|
||||
{
|
||||
if (!lastWasHyphen && sb.Length > 0)
|
||||
{
|
||||
sb.Append('-');
|
||||
lastWasHyphen = true;
|
||||
}
|
||||
}
|
||||
// Skip all other characters
|
||||
}
|
||||
|
||||
// Trim trailing hyphen if any
|
||||
if (sb.Length > 0 && sb[sb.Length - 1] == '-')
|
||||
sb.Length--;
|
||||
|
||||
string slug = sb.ToString();
|
||||
|
||||
// Handle truncation with hash suffix for long strings
|
||||
if (slug.Length > maxLength)
|
||||
{
|
||||
// Generate hash of original text
|
||||
string hashSuffix = GenerateHashSuffix(text);
|
||||
int contentLength = maxLength - hashSuffix.Length;
|
||||
|
||||
// Truncate at word boundary if possible
|
||||
int cutPoint = contentLength;
|
||||
int lastHyphen = slug.LastIndexOf('-', contentLength - 1);
|
||||
|
||||
if (lastHyphen > contentLength / 2)
|
||||
cutPoint = lastHyphen;
|
||||
|
||||
slug = slug.Substring(0, cutPoint).TrimEnd('-') + hashSuffix;
|
||||
}
|
||||
|
||||
return slug;
|
||||
}
|
||||
|
||||
private static string GenerateHashSuffix(string text)
|
||||
{
|
||||
using (var sha256 = SHA256.Create())
|
||||
{
|
||||
byte[] hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(text));
|
||||
|
||||
// Take first 4 bytes (will become ~5-6 base64url chars)
|
||||
string base64Url = WebEncoders.Base64UrlEncode(hash, 0, 4);
|
||||
return "-" + base64Url;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue