Challenge Overview

Mythril Platform API enables a secure and thriving ecosystem of Ethereum dapps and smart contracts. This NodeJS-based API is being developed currently, with a large contribution of Topcoder development community. In this challenge you will update API authentication scheme to ensure higher security, and also add misc endpoints to support admin functionality.

Project Background

In its current state API exposes a very basic functionality provided by Mythril tool, and is deployed for an alpha testing by the community. Mythril team plans to focus on adding new features to the API during the next few months, and significant part of this work will be performed via Topcoder challenges.

Technology Stack

Mythril API is ExpressJS / NodeJS (thus JavaScript) server-side application. It uses MongoDB as the database, and RabbitMQ as message queue for communication between API REST server and worker(s) which performs time-consuming operations. API tests are implemented with Jest and Supertest.

Code Access

Mythril API codebase is proprietary, its current version is provided in the challenge forum as ZIP version of the code repository (Git). That repository also contains basic API tests. In addition, in the separate public repository mythril-ci we host API integration tests, which run API against the latest version of Mythril tool to detect any possible regression (see src/docker/integration-tests folder in the integration-tests branch, work out of the commit c74b08232144c866c90561249fcc4b182ed9af38).

Individual Requirements

Consider all requirements as major.

  1. Update user roles handling.

    Currently, user’s type field is a string with two possible values: free and unlimited, which determine API usage quotas for that user. It should be replaced by a set of user roles, so that multiple roles can be assigned to the user and tested efficiently. Add admin role, which will allow user to perform admin operations, as described in further points.

  2. Update user management endpoints and logic: replace API key by account password.

    Move existing POST /auth/user endpoint to POST /users,  then:
    - Update it to require ReCaptcha only from non-admin users;
    - Do not generate API key.
    - Use user ID instead of email in the link send with the email verification message.

    Replace existing GET /auth/user/verify/{EMAIL}/{VERIFICATION_CODE} endpoint by POST /users/{USER_ID}/activate. The payload must be VERIFICATION_CODE and USER_PASSWORD (i.e. user sets his password as a part of verification). Check that password is strong (at least 8 symbols, includes letters of different case, digits, and special characters). If password is provided and fails the check - fail the request; otherwise, the password should be salted, hashed, and stored to the database, and the account should be activated.

    Replace existing POST /auth/user/resend and POST /auth/user/lost endpoints, by POST /users/recover as the payload it will require user email, and recaptcha code. In case ReCaptcha code is valid, and the email is found in the database, this endpoint will send recovery email, with the same link as at the registration time, but with different, appropriate text. When the link is clicked, POST /users/{USER_ID}/activate endpoint will be used again to set a new user password. In case either ReCaptcha is wrong, request fails, but in case the email is unknown, the the request will succeed, without sending recovery emai (to not allow using this endpoint to check for registered emails).

  3. Replace API key authentication by JWT authentication scheme.

    Add POST /auth/login endpoint, which, given user email and API key, will return a pair of JWT tokens: access and refresh. JWT access token will be used in the Authorization header of requests to protected API endpoints, instead of the current API key. Its payload will hold essential user information: id, firstName, email, lastName, termsId, type. The token will have 10 minutes expiration time (the value should be set via API config).

    Add POST /auth/refresh endpoint, which, given current JWT access and JWT refresh tokens will return a new pair of JWT access and JWT tokens. Be sure to properly check that input tokens pairs match each other, and they are revoked in the result of this operation.

    Add POST /auth/logout endpoint that should revoke user’s JWT tokens.

    Update existing protected endpoints to use JWT tokens authentication scheme.

    NOTE: Implementation should still allow several pairs of JWT tokens be active at the same time. E.g. if user logins via POST /auth/login from two different devices he will get two different pairs (A and B) of JWT tokens for the first and second login. When he refreshes, say the token pair A, only the old tokens from pair A should be rovoked, while the tokens from pair B should remain functional until their expiration or refresh. Also, the logout endpoint should only revoke the tokens that authenticate the logout request (thus loggin the user out only on the device where he opted to logout).

  4. Admin endpoints.

    Add GET /users - returns the list of registered API users. It should return at most 10 users, and support offset query param for pagination. It should also support email param to filter users by email address (partial match).

    Add PUT /users/{ID} endpoint which will allow to update existing user’s data.

  5. Update API tests according to the change of auth scheme, both in the API repo, and in the mythril-ci repository, mentioned earlier. Add tests for the newly added endpoints to mythril-ci (no need to duplicate them in the API repo).

  6. Update Postman collection and OpenAPI doc, to document all updated / added endpoints.

As usual, in case of any doubts do not hesitate to raise questions in the challenge forum.

Final Submission Guidelines

Submit Git patches for the API and mythril-ci repositories, along with a brief verification video, and any additional instructions / notes for reviewers you may have.


Topcoder Open 2019


Final Review:

Community Review Board


User Sign-Off


ID: 30070422