Skip to content

Repository files navigation

πŸš€ ToDoApp β€” ASP.NET Core Web API

Release Downloads Last Commit Repo Size Top Language

A modern and production-ready ToDo Web API built with ASP.NET Core, Clean Architecture, JWT Authentication, PostgreSQL, and Docker.

This project was designed as a scalable backend foundation for a notes / task management platform with secure authentication, domain separation, infrastructure isolation, and automated unit testing.


✨ Features

πŸ” Authentication & Security

  • JWT Authentication
  • JWT stored in secure HttpOnly Cookies
  • User logout with JWT cookie invalidation
  • Argon2 password hashing
  • Authorization using .RequireAuthorization()
  • Global exception handling middleware
  • Secure cookie policy configuration
  • HTTPS support

πŸ“ Notes System

  • Create notes
  • Update notes
  • Delete notes
  • Get all notes for authenticated user
  • Get note by ID
  • One-to-many relationship between users and notes
  • Attach tags to notes
  • Get all notes of authenticated user by tag
  • Detach tags from notes
  • Multiple tags can be attached to a single note
  • Note visibility authorization based on account visibility settings
  • Access to public notes, private notes, and notes of friends
  • Friendship-based access control using accepted friendships
  • Filtering notes based on the authenticated user's permissions

πŸ“ Tags System

  • Create tags
  • Update tags
  • Delete tags
  • Get all tags for authenticated user
  • Get tag by ID
  • Many-to-many relationship between notes and tags
  • Attach tags to notes
  • Detach tags from notes
  • User-owned tags
  • Tag ownership validation
  • Prevention of duplicate tag attachments

πŸ‘€ Users System

  • User registration
  • User login
  • User logout
  • Delete own account
  • Get info about current authenticated user
  • Get all users
  • Get user by ID
  • User account visibility settings (Public, Private, OnlyForFriends)
  • Change account visibility

🀝 Friendship System

  • Send friend requests
  • Accept friend requests
  • Reject friend requests
  • Remove friends
  • View all friends
  • View incoming friend requests
  • Friendship status management (Pending, Accepted, Rejected)

πŸ§ͺ Automated Testing

The project includes a dedicated unit testing suite built with xUnit, FluentAssertions, and Moq.

Tested Features

  • User registration
  • User authentication
  • Note creation
  • Note retrieval
  • Note retrieval by tag
  • Note updating
  • Note deletion
  • Account visibility changes
  • Note visibility authorization
  • Access control based on friendship status
  • Filtering notes by visibility permissions
  • Tag creation
  • Tag retrieval
  • Tag updating
  • Tag deletion
  • Tag attachment to notes
  • Tag detachment from notes
  • Friend requests
  • Friend request acceptance
  • Friend request rejection
  • Friend removal
  • Friendship retrieval
  • Account deletion
  • Validation and error scenarios

Testing Stack

Technology Purpose
xUnit Test framework
FluentAssertions Readable assertions
Moq Mocking dependencies

Tests primarily target Application Layer use cases and handlers, isolating business logic from external infrastructure.


πŸ— Architecture

  • Clean Architecture
  • Domain-Driven Design principles
  • CQRS-like Use Cases / Handlers
  • Repository Pattern
  • Unit Of Work Pattern
  • DTO separation
  • Value Objects
  • Result / Error pattern
  • Authorization services

🧱 Project Structure

ToDoApp
β”‚
β”œβ”€β”€ ToDoApp.Domain          β†’ Core business entities and value objects
β”œβ”€β”€ ToDoApp.Application     β†’ Use cases, DTOs, interfaces, business logic
β”œβ”€β”€ ToDoApp.Infrastructure  β†’ Database, repositories, authentication, persistence
β”œβ”€β”€ ToDoApp.WebApi          β†’ Minimal API endpoints and application entry point
β”‚
β”œβ”€β”€ ToDoApp.Application.Tests
β”‚   β”œβ”€β”€ Users               β†’ User use case tests
β”‚   β”œβ”€β”€ Notes               β†’ Note use case tests
β”‚   β”œβ”€β”€ Tags                β†’ Tag use case tests
β”‚   └── Friendships         β†’ Friendship use case tests
β”‚
β”œβ”€β”€ nginx                   β†’ Nginx reverse proxy configuration
β”œβ”€β”€ docker-compose.dev.yaml
β”œβ”€β”€ docker-compose.prod.yaml
└── Dockerfile

🧠 Architecture Overview

The project follows a layered Clean Architecture approach:

Domain Layer

Contains:

  • Entities
  • Value Objects
  • Core business rules

This layer has zero dependencies on external frameworks.


Application Layer

Contains:

  • Use Cases
  • DTOs
  • Repository Interfaces
  • Authorization Services
  • Friendship-aware authorization
  • Visibility-based access control
  • Validation
  • Result/Error abstractions

Business logic lives here.


Infrastructure Layer

Contains:

  • Entity Framework Core
  • PostgreSQL integration
  • JWT token generation
  • Argon2 password hashing
  • Repository implementations
  • Dependency Injection configuration

Web API Layer

Contains:

  • Minimal API endpoints
  • Authentication setup
  • Middleware configuration
  • Swagger
  • HTTP concerns
  • Centralized JWT claims access
  • Rate limiting configuration

πŸ§ͺ Testing Architecture

Unit tests are separated from the production application and focus primarily on the Application Layer.

