You can generate a new repository with the same directory structure and files as an existing repository using GitHub article: Creating a repository from a template.
N.B. This structure is recommended for the implementation tasks starting from the second. The first task is not related to subsequent ones.
Implement CLI tool that will encode and decode a text by Caesar cipher.
CLI tool should accept 4 options (short alias and full name):
- -s, --shift: a shift
- -i, --input: an input file
- -o, --output: an output file
- -a, --action: an action encode/decode
Details:
- For command-line arguments could be used one of
- https://www.npmjs.com/package/commander
- https://www.npmjs.com/package/minimist or any other module.
- Action (encode/decode) and the shift are required, if one of them missed - an error should be shown, the process should exit with non-zero status code.
- If the input file is missed - use stdin as an input source.
- If the output file is missed - use stdout as an output destination.
- If the input and/or output file is given but doesn't exist or you can't read it (e.g. because of permissions or it is a directory) - human-friendly error should be printed in stderr.
- If passed params are fine the output (file or stdout) should contain encoded/decoded content of input (file or stdin).
- For encoding/decoding use only the English alphabet, all other characters should be kept untouched.
Hints: As suggested solution to make streams code more robust, and memory effective, consider to use pipeline method. Structure can be the following:
pipeline(
input_stream, // input file stream or stdin stream
transform_stream, // standard Transform stream or https://github.com/rvagg/through2
output_stream // output file stream or stdout stream
)
.then(success and error callbacks)
Usage example:
$ node my_caesar_cli -a encode -s 7 -i "./input.txt" -o "./output.txt"
$ node my_caesar_cli --action encode --shift 7 --input plain.txt --output encoded.txt
$ node my_caesar_cli --action decode --shift 7 --input decoded.txt --output plain.txt
input.txt
This is secret. Message about "_" symbol!
output.txt
Aopz pz zljyla. Tlzzhnl hivba "_" zftivs!
Let's try to create a competitor for Trello!
Create an Express application, the application should operate with the following resources:
- User (with attributes):
{ id, name, login, password }
- Board (set of columns):
{ id, title, columns }
- Column (set of tasks):
{ id, title, order }
- Task:
{ id, title, order, description, userId, //assignee boardId, columnId }
Details:
-
For User, Board and Task REST endpoints with separate router paths should be created
/users
GET /users
- get all users (remove password from response)GET /users/:id
- get the user by id (ex. “/users/123”) (remove password from response)POST /users
- create userPUT /users/:id
- update userDELETE /users/:id
- delete user
/boards
- GET all
- GET by id
- POST
- PUT
- DELETE
/tasks
- GET all by boardId
- GET by id
- POST
- PUT
- DELETE
-
When somebody DELETE Board, all its Tasks should be deleted as well.
-
When somebody DELETE User, all Tasks where User is assignee should be updated to put userId=null.
-
For now, these endpoints should operate only with in-memory (hardcoded) data, in the next tasks we will use a DB for it. You may organize your modules with the consideration that the data source will be changed soon.
-
An application/json format should be used for request and response body.
-
Do not put everything in one file - use a separate file for application creation (bootstrapping), for controllers (routers) and code related to business logic. Also split files to different modules depends on a domain (user-related, board-related, etc...).
-
To run the service “npm start” command should be used.
-
Service should listen on PORT 4000.
Hints
- To test the service CRUD methods you can use Swagger html (see README.md).
- To generate all entities “id”s use uuid package.
Add logging functionality to already existing REST service.
-
Add express middleware which will log incoming requests to service (url, query parameters, body).
-
Add express middleware which will log all unhandled errors and return a standard message with HTTP code 500 (Internal Server Error).
-
Add errors handling to
process.on(‘uncaughtException’,...)
. -
Add Unhandled promise rejection listener to log error
-
console.log
or writing to a file can be used for logging. Any third-party logging library can also be used for this purpose.
- Use MongoDB database to store REST service data (Users, Boards, Tasks).
- Follow the MongoDB Atlas registration link.
- Fill all mandatory fields and click create account button.
- Choose “Starter Cluster” option and click Create a cluster.
- The next screen choose: cloud provider - AWS, region - Ireland (eu-west-1) and click “Create Cluster” button (Not change another options).
- Click Security - Database access tab.
- Click Add new user button.
- Choose method - Password and fill the username and the password fields (remember them, you will use them to connect mongodb database).
- User Privileges - Set read and write to any database.
- Click “Add user” button.
- Click Security - Network Access tab.
- Click “Add IP Address” button.
- Click “Allow access from anywhere” button.
- Click “Confirm” button.
- You can generate connect string, by the following: in Atlas - Clusters tab click “Connect” button.
- On Modal window (Connect to Cluster) click “Connect your Application” button. The window should look similar as in the picture:
- Use Mongoose ODM to store and update data.
- The information on DB connection (connection string) should be stored in
.env
file and should be passed to the application using the environment variables with the help of the following dotenv package.
POST /users
should accept password field and before save replace it with hash (use bcrypt package).- Add a
POST /login
method which accepts json with login and password and should return JWT token in response body:{ token: <jwt_token> }
(use jsonwebtoken package). - JWT token should contain userId and login in a payload.
- Secret that used for signing the token should be stored in
.env
file - For all client requests the JWT token should be added in HTTP Authorization header to all requests that requires authentication. HTTP authentication must follow
Bearer
scheme, e.g.:
Authorization: Bearer <jwt_token>
- Add a middleware which will proxy all the requests (except
/login
) and check that HTTP Authorization header has the correct value of JWT token. - In case of the HTTP Authorization header in the request is absent or invalid or doesn’t follow
Bearer
scheme, the middleware should stop further router method execution and return HTTP 401 code (Unauthorized error) and the corresponding error message. - Add admin user to DB on service start with login=admin and password=admin.
gyp ERR! stack Error: "pre" versions of node cannot be installed, use the --nodedir flag instead
Please check compatibility between Node.JS and Bcrypt versions.
node-pre-gyp ERR! Tried to download(404): https://github.com/kelektiv/node.bcrypt.js/releases/download/v1.0.2/bcrypt_lib-v1.0.2-node-v48-linux-x64.tar.gz
Make sure you have the appropriate dependencies installed and configured for your platform. You can find installation instructions for the dependencies for some common platforms in this page.