API Docs - HackRU/HackRU-Backend GitHub Wiki

Welcome to the HackRU-Backend wiki! We'll be using Typescript, Node.js, and Serverless to set up our backend.

Endpoints:

/authorize:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

"email": "[email protected]",
"password": "plain-text-password"

Return:

Situation Return Value
Wrong password {'statusCode': 403, message: 'Wrong password'}
Email doesn't exist in DB {'statusCode': 403, message: 'Invalid email'}
Success Auth {'statusCode': 200, message: 'Authentication Successful', token}
Internal error {'statusCode': 500, message: 'Internal server error'}

/attend-event:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

auth_email: "[email protected]", (this user must have role director/organizer)
auth_token: "authentication-token",
qr: "[email protected]",
event: "dinner", 
limit: 1, (how many times user can attend this event)
points: 10, (optional - amount of points user earns for this event)

RETURN:

Situation Return value
Auth token not valid {'statusCode': 401, message: 'Unauthorized'}
Hacker (qr) not found {'statusCode': 404, message: 'User not found'}
Auth user (auth_email) not found {'statusCode': 404, message: 'Auth user not found'}
Auth user does not have roles organizer/director {'statusCode': 401, message: 'Only directors/organizers can call this endpoint.'}
User tries to check into an event that they reached the limit for {'statusCode': 409, message: 'User already checked into event.', attendance: number}
Success check-in {'statusCode': 200, message: 'user successfully checked into event', attendance: number}
Internal error {'statusCode': 500, message: 'Internal server error'}

/create:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
    email: '[email protected]',
    password: 'hackerPassword'
}

This is the minimum required JSON body for the /create endpoint which includes simply the Hacker email and password.

Return:

Situation Return value
Registration Time Has Passed {'statusCode': 400, message: 'Registration is closed!'}
Creating a duplicate of existing user {'statusCode': 400, message: 'Duplicate User'}
Successfully create user {'statusCode': 200, message: 'User created!'}

/update:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
    user_email: '[email protected]',
    auth_email: '[email protected]',
    auth_token: 'user.JWT.token',
    updates: {
        $set: {
            last_name: 'sampleLastName'
        }
    }
}

This sample JSON request body represents changing the last name of the hacker, given they provide a valid auth token.

THIS CALL WILL RETURN 400 STATUS IF:

  • If you don't follow the FSM model with regard to registration status
  • If you attempt to update these fields: '_id', 'password', 'discord', 'created_at', 'registered_at'

  • If your profile is not entirely filled out.

Return:

Situation Return value
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
Auth user (auth_email) not found {'statusCode': 404, message: 'Auth user not found'}
Auth user does not have a valid role to update (organizer/director/hacker) {'statusCode': 401, message: 'Unauthorized. Auth user is not an organizer/director/hacker.'}
User to be updated not found {'statusCode': 404, message: 'User to be updated not found.'}
User provided invalid updates: update registration status in a way that doesn't follow registration order, update password or _id {'statusCode': 400, message: 'Bad updates.'}
Success update {'statusCode': 200, message: 'User updated successfully'}
Internal error {'statusCode': 500, message: 'Internal server error'}

/discord:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
    email: '[email protected]',
    auth_token: 'user JWT',
    code: 'discord code from OAuth2',
    redirect_uri: 'discord redirect uri'
}

Return:

Situation Return value
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
User (email) not found {'statusCode': 404, message: 'User not found'}
Success {'statusCode': 200, message: 'Discord user verified', discordId: 'discord user id', discordUsername: 'discord username'}
Internal error {'statusCode': 500, message: 'Internal Server Error', error: error}

If successful, user in database gets updated:

{
    discord: {
      user_id: 'discord user id',
      username: 'discord username',
      access_token: 'discord auth access token',
      refresh_token: 'discord auth refresh token',
      expires_at: 'timestamp (ms) when token expires'
    }
}

/read:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
  "auth_email": "[email protected]",
  "auth_token": "user.JWT.token",
  "email": "[email protected]",
  "all" (optional): false (default)
}

RETURN:

