Skip to content

Architectural Decisions

Flacial edited this page Aug 22, 2022 · 7 revisions

Code Quality

c0d3.com Scale / High Availability

To understand how to scale, we decided to focus on the following components:

  • c0d3.com - the main site for users to learn, study, review submissions.
  • chat.c0d3.com - chat site for users to ask for help and chat with other users (users will spend the majority of their time here)
  • git.c0d3.com - repository management for user's projects. It will use for central authentication systems.

Problems to address

  • In v1 of c0d3.com, there are 3 accounts created for each user (chat, gitlab, and c0d3.com). This created a problem where users end up with different usernames/passwords across chat, GitLab, and c0d3.com.
  • Scale: We want to scale each component independently of each other because they get different usage.

Conclusion

  • We want 1 central authority for user information. Gitlab currently offers the most robust system. Since this service will receive the lowest traffic, we need 2 instances: One for main production use and another for redundancy.
  • c0d3.com will be serverless, so we can use it as needed.
  • chat.c0d3.com: This is most heavily used by users, getting around 600-1000 messages/day with only 30 active users. We want chat to scale across a Kubernetes cluster.

Demo

  • We got a working authentication service (proof of concept, not polished):

c0d3.com Signup / Login Workflow

Link to c0d3.com login / register notes
c0d3.com needs a way to interact with users, sign the users for GitLab and MatterMost service, and a way to track their progress through the curriculum.

Purpose

The purpose of this document is to discuss the flow and layout for Login / SignUp for c0d3.com

Register

Inputs

Register Input

Register Input

Errors:

If the username or email is unavailable, the user should see immediate feedback below in the input

Register errors

The user should see one of two error messages:

  • Username / email is not available. You probably already have an account Try Logging In!
  • Invalid Format

Typing Validation

Client

  • The client sends debounced request (500ms) to the server endpoint /validateFields to check availability of username and email.

      fetch(`${SERVER_URL}/validateFields`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ username: value, email: value })
      });
    
  • The client takes server response and either display in green Valid or in red Invalid + Condition for email and User Name

  • For confirm password, the client should validate whether the password and confirm password match.

  • Formik will be used to validate the required pattern and required fields.

    • Alternatively, HTML5 can be used to speed up custom field validation depending on implementation validation

Server

  • Server checks if the email, password and email is using the correct format.

    • username: /[a-z0-9]{2}/
      • only lowercase, alphanumeric and more than 2 characters
    • password: /[a-zA-Z0-9]{2,64}/
    • email: /^[a-zA-Z0-9.!#$%&’*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$/`
  • Server checks whether the username exists in the database, on Mattermost or on GitLab and sends response

      { 
      	valid: true / false, 
      	message: 'error message' 
      }
    
  • Server checks whether em

Submission Validation:

Client

The form should send a POST request to /register on the backend endpoint. The current endpoint is /signup. We are using a different endpoint so the code can be merged into the codebase without breaking the existing code. The password should be encoded before being sent to the server.

fetch(`${SERVER_URL}/register`, {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json'
	},
	body: JSON.stringify({
		username,
		fullName,
		password: btoa(password),
		email
		})
})

If the response is validated, the server should redirect user to confirm email link.

Server

The server should take the information and inserts the information into the db.

Prior to doing any database queries, the server must check for the following:

  • All fields are not empty
  • All fields are valid using RegExp
  • No existing username in database, MatterMost, and GitLab

Server returns

{
  success: true / false,
  errors: {
    username: 'error message for username',
    password: 'error message for password',
  }
	username: 'the username that was created'
}

Login

Inputs

Login Form

Errors

Login errors

Errors are returned from the server and displayed on a warning div

Typing Validation

Not required

Submission Validation

Client

  • Checks for any empty fields using HTML5

  • Encodes password before sending POST request.

    fetch(${SERVER_URL}/login, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: { JSON.stringify({ username, // or email password: btoa(password) }) } })

The client will redirect the user to reconfirm the email page if the email is not confirmed.

Otherwise, the client will redirect the user to the c0d3.com home page.

Server

  • Check for any empty fields
  • Checks database for existing username
  • Validates user-entered password matches
  • The server should validate whether the user has confirmed the email.

Current Implementation

{
	success: true / false,
	user: // Information from Passport Local
}

The decision to keep current implementation