November 1st, 2021

SaintsXCTF Version 2.0: React Web Application Overview







This is part of a series of articles on SaintsXCTF Version 2.0. The first article in the series provides an overview of the application.

At its core, SaintsXCTF is a web application that allows users to log their running workouts, openly express how they felt while running, and encourage and support teammates. From a user perspective, the website is the most important part of the SaintsXCTF technology stack, since it is what they interact with every day and depend on being operational.

When I wrote the first version of the website, I was a senior in college who just began learning web development. I was also new to user interface (UI) design and user experience (UX) design. Over time, this inexperience became more and more apparent when viewing the first version of the website and its underlying code. While designing the second version of the website, I knew not only did I need to follow best engineering practices, but I also had to make an elegant user interface.

The next five articles in the SaintsXCTF series are devoted solely to the website and its React codebase. This article gives an overview of the technologies used in the frontend code and a walkthrough of the pages on the website.

Version 2.0 of the SaintsXCTF web application uses the React.js frontend library. For stylesheets, it uses JSS (CSS in JavaScript). Redux is leveraged for state management within the application. For testing, Jest is utilized for unit, integration, and snapshot tests. Cypress is utilized for end to end (E2E) tests.

When I first started creating version 2.0 of the web application, I wrote all the React, Redux, and JSS code in JavaScript. However, after further consideration, I decided to pivot towards writing all the frontend code in TypeScript. TypeScript is a superset of JavaScript with static type checking and additional language features. Nowadays, I often use TypeScript instead of JavaScript to make my code safer and less prone to subtle bugs. With SaintsXCTF, version 2.0 was a great opportunity to finally use TypeScript in a production application. Alongside the application code, the Jest and Cypress test code is also written in TypeScript.

The React application is bundled for distribution with Webpack. Locally, the application is run either with Webpack Dev Server or Docker. In production, the application runs on a Docker container. The Docker container configures and runs an Nginx server, which routes requests to the React code bundle. This Docker container is orchestrated using Kubernetes and is part of a larger AWS infrastructure.

Upcoming articles look at the web application code in detail, but the codebase is also accessible on GitHub in a saints-xctf-web repository.

There are two main sections of the website: when there is no user session and when a user is signed in. When there is no user session, the landing page is the home page:

When there is a user session, the landing page is the dashboard page:

User sessions are determined by a JWT in the browser's localStorage. JWT tokens are passed along with all API requests for authentication. If the JWT is expired or an API call results in an unauthenticated error, the JWT is removed and the user is signed out.

A signed out user has the option to sign in or register. Both sign in and registration have their own pages.

As shown previously, signed in users are navigated to a dashboard page, which shows the latest exercise logs. It also gives them multiple navigation options. Since the main purpose of the website is to allow users to write exercise logs, there is a page with an exercise log form.

Each user has a profile page. A profile page consists of multiple tabs, each showing a different view to the user. Tabs include exercise logs, statistics, a weekly chart, and a monthly calendar.

If the profile page corresponds to the signed in user, an additional administrative tab is viewable, allowing the user to edit their profile.

Each user is a member of zero to many teams, and each team consists of one or many groups. These groups also get their own pages with multiple tabs. One way to navigate to a group page is by clicking on the Teams link in the navigation bar, which displays all the teams the user is a member of and the corresponding groups.

From here, group pages are accessible. For example, the following screenshots show all the tabs on the Alumni group page within the team St. Lawrence Cross Country and Track & Field.

The website also has an admin feature, where certain users are designated as administrators for specific groups. If a user is an administrator, they can access a separate section of the website. The admin section starts with a page that lists all the groups for which the user is an administrator.

From this page, group admin pages are selectable. Group admin pages have multiple tabs, giving users different ways to alter the group, change memberships, and invite new users to the website.

I'm really proud to see all my hard work pay off with the new version of In the next couple articles, I'll look at the technical details of the website in more detail. If you want a preview of the code, you can view the saints-xctf-web repository on GitHub.