ToDoApp.Application.Tests
β”‚
β”œβ”€β”€ Users
β”‚   β”œβ”€β”€ CreateUserHandlerTests
β”‚   β”œβ”€β”€ LoginUserHandlerTests
β”‚   β”œβ”€β”€ ChangeUserVisibilityHandlerTests
β”‚   └── DeleteMyAccountHandlerTests
β”‚
β”œβ”€β”€ Notes
β”‚   β”œβ”€β”€ CreateNoteHandlerTests
β”‚   β”œβ”€β”€ GetNoteHandlerTests
β”‚   β”œβ”€β”€ GetNotesHandlerTests
β”‚   β”œβ”€β”€ GetUserNotesByTagHandlerTests
β”‚   β”œβ”€β”€ NotesAuthorizationServiceTests
β”‚   β”œβ”€β”€ UpdateNoteHandlerTests
β”‚   β”œβ”€β”€ DeleteNoteHandlerTests
β”‚   β”œβ”€β”€ AttachTagToNoteHandlerTests
β”‚   └── DetachTagFromNoteHandlerTests
β”‚
β”œβ”€β”€ Tags
β”‚   β”œβ”€β”€ CreateNewTagHandlerTests
β”‚   β”œβ”€β”€ GetAllMyTagsHandlerTests
β”‚   β”œβ”€β”€ GetMyTagByIdHandlerTests
β”‚   β”œβ”€β”€ UpdateTagHandlerTests
β”‚   └── DeleteTagHandlerTests
β”‚
└── Friendships
    β”œβ”€β”€ SendFriendRequestHandlerTests
    β”œβ”€β”€ AcceptFriendRequestHandlerTests
    β”œβ”€β”€ RejectFriendRequestHandlerTests
    β”œβ”€β”€ RemoveFriendHandlerTests
    └── GetFriendsHandlerTests

The tests use mocks to isolate application logic from repositories, unit-of-work implementations, logging, and other external dependencies.

This allows individual use cases to be tested independently and deterministically.


πŸ›  Tech Stack

Technology Description
ASP.NET Core Web API framework
.NET 10 Runtime
Entity Framework Core ORM
PostgreSQL Database
JWT Authentication
Argon2 Password hashing
Docker Containerization
Nginx Reverse proxy
Serilog Structured logging
Swagger/OpenAPI API documentation
xUnit Unit testing
FluentAssertions Test assertions
Moq Mocking

πŸ”‘ Authentication Flow

  1. User registers or logs in
  2. Server generates JWT token
  3. JWT is stored in secure HttpOnly cookie
  4. Authorized endpoints validate token automatically
  5. User identity is extracted from JWT claims
  6. User can log out by invalidating the JWT cookie

πŸ“Œ API Endpoints

Authentication

Method Endpoint Description
POST /Auth/Register Register new user
POST /Auth/Login Login user
POST /Auth/Logout Logout and remove JWT cookie

Users

Method Endpoint Description
GET /Users Get all users
GET /Users/{id} Get user by ID
GET /Users/Me Get current authenticated user info
DELETE /Users/Me Delete current authenticated user

Notes

Method Endpoint Description
GET /Notes Get all visible notes
GET /Notes/{id} Get note by ID
GET /Notes/Me Get all notes of authenticated user
GET /Notes/Me/Tags/{tagId} Get authenticated user's notes by tag
POST /Notes Create new note
PUT /Notes/{id} Update note
DELETE /Notes/{id} Delete note
POST /Notes/{noteId}/Tags/{tagId} Attach tag to note
DELETE /Notes/{noteId}/Tags/{tagId} Detach tag from note

Tags

Method Endpoint Description
GET /Tags/Me Get all tags of authenticated user
GET /Tags/Me/{id} Get tag by ID
POST /Tags Create new tag
PUT /Tags/{id} Update tag
DELETE /Tags/{id} Delete tag

Friendships

Method Endpoint Description
GET /Friends Get all friends
GET /Friends/Incoming Get incoming friend requests
POST /Friends/{friendId} Send friend request
PUT /Friends/{friendId}/Accept Accept friend request
PUT /Friends/{friendId}/Reject Reject friend request
DELETE /Friends/{friendId} Remove friend

Health Check

Method Endpoint
GET /health

🐳 Running With Docker

Development

docker compose -f docker-compose.dev.yaml up

Production

docker compose -f docker-compose.prod.yaml up -d

⚑ Local Development

1. Clone Repository

git clone <repository-url>
cd ToDoApp

2. Start Development Environment

docker compose -f docker-compose.dev.yaml up --build

3. Run Application

dotnet run --project ToDoApp.WebApi

πŸ§ͺ Running Tests

Run the complete test suite with:

dotnet test

To run tests with detailed output:

dotnet test --verbosity normal

πŸ“š Swagger UI

Swagger is enabled automatically.

After launching the application open:

localhost/

or

localhost:5000/

πŸ—ƒοΈ Seq (logs)

Seq is enabled automatically.

After launching the application open:

localhost:5341

User - Admin Password - Admin


πŸ”’ Security Notes

The application uses:

  • Secure HttpOnly cookies
  • Strict SameSite policy
  • HTTPS-only cookies
  • Argon2 password hashing
  • JWT validation
  • Centralized exception handling
  • Centralized user ID extraction from JWT claims
  • Rate limiting to restrict excessive requests
  • Friendship-aware authorization for protected notes

πŸ“„ License

This project is licensed under the MIT License.

See LICENSE.txt for more information.


πŸ‘¨β€πŸ’» Author

Developed by ArGul.

If you like this project β€” consider giving it a ⭐ on GitHub.

Releases

Packages

Used by

Contributors

Languages