Situation Return value
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
Auth user (auth_email) not found {'statusCode': 404, message: 'Auth user not found.'}
Auth user does not have a valid role (hacker/director/organizer) {'statusCode': 401, message: 'Unauthorized. Auth user is not an organizer/director/hacker.'}
Hacker tries to look up information for a different user {'statusCode': 403, message: 'Hackers can only look up their own information.'}
Look-up user (email) not found {'statusCode': 404, message: 'Look-up user not found.'}
Success {'statusCode': 200, body: [User Object]}
Internal error {'statusCode': 500, message: 'Internal server error.', error: [Error details]}

/resume:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
  "email": "[email protected]",
  "auth_token": "user.JWT.token"
}

RETURN:

Situation Return value
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
User has already submitted a resume before {'statusCode': 400, message: 'You already submitted a resume'}
Success {'statusCode': 200, body: {url, message: 'Upload the resume through the generated URL.'}}
Internal error {'statusCode': 500, message: 'Internal server error.', error: [Error details]}

If this endpoint returns the success case, there will be a URL in the return body. You can call that URL, with PUT http method, and attach your PDF file in the body as type 'Binary.' Do keep in mind that it ONLY accepts PDF files.


/waiver:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
  "email": "[email protected]",
  "auth_token": "user.JWT.token"
}

RETURN:

Situation Return value
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
User has already submitted a waiver before {'statusCode': 400, message: 'You already submitted a waiver'}
Success {'statusCode': 200, body: {url, message: 'Upload the waiver through the generated URL.'}}
Internal error {'statusCode': 500, message: 'Internal server error.', error: [Error details]}

If this endpoint returns the success case, there will be a URL in the return body. You can call that URL, with PUT http method, and attach your PDF file in the body as type 'Binary.' Do keep in mind that it ONLY accepts PDF files.


/reset-password:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
  "email": "[email protected]",
  "reset_token": "tokenFromEmail",
  "new_password": "iLoveHackRU"
}

RETURN:

Situation Return value
User did not request a password change {'statusCode': 403, message: 'You did not request a password change'}
Invalid reset token {'statusCode': 401, message: 'Reset token is invalid'}
Reset token has expired {'statusCode': 401, message: 'Reset token has expired'}
Successful password update {'statusCode': 200, message: 'Password reset successful'}
Internal error {'statusCode': 500, message: 'Internal server error.', error: [Error details]}

/points:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
  "email": "[email protected]",
  "auth_token": "user.JWT.token",
  "buy_ins": [
      // Array of buy_ins
   ]
}

RETURN:

Situation Return Value
Invalid email format {'statusCode': 400, message: 'Invalid email format'}
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
User not found {'statusCode': 404, message: 'User not found.'}
Success {'statusCode': 200, body: { balance: number, total_points: number, buy_ins: [{prize_id: number}, {prize_id: number}] }}
Internal error {'statusCode': 500, message: 'Internal server error.', error: [Error details]}

Notes:

  • This endpoint is specifically for the F24 Hackathon points system.
  • The endpoint uses JWT for authentication.
  • Returns empty array if user has no buy_ins
  • All corner cases should be handled, including invalid email, invalid JWT token, non-existent email in Users collection, and non-existent hacker in Points collection.

/update-buy-ins:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

"email": "[email protected]",
"auth_token": "token", 
"buy_ins": [
    {
        "prize_id": "prize_A",
        "buy_in": 20
    }, 
    {
        "prize_id": "prize_B",
        "buy_in": 10
    }
]

Criterias for a successful call:

  • All the prize_id in the buy_ins array must match ALL the prize_id in the attribute buy_ins in the Points collection. For instance, if your request body has prizeA, prizeB, prizeC, then the buy_ins array in the Points collection must contain those prizes as well (ordering does not matter). Else, the request will not be fulfilled.

  • The sum of buy_in in the buy_ins array MUST BE LESS THAN OR EQUAL to the total_points attribute in the Points collection.

Return:

Situation Return Value
Unauthorized {'statusCode': 401, message: 'Unauthorized'}
Object doesn't exist in DB {'statusCode': 404, message: 'User point balance information not found'}
Request body prizes do not match {'statusCode': 400, message: 'Request body prizes do not match'}
Points distributed exceed user point total {'statusCode': 403, message: 'Points distributed exceed user point total'}
Updated user point balance successfully {'statusCode': 200, message: 'Updated user point balance successfully'}
Internal error {'statusCode': 500, message: 'Internal server error'}

/get-buy-ins:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

"email": "[email protected]",
"auth_token": "token", 

What it does: Returns the sum of all buy-ins for each prize across the Points collection.

Return:

Situation Return Value
Unauthorized {'statusCode': 401, message: 'Unauthorized'}
Success {'statusCode': 200, buyIns: {prizeID: integer sum of prizeID across Points collection, ....} }
Internal error {'statusCode': 500, 'message': 'Internal server error'}

/verify-email:

METHOD: POST

BODY REQUEST TYPE: JSON

To send the user a verification email, specify email and auth_token. To verify, specify only code.

EXAMPLE BODY REQUEST:

{
    email: '[email protected]',
    auth_token: 'user JWT',
}

OR

{
    code: 'email verification code'
}

Return:

Situation Return value
Invalid auth token {'statusCode': 401, message: 'Unauthorized'}
User (email) not found {'statusCode': 404, message: 'User not found'}
Success {'statusCode': 200, message: 'HackRU account ({email}) verified successfully.'}
Invalid code {'statusCode': 400, message: 'Invalid email verification code. It may be expired.'}
Internal error {'statusCode': 500, message: 'Internal Server Error', error: error}

If successful, user in database gets updated:

{
    email_verified: true
}

/delete:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

auth_email: "[email protected]", (this user must have role director/organizer)
auth_token: "authentication-token",
email: "[email protected]"

RETURN:

Situation Return value
Auth token not valid {'statusCode': 401, message: 'Unauthorized'}
User not found {'statusCode': 404, message: 'User not found'}
Auth user (auth_email) not found {'statusCode': 404, message: 'Auth user not found'}
Auth user does not have roles organizer/director {'statusCode': 401, message: 'Only directors/organizers can call this endpoint.'}
Success {'statusCode': 200, message: 'Deleted {user_email} successfully'}
Internal error {'statusCode': 500, message: 'Internal server error'}

/interest-form:

METHOD: POST

BODY REQUEST TYPE: JSON

EXAMPLE BODY REQUEST:

{
    "firstName": "John",
    "lastName": "Doe", 
    "age": 20,
    "phoneNumber": "+1234567890",
    "email": "[email protected]",
    "school": "Rutgers University",
    "levelOfStudy": "Undergraduate",
    "countryOfResidence": "United States",
    "linkedInUrl": "https://linkedin.com/in/johndoe",
    "mlh_code_of_conduct": true,
    "mlh_privacy_policy": true,
    "mlh_terms_and_conditions": true
}

REQUIRED FIELDS:

  • firstName (string)
  • lastName (string)
  • age (number)
  • phoneNumber (string)
  • email (string, must be valid email format)
  • school (string)
  • levelOfStudy (string)
  • countryOfResidence (string)
  • mlh_code_of_conduct (boolean)
  • mlh_privacy_policy (boolean)
  • mlh_terms_and_conditions (boolean)

OPTIONAL FIELDS:

  • linkedInUrl (string, must be valid LinkedIn profile URL if provided) RETURN:
Situation Return Value
Successful form submission {'statusCode': 200, message: 'Successful Form Submission', submissionId: 'database-generated-id'}
Invalid LinkedIn URL format {'statusCode': 422, message: 'Please provide a valid LinkedIn profile URL (e.g., https://linkedin.com/in/yourname)'}
Internal error {'statusCode': 500, message: 'Internal Server Error', error: 'error-details'}

NOTES:

  • LinkedIn URL is optional but if provided, must follow the format: https://linkedin.com/in/username
  • All MLH fields are required and must be boolean values
  • Email format is validated by the schema
  • Age must be a positive number
  • Form data is stored in the interest-forms collection