Skip to content

Identity, JWT auth and tenant scoping - #1

Merged
navaneeth06 merged 18 commits into
mainfrom
feature/identity-and-employees
Nov 9, 2026
Merged

navaneeth06 merged 18 commits into
mainfrom
feature/identity-and-employees

Conversation

@navaneeth06

Copy link
Copy Markdown
Owner

No description provided.

- Employee domain entity with deactivate/reactivate/anonymise rules
- ApplicationUser on Identity with GUID keys, linked to tenant
- Partial unique index: an email belongs to at most one active account
- Unit tests for employee rules; integration tests for email uniqueness
- IIdentityService in Application hides ASP.NET Core Identity types
- Duplicate active email detected from the database unique index (race-safe)
- Expected failures returned as results; integration tests for each outcome
- POST /api/v1/auth/register creates tenant, owner login and Administrator employee
- Single transaction via IUnitOfWork; failure at any step rolls back
- 409 for email already active elsewhere, 400 for validation/password policy
Tenants are now created only via POST /api/v1/auth/register together with
their owner. Tenant tests seed data through the DbContext instead.
- ITokenService issues HS256 access tokens with sub, employee_id, tenant_id, role and jti
- JwtOptions validated at startup; signing key from user-secrets/env vars, never in appsettings
- TimeProvider injected so expiry is unit-testable
- POST /api/v1/auth/login returns a JWT for the single active account with that email
- Lockout after 5 failures; checked before the password
- Same 401 for unknown email, wrong password, inactive or locked account; 403 for suspended distributor
- Validates issuer, audience, signature, lifetime; HS256 only; 30s clock skew
- Claim names kept as issued (MapInboundClaims = false)
- GET /api/v1/me proves end to end; tests for missing, tampered, foreign-key, expired and wrong-audience tokens
AddApplication, AddInfrastructure, AddApiControllers and AddJwtAuthentication keep each
layer's wiring next to its code. No behaviour change.
ICurrentTenant reads tenant_id only from the request's signed JWT;
returns null for anonymous requests (login, register).
- Employee queries are filtered by the current tenant from the JWT; no tenant sees nothing
- Login lookup explicitly ignores the filter (no tenant before login)
- Isolation tests (A cannot see B) and a model test requiring a filter on every TenantId entity
- GET/PUT /api/v1/tenant read the tenant from the JWT; no id in the route
- Update restricted to Administrator; IsActive no longer client-settable
- Removed list-all and deactivate endpoints (platform-level, not per distributor)
- Fallback authorization policy requires an authenticated user on every endpoint
- Health check and OpenAPI explicitly opt out with AllowAnonymous
- Test lists the exact set of public endpoints so new ones are reviewed
@navaneeth06
navaneeth06 merged commit 36cf174 into main Nov 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant