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
- Host: GitHub
- URL: https://github.com/rolling-scopes-school/fun-chat-server
- Owner: rolling-scopes-school
- Created: 2024-01-21T17:23:28.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-04-13T19:46:32.000Z (over 1 year ago)
- Last Synced: 2025-04-13T20:36:10.874Z (over 1 year ago)
- Language: JavaScript
- Size: 106 KB
- Stars: 6
- Watchers: 1
- Forks: 80
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
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