- Git
- Node JS >= 14+
- MongoDb Driver
- MongoDb Server.
- ExpressJS
- Redis
- JWT Token
- Docker and Docker Compose
- Ajv and AJv Plugins
- Uuid
- Docker and Docker Compose
- [Winston]https://www.npmjs.com/package/winston)
- Postman
Please check the file env.example
and change to .env
there are 2 .env
files, and both are required.
NODE_ENV = development
APP_PORT = 3000
APP_ISSUER = gitbub.com/mrbontor
....
This mini microservice is developed using Docker and Docker Compose, Hint:
- If you are going to use your existing MongoDb and Redis, please change the configuration in [.env](../../app-job-list/.env-example) and [backend](./.env-example) (i expects the env files has been renamed)
- If you are using MongoAtlas or other Mongo Cloud, please set variable `MONGO_LOCAL` to be true in [backend](./.env-example)
Running service using Docker
and Docker-Compose
# start
$ docker-compose up
# stop
$ docker-compose down
# remove
$ docker-compose down -v
#login to the container by container name base on docker-compose.yml
$ docker exec -it [`container-name`] sh
#logging the container
$ docker logs -f `container-name`
Running for existing MongoDB and Redis
# enter to the backend
$ cd apps/backend
# install dependencies
$ npm install
# run app
$ npm start
# or
$ node index.js
on progress..
User(s) must be authenticated before accessing any API.
The AUTH API
will return accessToken
, refreshToken
and DID
API
has provided Cookies
for clients with expiration time
.
To change the lifetime
, look in the .env
file. Expiration time is used to handle JWT Token
and Cookie
expiration
Notes:
accessToken
will be returned in response bodyrefreshToken
will be returned asCookie
with nameRTOKEN
deviceId
is the device identifier and will be returned as aCookie
with nameDID
User login using method POST with paramatersusername
and password.
Endpoint:
Method: POST
Type: RAW
URL: {{local}}/v1/auth/login
Body:
{
"emailAddress": "superadmin@gmail.com",
"password": "Superadmin123!"
}
More example Requests/Responses:
Body:
{
"emailAddress": "superadmin@gmail.com",
"password": "Superadmin123!"
}
{
"status": true,
"message": "Success",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJOYW1lIjoic3VwZXJhZG1pbiIsImVtYWlsQWRkcmVzcyI6InN1cGVyYWRtaW5AZ21haWwuY29tIn0sImlhdCI6MTY3NjMxNzg0NywiZXhwIjoxNjc2MzUzODUwLCJhdWQiOiJnaXRidWIuY29tL21yYm9udG9yIiwiaXNzIjoiZ2l0YnViLmNvbS9tcmJvbnRvciJ9._YH23frdqyVqenHCU0y5uOs-1y2hMKeWfa4RxRsAVTU"
}
}
Status Code: 200
Body:
{
"emailAddress": "superadmin@gmail.com",
"password": "Superadmin123!!"
}
{
"status": false,
"message": "Un Authorized!"
}
Status Code: 401
Register user use JSON
payload to create a user
Endpoint:
Method: POST
Type: RAW
URL: {{local}}/v1/auth/register
Body:
{
"firstName": "user",
"lastName": "baru",
"gender": "Man",
"userName": "user1",
"emailAddress": "user1@gmail.com",
"password": "User123!"
}
More example Requests/Responses:
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": true,
"message": "Success",
"data": "63ea87cef26e1fd489b65dfe"
}
Status Code: 200
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "The userName has been registered!"
}
Status Code: 422
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin1",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "The emailAddress has been registered!"
}
Status Code: 422
Body:
{
"firstName": "Super",
"lastName": "Admin",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "Validation Error!",
"errors": [
{
"param": "gender",
"key": "required",
"message": "Gender is required!"
}
]
}
Status Code: 400
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!",
"xxx": "xxx"
}
{
"status": false,
"message": "Validation Error!",
"errors": [
{
"param": "xxx",
"key": "additionalProperties",
"message": "must NOT have additional properties"
}
]
}
Status Code: 400
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "Token invalid"
}
Status Code: 401
Fetch new Token as a refresh token
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/auth/refresh-token
More example Requests/Responses:
Body: None
{
"status": true,
"message": "Success",
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InVzZXJOYW1lIjoic3VwZXJhZG1pbiIsImVtYWlsQWRkcmVzcyI6InN1cGVyYWRtaW5AZ21haWwuY29tIn0sImlhdCI6MTY3NjMxOTA1MiwiZXhwIjoxNjc2MzU1MDU1LCJhdWQiOiJnaXRidWIuY29tL21yYm9udG9yIiwiaXNzIjoiZ2l0YnViLmNvbS9tcmJvbnRvciJ9.xLYDBHw7wpYYSWYy5Nnyhp6Wxk0LD9YnNmfdnnlmY0A"
}
}
Status Code: 200
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
User Logout and remove token, cookies etc
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/auth/logout
More example Requests/Responses:
Query:
Key | Value | Description |
---|---|---|
allDevices | true | true or false |
Body: None
Status Code: 204
Query:
Key | Value | Description |
---|---|---|
allDevices | true | true or false |
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Users
directory contains all the user related APIs. For authentication these apis requrie AuthBearerToken
Create user use JSON
payload to create a user
Endpoint:
Method: POST
Type: RAW
URL: {{local}}/v1/users
Body:
{
"firstName": "user",
"lastName": "baru",
"gender": "Man",
"userName": "user1",
"emailAddress": "user1@gmail.com",
"password": "User123!"
}
More example Requests/Responses:
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": true,
"message": "Success",
"data": "63ea87cef26e1fd489b65dfe"
}
Status Code: 200
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "The userName has been registered!"
}
Status Code: 422
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin1",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "The emailAddress has been registered!"
}
Status Code: 422
Body:
{
"firstName": "Super",
"lastName": "Admin",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "Validation Error!",
"errors": [
{
"param": "gender",
"key": "required",
"message": "Gender is required!"
}
]
}
Status Code: 400
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!",
"xxx": "xxx"
}
{
"status": false,
"message": "Validation Error!",
"errors": [
{
"param": "xxx",
"key": "additionalProperties",
"message": "must NOT have additional properties"
}
]
}
Status Code: 400
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "Token invalid"
}
Status Code: 401
Patch
password user use JSON
payload to update user password.
fields:
- password,
required
- newPassword,
required
Noted: Changing password will remove Token Bearer
Endpoint:
Method: PATCH
Type: RAW
URL: {{local}}/v1/users/password/superadmin
Body:
{
"password": "SuperAdmin123!",
"newPassword": "Superadmin123!"
}
More example Requests/Responses:
Body:
{
"password": "SuperAdmin123!",
"newPassword": "Superadmin123!"
}
Status Code: 204
Body:
{
"password": "Superadmin123!!",
"newPassword": "Superadmin123!"
}
{
"status": false,
"message": "Incorect Password"
}
Status Code: 400
Body:
{
"password": "!Haruslolos123",
"newPassword": "Haruslolos123!"
}
Unauthorized
Status Code: 401
Fetch all list users
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/users
More example Requests/Responses:
Query:
Key | Value | Description |
---|---|---|
userName | user |
Body: None
{
"status": true,
"message": "Success",
"data": [
{
"firstName": "user",
"lastName": "baru",
"gender": "Man",
"userName": "user",
"emailAddress": "user@gmail.com",
"infoLogin": {
"hash": "ca2658da7607e51c90f34c40673e90703f3fd166325bb93e7af42996602a908ad9001549d89e19680cd57ccabc63f5ff175e79602ca70686b230750df11a132a",
"salt": "9QivnIANDqJZlrX6tknuotPULAiX+sS4eiOUsO+ODAU=",
"iterations": 13786
},
"createdAt": "2023-02-13T19:29:30.069Z",
"updatedAt": "2023-02-13T19:29:30.069Z",
"_id": "63ea8f9a33fc7d066c2a1c60"
}
]
}
Status Code: 200
Body: None
{
"status": true,
"message": "Success",
"data": [
{
"firstName": "user",
"lastName": "baru",
"gender": "Man",
"userName": "user",
"emailAddress": "user@gmail.com",
"infoLogin": {
"hash": "ca2658da7607e51c90f34c40673e90703f3fd166325bb93e7af42996602a908ad9001549d89e19680cd57ccabc63f5ff175e79602ca70686b230750df11a132a",
"salt": "9QivnIANDqJZlrX6tknuotPULAiX+sS4eiOUsO+ODAU=",
"iterations": 13786
},
"createdAt": "2023-02-13T19:29:30.069Z",
"updatedAt": "2023-02-13T19:29:30.069Z",
"_id": "63ea8f9a33fc7d066c2a1c60"
},
{
"_id": "63ea8edeb1c4594d460bf06a",
"firstName": "Super",
"lastName": "Admins",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"infoLogin": {
"hash": "0c3d37e8400d491340aaebcbd61d03dbcc633ab5bc2a68db5c9a89405a61d5e1ea27305be13d1e816feb5909aa05d8950e22e7fccfdced84f484d6183d7c9153",
"salt": "0HsD05G4VWBiHbddEo9MaDqvQSekNCIaUdaDmjtc/R0=",
"iterations": 25475
},
"createdAt": "2023-02-13T19:28:27.894Z",
"updatedAt": "2023-02-13T19:28:27.894Z"
}
]
}
Status Code: 200
Headers:
Key | Value | Description |
---|---|---|
Content-Type | application/json |
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Fetch User
using pagination
allowed filter/search by multiple fields
- firstName
- username
can be sorted by those fields as well
sortBy
= status
sortType
= desc
or asc
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/users/table
More example Requests/Responses:
Body: None
{
"status": true,
"message": "Success",
"data": {
"sort": {
"updatedAt": "ASC"
},
"page": 1,
"size": 10,
"totalRecord": 2,
"totalPage": 1,
"data": [
{
"_id": "63df5fb20a6799aeaf22f724",
"userName": "superadmin",
"accountNumber": 12345671,
"emailAddress": "superadmin@gmail.com",
"identityNumber": 1234567898765431,
"createdAt": "2023-02-05T07:50:10.417Z",
"updatedAt": "2023-02-05T07:50:10.417Z"
},
{
"_id": "63df60c87116dd7ec619891b",
"userName": "user",
"accountNumber": 12345672,
"emailAddress": "user@gmail.com",
"identityNumber": 1234567898765432,
"createdAt": "2023-02-05T07:54:48.310Z",
"updatedAt": "2023-02-05T07:54:48.310Z"
}
]
}
}
Status Code: 200
Query:
Key | Value | Description |
---|---|---|
sortBy | status | userName, emailAddress, identityNumber, accountNumber |
sortType | desc | asc, desc and/or 0, 1 |
search | superadmin | string |
Body: None
{
"status": true,
"message": "Success",
"data": {
"sort": {
"status": "DESC"
},
"page": 1,
"size": 10,
"totalRecord": 2,
"totalPage": 1,
"data": [
{
"_id": "63df5fb20a6799aeaf22f724",
"userName": "superadmin",
"accountNumber": 12345671,
"emailAddress": "superadmin@gmail.com",
"identityNumber": 1234567898765431,
"createdAt": "2023-02-05T07:50:10.417Z",
"updatedAt": "2023-02-05T07:50:10.417Z"
}
]
}
}
Status Code: 200
Query:
Key | Value | Description |
---|---|---|
sortBy | status | firstName, username, email, status |
sortType | desc | asc, desc and/or 0, 1 |
Body: None
{
"status": true,
"message": "Success",
"data": {
"sort": {
"status": "DESC"
},
"page": 1,
"size": 10,
"totalRecord": 2,
"totalPage": 1,
"data": [
{
"_id": "63df5fb20a6799aeaf22f724",
"userName": "superadmin",
"accountNumber": 12345671,
"emailAddress": "superadmin@gmail.com",
"identityNumber": 1234567898765431,
"createdAt": "2023-02-05T07:50:10.417Z",
"updatedAt": "2023-02-05T07:50:10.417Z"
},
{
"_id": "63df60c87116dd7ec619891b",
"userName": "user",
"accountNumber": 12345672,
"emailAddress": "user@gmail.com",
"identityNumber": 1234567898765432,
"createdAt": "2023-02-05T07:54:48.310Z",
"updatedAt": "2023-02-05T07:54:48.310Z"
}
]
}
}
Status Code: 200
Headers:
Key | Value | Description |
---|---|---|
Content-Type | application/json |
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Fetch a single user using identityNumber
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/users/users
More example Requests/Responses:
Body: None
{
"status": true,
"message": "Success",
"data": {
"firstName": "user",
"lastName": "baru",
"gender": "Man",
"userName": "user",
"emailAddress": "user@gmail.com",
"infoLogin": {
"hash": "ca2658da7607e51c90f34c40673e90703f3fd166325bb93e7af42996602a908ad9001549d89e19680cd57ccabc63f5ff175e79602ca70686b230750df11a132a",
"salt": "9QivnIANDqJZlrX6tknuotPULAiX+sS4eiOUsO+ODAU=",
"iterations": 13786
},
"createdAt": "2023-02-13T19:29:30.069Z",
"updatedAt": "2023-02-13T19:29:30.069Z",
"_id": "63ea8f9a33fc7d066c2a1c60"
}
}
Status Code: 200
Body: None
{
"status": false,
"message": "User not found!"
}
Status Code: 404
Headers:
Key | Value | Description |
---|---|---|
Content-Type | application/json |
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Update user use JSON
payload to update a user
Endpoint:
Method: PUT
Type: RAW
URL: {{local}}/v1/users/superadmin
Body:
{
"firstName": "Super",
"lastName": "Admins",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "user@gmail.com"
}
More example Requests/Responses:
Body:
{
"firstName": "Super",
"lastName": "Admins",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com"
}
{
"status": true,
"message": "Success",
"data": {
"_id": "63ea8edeb1c4594d460bf06a",
"firstName": "Super",
"lastName": "Admins",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"infoLogin": {
"hash": "0c3d37e8400d491340aaebcbd61d03dbcc633ab5bc2a68db5c9a89405a61d5e1ea27305be13d1e816feb5909aa05d8950e22e7fccfdced84f484d6183d7c9153",
"salt": "0HsD05G4VWBiHbddEo9MaDqvQSekNCIaUdaDmjtc/R0=",
"iterations": 25475
},
"createdAt": "2023-02-13T19:28:27.894Z",
"updatedAt": "2023-02-13T19:28:27.894Z"
}
}
Status Code: 200
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "Validation Error!",
"errors": [
{
"param": "password",
"key": "additionalProperties",
"message": "must NOT have additional properties"
}
]
}
Status Code: 400
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com"
}
{
"status": false,
"message": "User not found!"
}
Status Code: 404
Body:
{
"firstName": "Super",
"lastName": "Admins",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "user@gmail.com"
}
{
"status": false,
"message": "The emailAddress has been registered!"
}
Status Code: 422
Headers:
Key | Value | Description |
---|---|---|
Content-Type | application/json |
Body:
{
"firstName": "Super",
"lastName": "Admin",
"gender": "Man",
"userName": "superadmin",
"emailAddress": "superadmin@gmail.com",
"password": "SuperAdmin123!"
}
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Delete a single user using idUser
Only Admin can perform this API
Endpoint:
Method: DELETE
Type:
URL: {{local}}/v1/users/user1
More example Requests/Responses:
Body: None
Status Code: 204
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/jobs
More example Requests/Responses:
Body: None
{
"status": true,
"message": "Success",
"data": {
"data": [
{
"id": "32bf67e5-4971-47ce-985c-44b6b3860cdb",
"type": "Full Time",
"url": "https://jobs.github.com/positions/32bf67e5-4971-47ce-985c-44b6b3860cdb",
"created_at": "Wed May 19 00:49:17 UTC 2021",
"company": "SweetRush",
"company_url": "https://www.sweetrush.com/",
"location": "Remote",
"title": "Senior Creative Front End Web Developer",
"description": "description",
"how_to_apply": "<p>If this describes your interests and experience, please submit your current resume and salary requirements through the following link:\n<a href=\"https://www.sweetrush.com/join-us/\">https://www.sweetrush.com/join-us/</a></p>\n",
"company_logo": "https://jobs.github.com/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBaUtqIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--82886ff47e94ff4c0255b95773a9667644768b2b/SR%20Logo.png"
},
],
"page": 1,
"size": 10
}
}
Status Code: 200
Query:
Key | Value | Description |
---|---|---|
location | Schwerin |
Body: None
{
"status": true,
"message": "Success",
"data": {
"data": [
{
"id": "7638eee4-4e75-4c06-a920-ea7619a311b5",
"type": "Full Time",
"url": "https://jobs.github.com/positions/7638eee4-4e75-4c06-a920-ea7619a311b5",
"created_at": "Tue May 18 17:12:52 UTC 2021",
"company": "MANDARIN MEDIEN Gesellschaft für digitale Lösungen mbH",
"company_url": "https://www.mandarin-medien.de/",
"location": "Schwerin",
"title": "Systemadministrator:in",
"description": "description ex",
"how_to_apply": "<p><a href=\"https://t.gohiring.com/h/83f7df34249addb0bebc8dc680310d1ded43220a748ee285e27989a457dd10ea\">Application form</a></p>\n",
"company_logo": "https://jobs.github.com/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBaCtqIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--8d0339b9e43b0dca160b9db73b230b6067e39b05/MANDARIN%20MEDIEN%20Gesellschaft%20fu%CC%88r%20digitale%20Lo%CC%88sungen%20mbH.jpeg"
},
...
],
"page": 1,
"size": 3
}
}
Status Code: 200
Query:
Key | Value | Description |
---|---|---|
page | 3 |
Body: None
{
"status": false,
"message": "No data available"
}
Status Code: 404
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
Endpoint:
Method: GET
Type:
URL: {{local}}/v1/jobs/0cbbfe2b-5dcf-45f9-94bf-b74882b593ff
More example Requests/Responses:
Body: None
{
"status": true,
"message": "Success",
"data": {
"id": "0cbbfe2b-5dcf-45f9-94bf-b74882b593ff",
"type": "Full Time",
"url": "https://jobs.github.com/positions/0cbbfe2b-5dcf-45f9-94bf-b74882b593ff",
"created_at": "Fri May 14 08:12:18 UTC 2021",
"company": "Bertrandt Technikum GmbH Ehningen",
"company_url": "http:",
"location": "Ehningen",
"title": "Entwicklungsingenieur (m/w/d) AUTOSAR",
"description": "exem descript",
"how_to_apply": "<p><a href=\"https://bertrandtgroup.jobbase.io/apply/krjxavmlljhlwvli7c0r4burof6gt1j\">https://bertrandtgroup.jobbase.io/apply/krjxavmlljhlwvli7c0r4burof6gt1j</a></p>\n",
"company_logo": null
}
}
Status Code: 200
Body: None
{
"status": false,
"message": "Token Invalid"
}
Status Code: 401
To ensure this service online, the client can request to this API first than continue main API
Endpoint:
Method: GET
Type:
URL: localhost:3002
More example Requests/Responses:
Body: None
{
"uptime": 119.348257728,
"message": "OK",
"timestamp": 1676317218443
}
Status Code: 200