Challenge Overview
Mask emails of invited users with asterisks for non-admins.
Project Background
Topcoder Project Service is the main backend service of Topcode Connect – the client-facing application of Topcoder. We have the ability to invite members to projects by email. As all project members can see who is invited they also can see emails of all invited users. As email is private information we would like to hide it for non-admin users when we return it by Project Service.
Technology Stack
-
Node.js
Code access
The work for this challenge has to be done in one repository:
- Project Service repo https://github.com/topcoder-platform/tc-project-service branch dev commit 78b969f521507df8e83635a8e4aa7cb98379a263 or later.
- Config for local setup is provided on the forum.
Individual requirements
-
We have the next endpoints which can return the list of invites for projects or a single invite:
- `GET /v4/projects` - list of projects with list of invites
- `GET /v4/projects/db` - list of projects with list of invites
- `GET /v4/projects/:projectId(\\d+)` - one project with list of invites
- `GET /v4/projects/:projectId(\\d+)/members/invites` - list of invites
- `POST /v4/projects/:projectId(\\d+)/members/invite` - single invite
- `PUT /v4/projects/:projectId(\\d+)/members/invite` - single invite -
If these endpoints are called by non-admin user in the response we should mask `email` properties inside invites with asterisks so email like `abcdefgh@aaaaaaaa.com` should be returned by endpoints like `ab*****h@aa*****a.com`.
Implementation requirements
-
Create a reusable method `util.maskInviteEmails(inviteJsonPath, data, req)` which we can use to wrap around a response in any of these endpoints like this: https://monosnap.com/file/6xONzkz9qWwqQAlFQRTPwzaD0fDpqf.
- inviteJsonPath - is a jsonpath inside data. We should use JOSNPath to find object invites inside `data` to apply masking logic to them. So for the endpoint `GET /v4/projects` it would be something like `$..invites[*]`, for `GET /v4/projects/:projectId(\\d+)` something like `$.invites[*]`, and for `GET /v4/projects/:projectId(\\d+)/members/invites` like `$`. The “jsonpath”s provided here may be incorrect, this is to give you an idea of what we want to achieve here. So we should be able to reuse this method in the future with different JSON Path if we want. You may add npm package jsonpath, I guess it has a method for applying functions to the objects specified by JSON Path.
- data - the data which contains invites to process
- req - Express request object which we can use for checking if the user who made the request has admin permissions or no -
To check if the user has admin permission, reuse existent method: `util.hasPermission({ topcoderRoles: ADMIN_ROLES }, req.authUser)`
-
Put the logic of masking email in a separate reusable method `util.maskEmail(email)`. It should mask emails like this https://monosnap.com/file/4LSbEKNBCzNs9lNeqWzzxHYykBQWEl. You can use the next algorithm for reference https://stackoverflow.com/a/45944844 which gives such an output. If we pass non-email string to this method - return the same value which we pass.
General requirements
-
Write unit tests for method `util.maskEmail(email)`, test all the cases from this screenshot https://monosnap.com/file/4LSbEKNBCzNs9lNeqWzzxHYykBQWEl. Also, at least 2 test cases when we pass non-string (null) or non-email string values.
-
Write unit tests for method `util.maskInviteEmails(inviteJsonPath, data, req)`. At least 4 tests:
- “should mask emails when passing data like for a project list endpoint for non-admin user”
- “should mask emails when passing data like for a project details endpoint for non-admin user”
- “should mask emails when passing data like for a single invite endpoint for non-admin user”
- “should NOT mask emails when passing data like for a single invite endpoint for admin user” -
Existent unit tests should pass.
-
Lint should pass.
-
Git patch should be without errors or warnings.
If you have any questions or concerns, don’t hesitate to ask on the forum.
Final Submission Guidelines
Submit a zip file which would include:
-
Git patch with changes you’ve made to the code in our repository.
Additionally, the winner would be required to raise a pull request to the repository after the challenge is completed.