Skip to content

Login and Token Endpoints

Common Headers:

For any request with a body it is assumed that this header exists:

1
  Content-Type: application/json

Access Token Composition:

1
2
3
4
{
    "userId": INT,
    "adminLevel": INT
}
  • adminLevel: integer describing the user's privilege level.
    • 0: General Public (GP)
    • 1: Participating Family (PF)
    • 2: Admin

Note:

For any protected route, if the access token included in the request header is expired the backend will return a 401 with the following text indicating that a refresh is necessary.

1
 "Given access token is expired or invalid"

Unprotected Routes

These routes are called by a user that is not yet authenticated.

**These routes all have the prefix api/v1/

POST user/login

Used for logging in.

Request

Body:

1
2
3
4
{
    "email" : EMAIL,
    "password" : STRING
}
An EMAIL is a string representing a user's email.

Responses

201 Created

The username/password combination is valid. Includes distinct access and refresh tokens for the given user.

Body:

1
2
3
4
{
  "accessToken"  : JWT,
  "refreshToken" : JWT
}

400 Bad Request

Malformed request.

401 Unauthorized

The username/password combination is invalid.

POST user/login/refresh

Used for getting a new access token.

Request

Headers:

1
  X-Refresh-Token : JWT

Responses

201 Created

The refresh token is valid and has not yet expired. Response includes a new unique access_token.

Body:

1
2
3
{
  "accessToken" : JWT,
}

401 Unauthorized

The refresh token is invalid.

DELETE user/login

Used for logging out.

Request

Headers:

1
2
  X-Access-Token : JWT
  X-Refresh-Token : JWT

Responses

204 No Content

Logout successful.

POST user/signup

Used for signing up a new user.

Users will be given the access level of a GP from this route. Users signing up as PF should follow this call with a call to /protected/users/signup/pf to sumbit a request to be upgraded to a PF.

Request

Body

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "email" : EMAIL,
  "password" : STRING,
  "firstName" : STRING,
  "lastName" : STRING,
  "phoneNumber": STRING,
  "location": {
    "address": STRING,
    "city": STRING,
    "state": STRING,
    "zipCode": STRING
  }
}
  • EMAIL: Is a valid email string.
  • PASSWORD: Is a valid password string that is at least 8 characters.

Responses

201 Created

The email is still available, and an account has been successfully created.

Body:

1
2
3
4
{
  "accessToken"  : JWT,
  "refreshToken" : JWT
}

400 Bad Request

Malformed request body.

409 Conflict

The given email is already in use.

1
"Error creating new user, given email %s already used"

GET user/verify/:secret_key

Used for confirming an account email

Request

Path Params

  • secret_key: is a secret key randomly generated by the backend and sent to the user by email.

Responses

200 OK

The user's secret key has been verified.

401 Unauthorized

The secret key is invalid or expired.

TODO: GET user/create_secret/:user_id

Used for creating secret keys for users.

Request

PATH: GET user/create_secret/:user_id

Responses

200 OK

A secret key was created and stored for the given user.

400 BAD REQUEST

The given user id could not be found.

Protected Routes

These routes are called by an authenticated user. These routes can only be called with a valid access JWT token specified in the following header.

1
X-Access-Token: JWT-String

**These routes all have the prefix api/v1/protected/

DELETE /user

Deletes the user that called this route as determined by their access JWT.

This route is only implemented to support testing and does not invalidate user access tokens. This is not safe to be called by the frontend client for this reason.

Responses

200 OK

The user no longer exists

POST /user/change_password

Allows a user to change their password when already authenticated.

Request

1
2
3
4
{
  "currentPassword": STRING,
  "newPassword": STRING
}

passwords should be strings with length >= 8 characters.

Responses

200 OK

The password change was successful.

400 BAD REQUEST

If the request was malformed.

401 Unauthorized

The currentPassword does not match the calling user's current password.

POST /user/change_email

Allows a user to change the email address for the main contact. This updates the email the user logs in with as well as the email for the main contact that will recieve all communication.

Request

1
2
3
4
{
  "newEmail": STRING,
  "password": STRING
}

Responses

200 OK

The email change was successful.

400 BAD REQUEST

If the request was malformed.

401 Unauthorized

The currentPassword does not match the calling user's current password.

POST user/contact_info

Used for setting famil data as a participating family. It is expected that a user has already sent a request to the regular sign up and exists.

This route does NOT automatically create a PF request. That should be done with a call to POST /protected/requests.

Request

