An open API service indexing awesome lists of open source software.

https://github.com/rolling-scopes-school/fun-chat-server


https://github.com/rolling-scopes-school/fun-chat-server

Last synced: over 1 year ago
JSON representation

Awesome Lists containing this project

README

          

## Server Application for the Chat. API

### Install and Run the Application

To use the chat server application follow these steps:

- clone the repository
- install the dependencies with `npm i`
- create the `.env` file and specify the [port settings](#Setting-the-Listening-Port-Parameters) and server [event log settings](#Server-Event-Display-Settings) in it
- start the local server using `npm run start`

The server runs on port 4000 and listens for messages from client applications.

In the `.env.example` file, you can find an example of basic parameter settings for the `.env` file.

To apply the modified parameters, you will need to restart the server.

### Setting the Listening Port Parameters

In the created `.env` file, set the `SERVER_PORT` parameter to `4000`.

If it is not possible to run the server using port `4000`, you can use another port.

### Server Event Display Settings

The server event log facilitates real-time tracking of incoming requests received by the server and responses sent by the server.

In the created `.env` file, set the `LOG` parameter to one of the values listed in this section.

Server Log Display Options

- `ALL` - all incoming and outgoing requests
- `ERROR` - only erroneous requests
- `INCOMING` - all incoming requests
- `OUTCOMING` - all outgoing requests
- `NONE` - request logging disabled

### General Information

The server application utilizes the [WebSocket protocol](https://websockets.spec.whatwg.org/) where the initiator of the request can be either a client or server application. To use the protocol you will need to familiarize yourself with the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket).

Upon a request to the server, the client will receive a response containing information about the processing result of the request. Some client requests may trigger the server to send additional requests to other clients - such situations are specified in the request description.

General request format

```javascript
{
id: string | null
type: string,
payload: {
// Request payload
},
}
```

where:

- `id` - request identifier, generated by the client application, the value will be returned by the server in the `id` field in the response. If a server application is the initiator, the id value of request identifier will be null.
- `type` - request name
- `payload` - request payload

### User Authentication

Initiator: Client application

Description: Used to authenticate the current user or create a new user. Upon successful completion, the server sends a request to all authenticated users according to the ["Third-party User Authentication"](#Third-party-User-Authentication) section.

Request to the server

```javascript
{
id: string,
type: "USER_LOGIN",
payload: {
user: {
login: string,
password: string,
},
},
}
```

where:

- `id` - request identifier
- `login` - user's login
- `password` - user's password

Server Response

```javascript
{
id: string,
type: "USER_LOGIN",
payload: {
user: {
login: string,
isLogined: boolean,
},
},
}
```

where:

- `id` - request identifier received from the client
- `login` - user's login
- `isLogined` - current authentication status of the user

Server Responses for Errors

- user with the specified login is already logged in

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "a user with this login is already authorized",
}
}
```

- another user is already authorized in this connection

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "another user is already authorized in this connection",
}
}
```

- the provided password does not match the provided login

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "incorrect password",
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### User Logout

Initiator: Client application

Description: Used to end the session for the current user. Upon successful completion, the server sends a request to all authorized users in accordance with the ["Third-Party User Logout"](#Third-Party-User-Logout) section.

Request to the Server

```javascript
{
id: string,
type: "USER_LOGOUT",
payload: {
user: {
login: string,
password: string,
}
}
}
```

where:

- `id` - request identifier
- `login` - user's login
- `password` - user's password

Server Response

```javascript
{
id: string,
type: "USER_LOGOUT",
payload: {
user {
login: string,
isLogined: boolean,
}
}
}
```

where:

- `id` - request identifier received from the client
- `login` - user's login
- `isLogined` - current authentication status of the user

Server Responses in Case of Errors

- the user with the specified login does not exist

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "there is no user with this login",
}
}
```

- the provided password and login do not match

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "incorrect password",
}
}
```

