Skip to content

WebStore is a full-stack ecommerce application powering the business of a fictional bookstore.

Notifications You must be signed in to change notification settings

memarino92/WebStore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WebStore

WebStore is a full-stack ecommerce application powering the business of a fictional bookstore. Its main purpose is to familiarize myself with an unfimiliar technology stack (Angular, ASP.NET, IdentityServer).

Main Technologies

Angular 12

.NET 6

ASP.NET

Entity Framework Core

Duende Identity Server v6

SQL Server

Git

Technical Overview

WebStore is composed of three main independant services - an Angular front-end client (written in Typescript, HTML and CSS), an ASP.NET REST API (written in C#), and an IdentityServer to issue tokens for user authentication and role-based access control to the API. All services have their configurations set through environment variables to allow the source to remain open without leaking sensitive variables or credentials.

Authentication is based on the OpenID Connect/OAuth2 specs using Duende IdentityServer to to issue JSON Web Tokens (JWT). Both the client and the API recognize IdentityServer as the "Token Authority" - the client receives tokens when a user logs in, and sends them along with requests to the API. The API then checks with the IdentityServer to make sure the token is valid before executing any restricted requests. Currently there 3 types of routes in the API: open routes (no restrictions on who can call), routes that must validate that the user is authenticated, and routes that only an authenticated user with the role of admin can call. A list of assigned user roles is included in the access token that is issued so that both the front end and the API can grant role-based access without extra calls to the API or database.

The API is built on the latest versions of .NET, ASP.NET and Entity Framework Core. The API and IdentityServer both share access to the same underlying database (SQL Server). IdentityServer uses the database to persist and read configuration and operational data. Catalog, cart, order and user data are persisted to and read from the database through the API. Email sending with a custom domain (no-reply@michaelmarino.dev) is enabled through SendGrid integration.

The API uses Swagger to publish a JSON schema of available types, along with controller endpoints and their parameters, which NSwag then uses to generate a Typescript client for the Angular application.

The frontend is built on Angular 12. It uses Tailwind CSS for layout and Material Design for Bootstrap as a component library. Cloudinary is used for image uploading, hosting and on-the-fly transformations.

During development a local SQL Server instance running in a Docker container is used.

The deployed application was previously available to preview at https://webstore.michaelmarino.dev, but was shut down to save cost. It used Netlify to host the front end, Railway to host containerized versions of both the API and IdentityServer instances, and Azure to host the SQL Server instance. Domain services were configured using Google Domains as the registrar and Cloudflare for DNS. All SSL certificates were generated and renewed automatically using Let's Encrypt. Deployments were entirely automated and configured to listen for changes to the main branch on GitHub.

Functionality

The home page displays the option to browse books by categories and a selection of featured books. The navbar will display user info if the user is authenticated or a link to login if they are not. The search input in the navbar will search books by title and author.

Once a user is logged in, they can add books to their cart and place an order, which records the order in the database and sends an email to their registered email address. Admin users can create new books, delete books, create new users with the option to make them admins as well, and reset user passwords. Admin users can upload images when creating new books which are then requested back in a specific size as needed at runtime.