familynido/src/FamilyNido.Api/Features/Auth/PasswordPolicy.cs
Pablo Fernández a308041d59 Initial commit
FamilyNido — a self-hosted PWA for a single household: shared calendar,
chores, meals, school agenda, health records and a family wall. One
instance per family, deployable with `docker compose` on any home
server.

Stack: .NET 10 (ASP.NET Core Minimal APIs) + EF Core 10 + PostgreSQL 16
on the backend, Angular 21 (standalone, signals, zoneless) + Tailwind
CSS v4 on the frontend, SignalR for realtime, optional OIDC alongside
local credentials, integration via a versioned `/api/v1/**` public API.

See README.md for the module overview and how to deploy.
2026-05-13 00:23:14 +02:00

32 lines
1.2 KiB
C#

using FluentValidation;
namespace FamilyNido.Api.Features.Auth;
/// <summary>
/// Centralized password complexity requirements. Plain enough to remember,
/// strict enough to keep the obvious "1234" / "password" attacks out.
/// Reused by both <see cref="SetLocalPassword"/> and the invitation
/// "accept-local" path.
/// </summary>
internal static class PasswordPolicy
{
/// <summary>Minimum number of characters.</summary>
public const int MinLength = 8;
/// <summary>Maximum length we ever accept (defends the hash function from absurd inputs).</summary>
public const int MaxLength = 256;
/// <summary>
/// Rule helper used by FluentValidation builders.
/// Requires length, at least one letter, and at least one digit.
/// </summary>
public static IRuleBuilderOptions<T, string> Password<T>(this IRuleBuilder<T, string> rule)
{
return rule
.NotEmpty()
.MinimumLength(MinLength).WithMessage($"Password must be at least {MinLength} characters.")
.MaximumLength(MaxLength)
.Must(s => s.Any(char.IsLetter)).WithMessage("Password must contain at least one letter.")
.Must(s => s.Any(char.IsDigit)).WithMessage("Password must contain at least one digit.");
}
}