- the user with the specified login is not authorized

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "the user was not authorized",
}
}
```

- the user with the specified login is already authorized in another client connection

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "a user with this login is already authorized",
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### Third-party User Authentication

Initiator: Server application

Description: Is sent by the server to all authorized users after receiving a request in accordance with ["User Authentication"](#User-Authentication) section, indicating a successful result of the authorization of the user.

Request from the Server

```javascript
{
id: null,
type: "USER_EXTERNAL_LOGIN",
payload: {
user: {
login: string,
isLogined: boolean,
}
}
}
```

where:

- `id` - request identifier generated by the server
- `login` - username of the user who logged in
- `isLogined` - current authentication status of the user

### Third-Party User Logout

Initiator: Server application

Description: Is sent by the server to all authenticated users:
- after receiving a request according to the ["User Logout"](#User-Logout) section as a result of processing which the user's session is terminated.
- when the connection with an authorized user is broken by the client application, as a result of which the server changes the user's authorization state `isLogined` to `false`.

Request from the Server

```javascript
{
id: null,
type: "USER_EXTERNAL_LOGOUT",
payload: {
user: {
login: string,
isLogined: boolean,
}
}
}
```

where:

- `id` - request identifier generated by the server
- `login` - username of the user who logged out of the application
- `isLogined` - current authentication status of the user

### Getting All Authenticated Users

Initiator: Client application

Description: Used to retrieve a list of all authenticated users.

Request to the Server

```javascript
{
id: string,
type: "USER_ACTIVE",
payload: null,
}
```

where:

- `id` - request identifier

Server Response

```javascript
{
id: string,
type: "USER_ACTIVE",
payload: {
users: [],
}
}
```

where:

- `id` - request identifier received from the client
- `users` - array of authenticated users structurally corresponding to the `user` field in ["Third-party User Authentication"](#Third-party-User-Authentication) section. An empty array is not considered an error.

### Getting All Unauthorized Users

Initiator: Client application

Description: Used to retrieve a list of all unauthorized users.

Request to the Server

```javascript
{
id: string,
type: "USER_INACTIVE",
payload: null,
}
```

where:

- `id` - request identifier

Server Response

```javascript
{
id: string,
type: "USER_INACTIVE",
payload: {
users: [],
}
}
```

where:

- `id` - request identifier received from the client
- `users` - array of unauthorized users structurally corresponding to the `user` field in ["Third-party User Authentication"](#Third-party-User-Authentication) section. An empty array is not considered an error.

### Sending a Message to a User

Initiator: Client application

Description: Used to send a message to another user. If the message recipient is authenticated, the message is immediately directed to them according to the ["Receiving a Message From a User"](#Receiving-a-Message-From-a-User) section and the `isDelivered` status of the message is set to `true`. If the recipient is not authenticated, the message will be received along with all messages when requested according to the ["Fetching Message History With the User"](#Fetching-Message-History-With-the-User) section.

Request to the Server

```javascript
{
id: string,
type: "MSG_SEND",
payload: {
message: {
to: string,
text: string,
}
}
}
```

where:

- `id` - request identifier
- `to` - login of the user to whom the message is being sent
- `text` - text of the message

Server Response

```javascript
{
id: string,
type: "MSG_SEND",
payload: {
message: {
id: string,
from: string,
to: string,
text: string,
datetime: number,
status: {
isDelivered: boolean,
isReaded: boolean,
isEdited: boolean,
}
}
}
}
```

where:

- `id` - request identifier received from the client
- `message` - created message where:
- `id` - message identifier, generated by the server
- `from` - sender of the message
- `to` - recipient of the message
- `text` - text of the message
- `datetime` - date and time when the message was sent
- `isDelivered` - status which indicates whether the message has been delivered to the recipient
- `isReaded` - status which indicates whether the message has been read by the recipient
- `isEdited` - status which indicates whether the message has been edited by the sender

Server Responses in Case of Errors

- the sender's and recipient's logins match

```javascript
{
id: string,
type: "ERROR",
payload: {
error: 'sender and recipient logins are the same',
}
}
```

- the user with the specified login does not exist

```javascript
{
id: string,
type: "ERROR",
payload: {
error: 'the user with the specified login does not exist',
}
}
```

- the user sending the request is not authenticated

```javascript
{
id: string,
type: "ERROR",
payload: {
error: 'user not registered or not logged',
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### Receiving a Message From a User

Initiator: Server application

Description: Is sent by the server to the user specified as the recipient when requested in accordance with ["Sending a Message to a User"](#Sending-a-Message-to-a-User) section. The message is sent if the recipient user is authenticated.

Request from the Server

```javascript
{
id: null,
type: "MSG_SEND",
payload: {
message: {
id: string,
from: string,
to: string,
text: string,
datetime: number,
status: {
isDelivered: boolean,
isReaded: boolean,
isEdited: boolean,
}
}
}
}
```

where:

- `id` - request identifier generated by the server
- `message` - user's message field where:
- `id` - message identifier
- `from` - sender of the message
- `to` - recipient of the message
- `text` - text of the message
- `datetime` - date and time when the message was sent
- `isDelivered` - status which indicates whether the message has been delivered to the recipient
- `isReaded` - status which indicates whether the message has been read by the recipient
- `isEdited` - status which indicates whether the message has been edited by the sender

### Fetching Message History With the User

Initiator: Client application

Description: Used to retrieve a list of all messages with a specific user. All messages with the `isDelivered` status set to `false` will update the status to `true` if the request is made by the recipient user. In this case, for each message, the server will make a request to the sender user according to the ["Notification of Message Delivery Status Change"](#Notification-of-Message-Delivery-Status-Change) section.

Request to the Server

```javascript
{
id: string,
type: "MSG_FROM_USER",
payload: {
user: {
login: string,
}
}
}
```

where:

- `id` - request identifier
- `login` - username of the user with whom the message history is requested

Server Response

```javascript
{
id: string,
type: "MSG_FROM_USER",
payload: {
messages: [],
}
}
```

where:

- `id` - request identifier received from the client
- `messages` - array of messages sorted in ascending order by date and time, structurally corresponding to the `message` field in ["Receiving a Message From a User"](#Receiving-a-Message-From-a-User) section. An empty array is not considered an error.

Server Responses in Case of Errors

- the sender's and recipient's logins match

```javascript
{
id: string,
type: "ERROR",
payload: {
error: 'sender and recipient logins are the same',
}
}
```

- the user with the specified login does not exist

```javascript
{
id: string,
type: "ERROR",
payload: {
error: 'the user with the specified login does not exist',
}
}
```

- the user sending the request is not authenticated

```javascript
{
id: string,
type: "ERROR",
payload: {
error: 'user not registered or not logged',
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### Notification of Message Delivery Status Change

Initiator: Server application

Description: The request is sent to the message sender when the server receives a request from the recipient user according to the ["Fetching Message History With the User"](#Fetching-Message-History-With-the-User) section and the current status `isDelivered` is `false`. In this case, the server sets the `isDelivered` status to `true` before forwarding the message to the sender user.

Request from the Server

```javascript
{
id: null,
type: "MSG_DELIVER",
payload: {
message: {
id: string,
status: {
isDelivered: boolean,
}
}
}
}
```

where:

- `id` - request identifier generated by the server
- `message` - user's message field where:
- `id` - message identifier
- `isDelivered` - status which indicates whether the message has been delivered to the recipient

### Message Read Status Change

Initiator: Client application

Description: Used to change the status of `isReaded` to `true`. Upon successful processing of the request, the server sends a notification to the sender in accordance with ["Notification of Message Read Status Change"](#Notification-of-Message-Read-Status-Change) section.

Request to the Server

```javascript
{
id: string,
type: "MSG_READ",
payload: {
message: {
id: string,
}
}
}
```

where:

- `id` - request identifier
- `message` - user's message field where:
- `id` - message identifier

Server Response

```javascript
{
id: string,
type: "MSG_READ"
payload: {
message: {
id: string,
status: {
isReaded: boolean,
}
}
}
}
```

where:

- `id` - request identifier received from the client
- `message` - user's message field where:
- `id` - message identifier
- `isReaded` - current read status of the message

Server Responses in Case of Errors

- the message with the provided `id` does not exist

```javascript
{
id: string,
type: "ERROR"
payload: {
error: 'incorrect message id',
}
}
```

- the user sending the request is not the recipient of the message

```javascript
{
id: string,
type: "ERROR"
payload: {
error: 'user not recipient cannot be executed',
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### Notification of Message Read Status Change

Initiator: Server application

Description: This request is sent to the user who sent the message after the server successfully processes the request to change the `isReaded` status according to ["Message Read Status Change"](#Message-Read-Status-Change) section, provided that the sending user is authenticated.

Request from the Server

```javascript
{
id: null,
type: "MSG_READ"
payload: {
message: {
id: string,
status: {
isReaded: boolean,
}
}
}
}
```

where:

- `id` - request identifier generated by the server
- `message` - user's message field where:
- `id` - message identifier
- `isReaded` - current read status of the message

### Message Deletion

Initiator: Client application

Description: Used to delete a message sent to another user. If the recipient is authenticated, a notification is sent to them according to ["Notification of Message Deletion"](#Notification-of-Message-Deletion) section.

Request to the Server

```javascript
{
id: string,
type: "MSG_DELETE"
payload: {
message: {
id: string,
}
}
}
```

where:

- `id` - request identifier
- `message` - user's message field where:
- `id` - message identifier

Server Response

```javascript
{
id: string,
type: "MSG_DELETE"
payload: {
message: {
id: string,
status: {
isDeleted: boolean,
}
}
}
}
```

where:

- `id` - request identifier received from the client
- `message` - created message where:
- `id` - message identifier
- `isDeleted` - status which indicates whether the message has been deleted

Server Responses in Case of Errors

- the message with the provided `id` does not exist

```javascript
{
id: string,
type: "ERROR"
payload: {
error: 'incorrect message id',
}
}
```

- the user is not the sender of the message

```javascript
{
id: string,
type: "ERROR"
payload: {
error: 'user not sender cannot be executed',
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### Notification of Message Deletion

Initiator: Server application

Description: This request is sent to the recipient user after the server successfully processes a message deletion request in accordance with ["Message Deletion"](#Message-Deletion) section, provided that the recipient user is authorized.

Request from the Server

```javascript
{
id: null,
type: "MSG_DELETE"
payload: {
message: {
id: string,
status: {
isDeleted: boolean,
}
}
}
}
```

where:

- `id` - request identifier generated by the server
- `message` - created message where:
- `id` - message identifier
- `isDeleted` - status which indicates whether the message has been deleted

### Message Text Editing

Initiator: Client application

Description: Used to edit the text of a message sent to another user. If the recipient of the message is authorized, a notification is sent to them in accordance with ["Notification of Message Text Editing"](#Notification-of-Message-Text-Editing) section.

Request to the Server

```javascript
{
id: string,
type: "MSG_EDIT"
payload: {
message: {
id: string,
text: string
}
}
}
```

where:

- `id` - request identifier
- `message` - user's message field where:
- `id` - message identifier
- `text` - text of the message

Server Response

```javascript
{
id: string,
type: "MSG_EDIT"
payload: {
message: {
id: string,
text: string,
status: {
isEdited: boolean,
}
}
}
}
```

where:

- `id` - request identifier received from the client
- `message` - created message where:
- `id` - message identifier
- `text` - edited text of the message
- `isEdited` - status which indicates whether the message has been edited

Server Responses in Case of Errors

- the message with the provided `id` does not exist

```javascript
{
id: string,
type: "ERROR"
payload: {
error: 'incorrect message id',
}
}
```

- another user is the sender of the message

```javascript
{
id: string,
type: "ERROR"
payload: {
error: 'user not sender cannot be executed',
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the cause of the error

### Notification of Message Text Editing

Initiator: Server application

Description: This request is sent to the recipient user after the server successfully processes a message editing request in accordance with ["Message Text Editing"](#Message-Text-Editing) section, provided that the recipient user is authorized.

Request from the Server

```javascript
{
id: null,
type: "MSG_EDIT"
payload: {
message: {
id: string,
text: string,
status: {
isEdited: boolean,
}
}
}
}
```

where:

- `id` - request identifier generated by the server
- `message` - created message where:
- `id` - message identifier
- `text` - edited text of the message
- `isEdited` - status which indicates whether the message has been edited

### Server Responses in Case of Request Errors

When an error occurs in the request, the server returns a message indicating the reason for the error.

General Response Format for Requests with Errors

- detailed descriptions of errors and their causes are provided in the request descriptions

```javascript
{
id: string,
type: "ERROR",
payload: {
error: string,
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the error

Server Responses for Common Errors

Incorrect Request Structure

- sent by the server in response to a request that does not contain one of the mandatory fields (`id`, `type`, `payload`) or if the field type does not match this description

```javascript
{
id: string | null,
type: "ERROR",
payload: {
error: "incorrect request structure",
}
}
```

where:

- `id` - request identifier received from the client or `null` if there is no identifier in the request
- `error` - description of the error

Request Type

- sent by the server in response to a request with a `type` parameter not supported by the server

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "incorrect type parameters",
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the error

Request Payload Is Not Supported by the Server

- sent by the server in response to a request with a `payload` parameter not supported by the server

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "incorrect payload parameters",
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the error

Internal Server Error

- sent by the server in response to a request that resulted in an unexpected error

```javascript
{
id: string,
type: "ERROR",
payload: {
error: "internal server error",
}
}
```

where:

- `id` - request identifier received from the client
- `error` - description of the error