Authentication v1

Authors: @szainmehdi
Type: Feature

Overview

This phase of Authentication covers allowing Moderators to login to the site and manage content.

Definitions

Term Definition
Engineer A person with code & infrastructure control.
Moderator A privileged user with full edit and approval rights.
Contributor A standard user that has limited edit rights.
User Either a Moderator or a Contributor

Why are we making this change?

To achieve the greater effort of allowing public edit access on Nawhas.com, enabling moderators to log in is a prerequisite. This change will also lay the foundation for the overall authentication system and enable Contributor registration and logins in the future.

Requirements

Detailed Engineering Design

API

New Endpoints

We’ll add three new endpoints to the API:

POST /v1/auth/login
{
  "email": string,
  "password": string,
  "remember": ?bool,
}
RESPONSES
  - 200: Logged in
         { user: { ... } }
ERRORS
  - 401: Invalid credentials
         { message: "..." }
  - 422: Invalid request
         { message: "...", "errors": { email: "...", ... } }

[guard:auth]
POST /v1/auth/logout
RESPONSES
  - 204: No content
  - 401: Unauthorized
         { message: "..." }

[guard:auth]
GET /v1/auth/user
RESPONSES
  - 200: User in session
         { user: { ... } }
  - 401: Unauthorized
         { message: "..." }

User Entity

We’ll add a new User entity with the following fields.

private UuidInterface $id;
private string $name;
private ?string $nickname;
private Role $role;
private string $email;
private string $password;
private ?string $rememberToken;

Role above refers to an enum with two possible values as of now:

public const MODERATOR = 'moderator';
public const CONTRIBUTOR = 'contributor';

This should be sufficient for now.

Caveats

We’ll utilize Laravel Airlock for the basics of SPA authentication. A few caveats:

This solution only works if the SPA (the frontend) and the API (the backend) are on the same top-level domain (i.e. nawhas.com)

Frontend

We’ll be replacing the existing auth store with a new one, and hooking up a couple components.

Vuex Store

A new auth store written in Typescript will be created and replace the existing (outdated and unused) auth store.

State
// Store the user object
user: object|null;

// Used to determine if the first auth check has completed.
initialized: bool = false;
Mutations
Getters
Actions

App.vue

When the frontend loads for the first time, we’ll dispatch the auth/check action to initialize the auth store and grab a CSRF cookie.

UserMenu Component

We’ll add a new UserMenu component that will be responsible for drawing the current auth state along with relevant auth actions.

This component will be rendered into the app navbar in Public.vue

LoginForm Component

A LoginForm component will handle the processes of:

Deployment Strategy

This code should be safe to roll out to 100% of users. The API changes will go out first, and the frontend will go out after a successful API deploy.

Mockups

incorrect invalid login moderator