Thinh's ShopBack Node.js Challenge
FEATURES
Required Features:
- Allow users to register a new account with
name
,email
andpassword
. - Account login by
email
andpassword
.- Request should have a parameter to specify device info:
X-Device: mobile / web_browser
. - Request should have a parameter to support language:
X-Language: en / vi
. - Response: Contains a
uuid
in response header, for successful login. uuid
is an OTP, which will be used once for every request, expires after 2 hours and users need to login again to refresh.
- Request should have a parameter to specify device info:
- Logout, the OTP will be expired immediately.
- Search by email, name, latest access and supports pagination.
Security and assumptions:
- All passwords are encrypted with bcrypt, 7 rounds by default.
- Each OTP generated is available for ONE request only.
- OTP comes with the device you use to sign in. Mobile OTP cannot be used to authenticate requests from web_browser.
INSTALLATION
- Make sure you have the latest LTS version of Node.js (download here).
cd
to root directory (the one withindex.js
). Install dependencies by runningnpm install
.
START SERVER
Dev
- Start the live server by
PORT=8080 npm start
.
Production build & Start server
- Build the production code by
npm run build
. - Start the server by
PORT=8080 npm run start-build
.
SAMPLE DATA
Admin account
{
"email": "[email protected]",
"password": "12345678"
}
API SPECIFICATIONS
Sign Up
Request
POST /api/signup
X-Language: en / vi
X-Device: mobile / web_browser
Content-Type: application/json
{
"email": "[email protected]",
"password": "12345678",
"name": "Thinh Nguyen"
}
Responses
- 201 Created: User created successfully
(For X-Device: mobile and X-Language: vi)
{
"success": true,
"code": 201,
"message": "Bạn đã được đăng kí thành công",
"data": [
{
"email": "[email protected]",
"fullname": "Thinh Nguyen",
"latest": null,
"created": 1602009470
}
]
}
(For X-Device: web_browser and X-Language: vi)
{
"success": true,
"code": 201,
"message": "Bạn đã được đăng kí thành công",
"data": [
{
"login_id": "[email protected]",
"full_name": "Thinh Nguyen",
"latest_login": null,
"created_date": "2020-10-06T19:08:22.239Z"
}
]
}
- 400 Bad Request: User data is invalid
{
"success": true,
"code": 400,
"message": "The data you sent is invalid. Please check and try again",
"data": [
{
"msg": "Invalid value",
"param": "name",
"location": "body"
}
]
}
- 409 Conflict: Email has been registered
{
"success": true,
"code": 409,
"message": "This email is already registered in the system. Please try another one"
}
- 500 Internal Server Error
Sign In
Request
POST /api/signin
X-Language: en / vi
X-Device: mobile / web_browser
Content-Type: application/json
{
"email": "[email protected]",
"password": "12345678"
}
Responses
- 200 OK: User logged in successfully
Response headers:
- uuid: 097fcd6c-1933-4b03-b148-4000f6d1b4d1
(For X-Device: mobile and X-Language: vi)
{
"success": true,
"code": 200,
"message": "Bạn đã đăng nhập thành công",
"data": [
{
"email": "[email protected]",
"fullname": "Thinh Nguyen",
"latest": 1602011887,
"created": 1602011883
}
]
}
(For X-Device: web_browser and X-Language: vi)
{
"success": true,
"code": 200,
"message": "Bạn đã đăng nhập thành công",
"data": [
{
"login_id": "[email protected]",
"full_name": "Thinh Nguyen",
"latest_login": "2020-10-06T19:18:33.163Z",
"created_date": "2020-10-06T19:18:03.836Z"
}
]
}
- 400 Bad Request: Credentials is invalid
{
"success": true,
"code": 400,
"message": "The data you sent is invalid. Please check and try again",
"data": [
{
"msg": "Invalid value",
"param": "password",
"location": "body"
}
]
}
- 500 Internal Server Error
Search users
Request
GET /api/user/search
?page=(int, optional, default: 10)
&items_per_page=(int, optional, default: 30)
&name=(str, optional, example: thinh)
&email=(str, optional, example: [email protected])
&last_accessed_from=(str, optional, datetime, example: 2020-10-04)
&last_accessed_to=(str, optional, datetime, example: 2020-10-08)
(Parameters are all optional)
For example:
/user/search?name=thinh&items_per_page=2&page=1&last_accessed_from=2020-09-05&last_accessed_to=2020-09-08
X-Language: en / vi
X-Device: mobile / web_browser
Content-Type: application/json
uuid: 097fcd6c-1933-4b03-b148-4000f6d1b4d1
Responses
- 200 OK: Matching users found
(For X-Device: mobile and X-Language: vi)
{
"success": true,
"code": 200,
"message": "Truy vấn dữ liệu thành công",
"data": {
"total_pages": 1,
"total_items": 2,
"items_per_page": 30,
"items": [
{
"email": "[email protected]",
"fullname": "Thinh Nguyen",
"latest": 1602009484,
"created": 1602006074
},
{
"email": "[email protected]",
"fullname": "Thinh Nguyen",
"latest": 1602012463,
"created": 1602011883
}
]
}
}
(For X-Device: web_browser and X-Language: vi)
{
"success": true,
"code": 200,
"message": "Truy vấn dữ liệu thành công",
"data": {
"total_pages": 1,
"total_items": 2,
"items_per_page": 30,
"items": [
{
"login_id": "[email protected]",
"full_name": "Thinh Nguyen",
"latest_login": "2020-10-06T18:38:04.875Z",
"created_date": "2020-10-06T17:41:14.302Z"
},
{
"login_id": "[email protected]",
"full_name": "Thinh Nguyen",
"latest_login": "2020-10-06T19:27:43.776Z",
"created_date": "2020-10-06T19:18:03.836Z"
}
]
}
}
- 400 Bad Request: Filters or pagination query strings are invalid
{
"success": true,
"code": 400,
"message": "The data you sent is invalid. Please check and try again",
"data": [
{
"value": "hello",
"msg": "Invalid value",
"param": "items_per_page",
"location": "query"
}
]
}
- 403 Forbidden: An user trying to access an admin-only endpoint
{
"success": true,
"code": 403,
"message": "You don't have the permission to perform this action"
}
- 500 Internal Server Error