Body:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
  "mainContact": {
    "firstName": STRING,
    "lastName": STRING,
    "dateOfBirth": TIMESTAMP,
    "phoneNumber": STRING,
    "pronouns": STRING,
    "allergies": STRING OR NULL,
    "diagnosis": STRING OR NULL,
    "medications": STRING OR NULL,
    "notes": STRING OR NULL,
    "profilePicture": IMAGE OR NULL,
  },
  "additionalContacts": [
    {
        "firstName": STRING,
        "lastName": STRING,
        "email": EMAIL,
        "shouldSendEmails": BOOLEAN,
        "dateOfBirth": TIMESTAMP,
        "phoneNumber": STRING,
        "pronouns": STRING,
        "allergies": STRING OR NULL,
        "diagnosis": STRING OR NULL,
        "medications": STRING OR NULL,
        "notes": STRING OR NULL,
        "profilePicture": IMAGE OR NULL,
    },
    ...
  ],
  "children": [
    {
      "firstName": STRING,
      "lastName": STRING,
      "dateOfBirth": TIMESTAMP,
      "pronouns": STRING,
      "school": STRING,
      "schoolYear": STRING,
      "allergies": STRING OR NULL,
      "diagnosis": STRING OR NULL,
      "medications": STRING OR NULL,
      "notes": STRING OR NULL,
      "profilePicture": IMAGE OR NULL,
    }
    ...
  ],
}

An EMAIL is a string representing a user's email. An IMAGE is a BLOB representing the contents of an image.

Responses

200 OK

The information was successfuly stored and a request was made to the admins to become a pf.

400 Bad Request

Malformed request.

GET /user/contact_info

Gets all the information associated with this user's account.

Response

200 OK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
{
  "location": {
    "address": STRING,
    "city": STRING,
    "state": STRING,
    "zipCode": STRING
  },
  "mainContact": {
    "id": STRING,
    "firstName": STRING,
    "lastName": STRING,
    "dateOfBirth": TIMESTAMP,
    "phoneNumber": STRING,
    "pronouns": STRING,
    "allergies": STRING OR NULL,
    "diagnosis": STRING OR NULL,
    "medications": STRING OR NULL,
    "notes": STRING OR NULL,
    "profilePicture": STRING OR NULL,
  },
  "additionalContacts": [
    {
        "id": STRING,
        "firstName": STRING,
        "lastName": STRING,
        "email": EMAIL,
        "shouldSendEmails": BOOLEAN,
        "dateOfBirth": TIMESTAMP,
        "phoneNumber": STRING,
        "pronouns": STRING,
        "allergies": STRING OR NULL,
        "diagnosis": STRING OR NULL,
        "medications": STRING OR NULL,
        "notes": STRING OR NULL,
        "profilePicture": IMAGE OR NULL,
    },
    ...
  ],
  "children": [
    {
      "id": STRING,
      "firstName": STRING,
      "lastName": STRING,
      "dateOfBirth": TIMESTAMP,
      "pronouns": STRING,
      "school": STRING,
      "schoolYear": STRING,
      "allergies": STRING OR NULL,
      "diagnosis": STRING OR NULL,
      "medications": STRING OR NULL,
      "notes": STRING OR NULL,
      "profilePicture": IMAGE OR NULL,
    }
    ...
  ]
}

PUT /user/contact_info

Updates the user's contact, children, and account infromation.

Request

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
{
  "location": {
    "address": STRING,
    "city": STRING,
    "state": STRING,
    "zipCode": STRING
  },
  "mainContact": {
    "firstName": STRING,
    "lastName": STRING,
    "dateOfBirth": TIMESTAMP,
    "phoneNumber": STRING,
    "pronouns": STRING,
    "allergies": STRING OR NULL,
    "diagnosis": STRING OR NULL,
    "medications": STRING OR NULL,
    "notes": STRING OR NULL,
    "profilePicture": IMAGE OR NULL,
  },
  "additionalContacts": [
    {
        "id": STRING OR NULL,
        "firstName": STRING,
        "lastName": STRING,
        "email": EMAIL,
        "shouldSendEmails": BOOLEAN,
        "dateOfBirth": TIMESTAMP,
        "phoneNumber": STRING,
        "pronouns": STRING,
        "allergies": STRING OR NULL,
        "diagnosis": STRING OR NULL,
        "medications": STRING OR NULL,
        "notes": STRING OR NULL,
        "profilePicture": IMAGE OR NULL,
    },
    ...
  ],
  "children": [
    {
      "id": STRING OR NULL,
      "firstName": STRING,
      "lastName": STRING,
      "dateOfBirth": TIMESTAMP,
      "pronouns": STRING,
      "school": STRING,
      "schoolYear": STRING,
      "allergies": STRING OR NULL,
      "diagnosis": STRING OR NULL,
      "medications": STRING OR NULL,
      "notes": STRING OR NULL,
      "profilePicture": IMAGE OR NULL,
    }
    ...
  ]
}

Any contacts or children that exist in the database and not in the request body will be deleted. Any contact or child with a null id will be treated as a brand new record. Any contact or child with a NON-null id will be treated as an update and will return a 400 if the row with that id is not owned by the calling user.

Responses

200 OK

Everything went ok.

400 BAD REQUEST

Either the JSON request body was malformed or a child or contact had a non-null id that is associated with a row in the db that is NOT associated with the user that called this route.