Compare commits
1 Commits
main
...
break-data
Author | SHA1 | Date |
---|---|---|
~erin | 64bb346a11 |
25
CHANGELOG.md
25
CHANGELOG.md
|
@ -3,10 +3,16 @@
|
||||||
- `/api/register` & `/api/login` now use JSON data
|
- `/api/register` & `/api/login` now use JSON data
|
||||||
- Changing user info now uses Enum (Name, Pin, or Pronouns)
|
- Changing user info now uses Enum (Name, Pin, or Pronouns)
|
||||||
|
|
||||||
### 0.6.1
|
### 0.5.2
|
||||||
- Add basic support for different user roles & moderator commands
|
- When changing a username, it now deletes the previous user instead of creating a new one
|
||||||
- Any user names "admin" will be made into an Admin user
|
- Database functions should now use some error handling
|
||||||
- User pronouns are stored in message body now
|
- Functions use `db_read_user()` instead of reading in the whole database
|
||||||
|
|
||||||
|
### 0.5.1
|
||||||
|
- `/api/logout` API to delete session token
|
||||||
|
- Add basic support for different message types
|
||||||
|
- Messages now use unix timestamps
|
||||||
|
- Backend finds timestamp
|
||||||
|
|
||||||
## 0.5.0
|
## 0.5.0
|
||||||
- Most actions should now fail on a NULL token
|
- Most actions should now fail on a NULL token
|
||||||
|
@ -14,17 +20,6 @@
|
||||||
- Use sled database instead of json file to store users
|
- Use sled database instead of json file to store users
|
||||||
- Now use `GET /api/token/<name>` to validate a users session token
|
- Now use `GET /api/token/<name>` to validate a users session token
|
||||||
|
|
||||||
### 0.5.1
|
|
||||||
- `/api/logout` API to delete session token
|
|
||||||
- Add basic support for different message types
|
|
||||||
- Messages now use unix timestamps
|
|
||||||
- Backend finds timestamp
|
|
||||||
|
|
||||||
### 0.5.2
|
|
||||||
- When changing a username, it now deletes the previous user instead of creating a new one
|
|
||||||
- Database functions should now use some error handling
|
|
||||||
- Functions use `db_read_user()` instead of reading in the whole database
|
|
||||||
|
|
||||||
## 0.4.0
|
## 0.4.0
|
||||||
- Serve frontend code
|
- Serve frontend code
|
||||||
- Set cookie for token
|
- Set cookie for token
|
||||||
|
|
|
@ -576,25 +576,6 @@ version = "0.2.98"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lila-chat"
|
|
||||||
version = "0.6.1"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"chrono",
|
|
||||||
"env_logger",
|
|
||||||
"log 0.4.14",
|
|
||||||
"once_cell",
|
|
||||||
"random-string",
|
|
||||||
"rocket",
|
|
||||||
"rocket_contrib",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"sha1",
|
|
||||||
"sled",
|
|
||||||
"uuid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -824,6 +805,25 @@ version = "2.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pogchat"
|
||||||
|
version = "0.6.0"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"chrono",
|
||||||
|
"env_logger",
|
||||||
|
"log 0.4.14",
|
||||||
|
"once_cell",
|
||||||
|
"random-string",
|
||||||
|
"rocket",
|
||||||
|
"rocket_contrib",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sha1",
|
||||||
|
"sled",
|
||||||
|
"uuid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "polyval"
|
name = "polyval"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
|
@ -1,11 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lila-chat"
|
name = "pogchat"
|
||||||
description = "A basic chat server written in rust"
|
version = "0.6.0"
|
||||||
version = "0.6.1"
|
authors = ["Erin Nova <erin@the-system.eu.org>"]
|
||||||
documentation = "https://git.lavender.software/erin/lila-chat/wiki"
|
|
||||||
repository = "https://git.lavender.software/erin/lila-chat/"
|
|
||||||
license = "CNPLv6+"
|
|
||||||
authors = ["Erin Nova <erin@the-system.eu.org>", "Charlotte"]
|
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
109
README.md
109
README.md
|
@ -4,7 +4,101 @@ A simple chat system for built for maya's livestream.
|
||||||
Provides a simple API for user authentication, and chat functions.
|
Provides a simple API for user authentication, and chat functions.
|
||||||
Frontend & backend code stored here.
|
Frontend & backend code stored here.
|
||||||
|
|
||||||
## Implemented Features:
|
## Auth API Documentation
|
||||||
|
|
||||||
|
Most API functions will return JSON in the following format:
|
||||||
|
|
||||||
|
`status`: either `ok` if action succeeded, or `fail` otherwise.
|
||||||
|
|
||||||
|
`reason`: More info about why the action failed.
|
||||||
|
|
||||||
|
### Register & Login:
|
||||||
|
|
||||||
|
`POST /api/register` with JSON body values of: `name`, `pin`, `pronouns`.
|
||||||
|
|
||||||
|
Will return JSON with `status` and `reason`.
|
||||||
|
|
||||||
|
`POST /api/login` with JSON body values of: `name`, `pin`.
|
||||||
|
|
||||||
|
Will return JSON with `status` and `reason`.
|
||||||
|
|
||||||
|
Will set a private cookie named `token` which is used for authentication.
|
||||||
|
|
||||||
|
### Change User Information
|
||||||
|
|
||||||
|
User information such as name, pin, and pronouns, can be changed currently one at a time.
|
||||||
|
|
||||||
|
`POST /api/change` with JSON body values of: `name`, `changed_event`, `new_event`.
|
||||||
|
|
||||||
|
`name` the user's current username. used for authentication.
|
||||||
|
|
||||||
|
`changed_event` which event to change. value can be one of: `Name`, `Pin`, `Pronouns`.
|
||||||
|
|
||||||
|
`new_event` the new value for the changed event.
|
||||||
|
|
||||||
|
User is authenticated via token.
|
||||||
|
|
||||||
|
### Check if User is Still Logged in
|
||||||
|
|
||||||
|
Instead of having to save the pin and re-login every time to check wether they're logged in, you can just check via the token.
|
||||||
|
|
||||||
|
`GET /api/token/<name>` where `<name>` is the current username.
|
||||||
|
|
||||||
|
Will return JSON with `status` and `reason`.
|
||||||
|
|
||||||
|
### Logout
|
||||||
|
|
||||||
|
This API will remove the cookie from the client, as well as invalidating the token serverside.
|
||||||
|
|
||||||
|
`POST /api/logout` with JSON body values of: `name`.
|
||||||
|
|
||||||
|
Will use the current token as authentication.
|
||||||
|
|
||||||
|
Will return JSON with `status` and `reason`.
|
||||||
|
|
||||||
|
### Get Info About A User
|
||||||
|
|
||||||
|
This API will return info about a user on success.
|
||||||
|
|
||||||
|
`GET /api/users/<name>`
|
||||||
|
|
||||||
|
On success returns JSON in format:
|
||||||
|
```
|
||||||
|
status: ok
|
||||||
|
user:
|
||||||
|
name: user's name
|
||||||
|
pronouns: user's pronouns
|
||||||
|
role: the users role, one of either 'Normal', 'Moderator', or 'Admin'
|
||||||
|
```
|
||||||
|
|
||||||
|
eg:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
status: "ok",
|
||||||
|
user: {
|
||||||
|
name: "example",
|
||||||
|
pronouns: "they/them",
|
||||||
|
role: "Normal",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Chat API Documentation
|
||||||
|
|
||||||
|
`POST /api/message/send {"name":"username","body":"message body"}` Post a message with JSON body values of: `name` & `body`
|
||||||
|
|
||||||
|
Will return JSON with `status` and `reason`.
|
||||||
|
|
||||||
|
`GET /api/message/messages.json` Returns a json file of all the messages
|
||||||
|
|
||||||
|
## Chat Planning
|
||||||
|
|
||||||
|
Clientside js will register & check login of users, if login is correct will ask for a random token.
|
||||||
|
Backend will generate token, store it, and then send it to the client to set as a cookie.
|
||||||
|
Whenever user sends a message, client will send message & token and backend will check if token matches.
|
||||||
|
|
||||||
|
## To-Do:
|
||||||
|
|
||||||
- [x] Basic auth API
|
- [x] Basic auth API
|
||||||
- [x] Return json instead of string
|
- [x] Return json instead of string
|
||||||
|
@ -14,6 +108,7 @@ Frontend & backend code stored here.
|
||||||
- [x] Finish up `chat::create_message()`
|
- [x] Finish up `chat::create_message()`
|
||||||
- [x] Create `chat::fetch_messages()`
|
- [x] Create `chat::fetch_messages()`
|
||||||
- [x] Use unix timestamp for date
|
- [x] Use unix timestamp for date
|
||||||
|
- [ ] Create `chat::delete_message()`
|
||||||
- [x] Switch to using sled database to store users
|
- [x] Switch to using sled database to store users
|
||||||
- [x] Error handling
|
- [x] Error handling
|
||||||
- [x] Token generation & storage
|
- [x] Token generation & storage
|
||||||
|
@ -28,20 +123,10 @@ Frontend & backend code stored here.
|
||||||
- [x] Set pronouns
|
- [x] Set pronouns
|
||||||
- [x] Change pronouns
|
- [x] Change pronouns
|
||||||
- [x] make changed_event Enum, use token instead of pin
|
- [x] make changed_event Enum, use token instead of pin
|
||||||
|
|
||||||
## To-Do:
|
|
||||||
|
|
||||||
- [x] Better messaging system
|
|
||||||
- [ ] Use websockets for chat [issue#3](https://git.lavender.software/erin/lila-chat/issues/3)
|
|
||||||
- [ ] Create `chat::delete_message()`
|
|
||||||
- [ ] Display pronouns [issue#4](https://git.lavender.software/erin/lila-chat/issues/4)
|
|
||||||
- [ ] Various database improvements [issue#1](https://git.lavender.software/erin/lila-chat/issues/1)
|
|
||||||
- [ ] Improve error handling on write functions
|
|
||||||
- [ ] Allow for asyncronous reading/writing
|
|
||||||
- [ ] Some form of plural support?
|
- [ ] Some form of plural support?
|
||||||
- [ ] User management (banning, etc.)
|
- [ ] User management (banning, etc.)
|
||||||
- [x] User roles (admin, mod, etc.)
|
- [x] User roles (admin, mod, etc.)
|
||||||
- [ ] Commands to affect users [issue#2](https://git.lavender.software/erin/lila-chat/issues/2)
|
- [ ] Commands to affect users
|
||||||
- [ ] Blacklist words from chat/names
|
- [ ] Blacklist words from chat/names
|
||||||
- [ ] More advanced chat features
|
- [ ] More advanced chat features
|
||||||
- [x] Different types of message events? eg. default, announcement, command
|
- [x] Different types of message events? eg. default, announcement, command
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,43 @@
|
||||||
|
html {
|
||||||
|
background: #F7A8B8;
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Lucida Console", "Courier New", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
padding: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox {
|
||||||
|
background-color: white;
|
||||||
|
padding: 1rem;
|
||||||
|
box-shadow: 10px 10px 10px black;
|
||||||
|
width: 40rem;
|
||||||
|
height: 40rem;
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#innerchatbox {
|
||||||
|
background-color: rgba(60, 60, 60, .75);
|
||||||
|
width: 100%;
|
||||||
|
height: 90%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loggeduser {
|
||||||
|
padding-top: 1%
|
||||||
|
}
|
||||||
|
|
||||||
|
#error {
|
||||||
|
padding-top: 2.5%;
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
<meta name="description" content="Maya's Stream Chat">
|
<meta name="description" content="Maya's Stream Chat">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="../css/chat.css">
|
<link rel="stylesheet" href="chat.css">
|
||||||
<link rel="icon" href="">
|
<link rel="icon" href="">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -15,27 +15,22 @@
|
||||||
|
|
||||||
<h1>Welcome to the chat!</h1>
|
<h1>Welcome to the chat!</h1>
|
||||||
|
|
||||||
<div id="outerchatbox">
|
<div id="chatbox">
|
||||||
|
|
||||||
<div id="chatbox">
|
<div id="innerchatbox">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form autocomplete="off">
|
<form autocomplete="off">
|
||||||
|
<label for="message">Input Message Here:</label>
|
||||||
<input type="text" id="message" name="message" required>
|
<input type="text" id="message" name="message" required>
|
||||||
<label for="message">Input Message Above</label>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="loggeduser"></div>
|
<div id="loggeduser"></div>
|
||||||
|
|
||||||
<button type="button" id="logoutbutton" onclick="logout()">Logout</button>
|
<script src="chat.js"></script>
|
||||||
|
|
||||||
<div id="errormessage"></div>
|
|
||||||
|
|
||||||
<script src="../js/chat.js"></script>
|
|
||||||
<script src="../js/logout.js"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
// VARIABLES
|
||||||
|
let date = '2021-07-22'
|
||||||
|
let messageCount = 0;
|
||||||
|
let username = localStorage.getItem('username');
|
||||||
|
const form = document.querySelector('form');
|
||||||
|
|
||||||
|
// SEND A MESSAGE
|
||||||
|
|
||||||
|
// GRABS MESSAGE FROM FORM & SENDS
|
||||||
|
form.addEventListener("submit", async function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const formData = new FormData(form);
|
||||||
|
|
||||||
|
formMessage = formData.get('message');
|
||||||
|
|
||||||
|
sendMessage()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
//SEND MESSAGE FETCH FUNCTION
|
||||||
|
|
||||||
|
async function sendMessage() {
|
||||||
|
sendMessageInfo = { "name": username, "body": formMessage, "date": date }
|
||||||
|
fetch('/api/message/send', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(sendMessageInfo),
|
||||||
|
})
|
||||||
|
form.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// RECIEVE MESSAGES
|
||||||
|
|
||||||
|
let messageUpdate = window.setInterval(fetchMessages, 500);
|
||||||
|
|
||||||
|
async function fetchMessages() {
|
||||||
|
const response = await fetch('/api/message/messages.json');
|
||||||
|
const recievedMessages = await response.json();
|
||||||
|
document.getElementById("innerchatbox").innerHTML = ""
|
||||||
|
|
||||||
|
for (const message of recievedMessages) {
|
||||||
|
printText(message.user.bold() + ": " + message.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (recievedMessages.length != messageCount) {
|
||||||
|
let scroll = document.getElementById("innerchatbox");
|
||||||
|
scroll.scrollTop = scroll.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageCount = recievedMessages.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTION TO PRINT MESSAGES IN THE CHAT BOX
|
||||||
|
|
||||||
|
function printText(text) {
|
||||||
|
let p = document.createElement("p");
|
||||||
|
const div = document.getElementById("innerchatbox");
|
||||||
|
div.appendChild(p)
|
||||||
|
p.innerHTML = text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//LOGGED IN STUFF
|
||||||
|
//TODO ADD CHECK TO SEE IF USERNAME AND TOKEN MATCHES
|
||||||
|
if (username === null) {
|
||||||
|
document.querySelector("#loggeduser").innerHTML = 'You are not logged in'
|
||||||
|
username = ''
|
||||||
|
} else {
|
||||||
|
document.querySelector("#loggeduser").innerHTML = `You are logged in as ${username}`
|
||||||
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
html {
|
|
||||||
background: #F7A8B8;
|
|
||||||
text-align: center;
|
|
||||||
font-family: "Linotte", "Lucida Console", monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Linotte;
|
|
||||||
src: url(../assets/LinotteRegular.otf);
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
width: 100%;
|
|
||||||
overflow:hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
margin-top: 1%;
|
|
||||||
padding: 2%;
|
|
||||||
width: 100%;
|
|
||||||
background-color: darkgrey;
|
|
||||||
border-style: none;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
border-bottom-color: black;
|
|
||||||
border-bottom-width: 1px;
|
|
||||||
font-family: "Lucida Console", "Courier New", monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: block;
|
|
||||||
margin-top: 1%;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
padding: 1%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#loggeduser {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#outerchatbox {
|
|
||||||
background-color: rgb(255, 199, 207);
|
|
||||||
padding: 1rem;
|
|
||||||
box-shadow: 10px 10px 10px black;
|
|
||||||
width: 30rem;
|
|
||||||
height: 40rem;
|
|
||||||
display: inline-flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chatbox {
|
|
||||||
background-color: rgb(60, 60, 60);
|
|
||||||
width: 100%;
|
|
||||||
height: 90%;
|
|
||||||
overflow-y: scroll;
|
|
||||||
overflow-x: hidden;
|
|
||||||
text-align: left;
|
|
||||||
color: white;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#loggeduser {
|
|
||||||
padding-top: 2%
|
|
||||||
}
|
|
||||||
|
|
||||||
#errormessage {
|
|
||||||
padding-top: 2.5%;
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
html {
|
|
||||||
background: #F7A8B8;
|
|
||||||
font-family: "Linotte", "Lucida Console", monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: Linotte;
|
|
||||||
src: url(../assets/LinotteRegular.otf);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: black;
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#streamchat {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
max-width: 960px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: -1%;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#stream {
|
|
||||||
width: 960px;
|
|
||||||
height: 540px;
|
|
||||||
margin-right: 0.3em;
|
|
||||||
margin-left: -40%;
|
|
||||||
margin-top: 5%;
|
|
||||||
margin-bottom: 20%;
|
|
||||||
font-size: 250%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#streamframe {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chatbox {
|
|
||||||
flex: 1;
|
|
||||||
height: 53rem;
|
|
||||||
margin-left: 0.3em;
|
|
||||||
margin-right: -30%;
|
|
||||||
margin-top: -8%;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navigation-list {
|
|
||||||
display: inline-flex;
|
|
||||||
list-style-type: none;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 10px;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 0;
|
|
||||||
margin-left: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
width: 150px;
|
|
||||||
background-color: #55CDFC;
|
|
||||||
margin: auto;
|
|
||||||
margin-bottom: 2%;
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
opacity: 0.8;
|
|
||||||
font-size: larger;
|
|
||||||
color: black;
|
|
||||||
padding: 15px;
|
|
||||||
border-bottom: solid;
|
|
||||||
border-left: solid;
|
|
||||||
border-color: lightblue;
|
|
||||||
border-width: 2px;
|
|
||||||
}
|
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
@ -9,6 +9,9 @@
|
||||||
id="svg5"
|
id="svg5"
|
||||||
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
|
||||||
sodipodi:docname="favicon.svg"
|
sodipodi:docname="favicon.svg"
|
||||||
|
inkscape:export-filename="/home/erin/bitmap.png"
|
||||||
|
inkscape:export-xdpi="200"
|
||||||
|
inkscape:export-ydpi="200"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.8 KiB |
|
@ -1,73 +1,34 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>Maya's Stream</title>
|
<title>Maya's Stream</title>
|
||||||
<meta name="author" content="Luna">
|
<meta name="author" content="Luna">
|
||||||
<meta name="description" content="Maya's Stream">
|
<meta name="description" content="Maya's Stream">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="css/index.css">
|
<link rel="stylesheet" href="stream.css">
|
||||||
<link rel="icon" href="assets/favicon.svg">
|
<link rel="icon" href="/favicon.svg">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<nav>
|
<nav>
|
||||||
|
|
||||||
<ul class="navigation-list">
|
<a href="register.html">Register Page</a>
|
||||||
<li><a href="index.html">
|
|
||||||
<div class="buttons">Stream</div>
|
|
||||||
</a></li>
|
|
||||||
<li><a href="/html/chat.html">
|
|
||||||
<div class="buttons">Just Chat</div>
|
|
||||||
</a></li>
|
|
||||||
<li><a href="/html/register.html">
|
|
||||||
<div class="buttons">Register</div>
|
|
||||||
</a></li>
|
|
||||||
<li><a href="/html/login.html">
|
|
||||||
<div class="buttons">Login</div>
|
|
||||||
</a></li>
|
|
||||||
<li><a href="/html/updateinfo.html">
|
|
||||||
<div class="buttons">Update Info</div>
|
|
||||||
</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
<a href="login.html">Login Page</a>
|
||||||
|
|
||||||
</nav>
|
<a href="updateinfo.html">Update Info Page</a>
|
||||||
|
|
||||||
<script>
|
|
||||||
// Checking if the stream is down and displays a message if it is.
|
|
||||||
async function isStreamDown() {
|
|
||||||
|
|
||||||
const response = await fetch(`https://cdn.chaos.stream/hls/src/maya.m3u8`);
|
|
||||||
|
|
||||||
if (response.status === 404) {
|
|
||||||
document.getElementById("streamframe").style.display = "none";
|
|
||||||
document.getElementById("stream").style.border = 'double'
|
|
||||||
document.getElementById("stream").innerHTML = 'Currently not streaming.'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = isStreamDown()
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
|
|
||||||
<div id="streamchat">
|
|
||||||
<div id="stream">
|
|
||||||
<iframe id="streamframe" src="https://live.on.chaos.stream/maya" title="mayas stream"
|
|
||||||
scrolling="no"></iframe>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<iframe id="chatbox" src="/html/chat.html" title="chat box" scrolling="no"></iframe>
|
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
<div id="streamchat">
|
||||||
|
<div id="stream">
|
||||||
|
<h1>Test Text</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</section>
|
<iframe id="chatbox" src="chat.html" title="chat box"></iframe>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
</main>
|
</html>
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,148 +0,0 @@
|
||||||
// VARIABLES
|
|
||||||
let messageCount = 0;
|
|
||||||
let username = localStorage.getItem('username');
|
|
||||||
const form = document.querySelector('form');
|
|
||||||
|
|
||||||
// SEND A MESSAGE
|
|
||||||
|
|
||||||
// GRABS MESSAGE FROM FORM & SENDS
|
|
||||||
form.addEventListener("submit", async function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const formData = new FormData(form);
|
|
||||||
|
|
||||||
formMessage = formData.get('message').toString();
|
|
||||||
|
|
||||||
//KINDA UNNECESSARY
|
|
||||||
//CHECKS TO SEE IF THE PERSON IS LOGGED IN IN ORDER TO SEND A MESSAGE.
|
|
||||||
const response = await fetch(`../api/token/${username}/`);
|
|
||||||
const matches = await response.json();
|
|
||||||
|
|
||||||
//YES THIS IS CONFUSING I KNOW.
|
|
||||||
if (matches.status === "ok") {
|
|
||||||
sendMessage()
|
|
||||||
} else {
|
|
||||||
const mismatch = 'Username and token mismatch. Try logging in again.'
|
|
||||||
printText(mismatch.bold())
|
|
||||||
logout()
|
|
||||||
localStorage.removeItem('username')
|
|
||||||
form.reset()
|
|
||||||
}
|
|
||||||
return formMessage;
|
|
||||||
})
|
|
||||||
|
|
||||||
//SEND MESSAGE FETCH FUNCTION
|
|
||||||
|
|
||||||
async function sendMessage() {
|
|
||||||
sendMessageInfo = { "name": username, "body": formMessage }
|
|
||||||
fetch('../api/message/send', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(sendMessageInfo),
|
|
||||||
})
|
|
||||||
form.reset()
|
|
||||||
modCommand()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// RECIEVE MESSAGES
|
|
||||||
|
|
||||||
let messageUpdate = window.setInterval(fetchMessages, 1000);
|
|
||||||
|
|
||||||
async function fetchMessages() {
|
|
||||||
const response = await fetch('/api/message/messages.json');
|
|
||||||
const recievedMessages = await response.json();
|
|
||||||
document.getElementById("chatbox").innerHTML = ""
|
|
||||||
|
|
||||||
for (const message of recievedMessages) {
|
|
||||||
|
|
||||||
let leftBracket = '('
|
|
||||||
let rightBracket = ')'
|
|
||||||
let space = ' '
|
|
||||||
|
|
||||||
if (message.pronouns === '' || message.pronouns === 'none' || message.pronouns === null) {
|
|
||||||
leftBracket = ''
|
|
||||||
rightBracket = ''
|
|
||||||
space = ''
|
|
||||||
}
|
|
||||||
printText(message.user.bold().toString() + space + "<i style='color:#b8d1e7'>" + leftBracket.small() + message.pronouns.small().toString() + rightBracket.small() + "</i>" + " : " + "<span style='color:#e4e4ef'>" + message.body.toString() + "</span>");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (recievedMessages.length != messageCount) {
|
|
||||||
let scroll = document.getElementById("chatbox");
|
|
||||||
scroll.scrollTop = scroll.scrollHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
messageCount = recievedMessages.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FUNCTION TO PRINT MESSAGES IN THE CHAT BOX
|
|
||||||
|
|
||||||
function printText(text) {
|
|
||||||
let p = document.createElement("p");
|
|
||||||
const div = document.getElementById("chatbox");
|
|
||||||
div.appendChild(p)
|
|
||||||
p.innerHTML = text
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//LOGGED IN STUFF
|
|
||||||
//TODO ADD CHECK TO SEE IF USERNAME AND TOKEN MATCHES
|
|
||||||
function loggedIn() {
|
|
||||||
if (username === '' || username === null) {
|
|
||||||
document.querySelector("#loggeduser").innerHTML = 'You are not logged in'
|
|
||||||
} else {
|
|
||||||
document.querySelector("#loggeduser").innerHTML = `You are logged in as "${username}"`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loggedIn()
|
|
||||||
|
|
||||||
//MODERATION
|
|
||||||
|
|
||||||
async function modCommand() {
|
|
||||||
let action = ''
|
|
||||||
let target = ''
|
|
||||||
|
|
||||||
if (formMessage.startsWith('/ban')) {
|
|
||||||
action = "Ban"
|
|
||||||
target = formMessage.replace('/ban ', '')
|
|
||||||
sendCommand()
|
|
||||||
} else if (formMessage.startsWith('/kick')) {
|
|
||||||
action = "Kick"
|
|
||||||
target = formMessage.replace('/kick ', '')
|
|
||||||
sendCommand()
|
|
||||||
} else if (formMessage.startsWith('/promote')) {
|
|
||||||
action = "Promote"
|
|
||||||
target = formMessage.replace('/promote ', '')
|
|
||||||
sendCommand()
|
|
||||||
} else if (formMessage.startsWith('/demote')) {
|
|
||||||
action = "Demote"
|
|
||||||
target = formMessage.replace('/demote ', '')
|
|
||||||
sendCommand()
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendCommand() {
|
|
||||||
let sendCommand = { "name": username, "action": action, "target": target }
|
|
||||||
const response = await fetch('/api/mod/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(sendCommand),
|
|
||||||
});
|
|
||||||
if (response.status === 'ok') {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
printText('Error Issuing Command. Are you an Admin or Mod?')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// // //VARIBLES
|
|
||||||
// myStorage = window.localStorage;
|
|
||||||
// allCookies = document.cookie;
|
|
||||||
|
|
||||||
//LOGOUT FETCH FUNCTION
|
|
||||||
|
|
||||||
async function logout() {
|
|
||||||
let sendLogoutInfo = { "name": username }
|
|
||||||
fetch('/api/logout/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(sendLogoutInfo),
|
|
||||||
});
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'Logged out.'
|
|
||||||
document.getElementById("logoutbutton").style.display = "none";
|
|
||||||
localStorage.removeItem('username')
|
|
||||||
username = null;
|
|
||||||
loggedIn()
|
|
||||||
}
|
|
||||||
|
|
||||||
// // IF THERE IS A TOKEN BUT NO USERNAME LOGOUT
|
|
||||||
// if (allCookies !== '' && myStorage.length === 0) {
|
|
||||||
// logout()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // IF THERE IS NO COOKIE BUT A USERNAME GET RID OF USERNAME LOCALLY.
|
|
||||||
// if (allCookies === '' && myStorage.length !== 0) {
|
|
||||||
// localStorage.removeItem('username')
|
|
||||||
// document.querySelector("#loggeduser").innerHTML = 'You are not logged in'
|
|
||||||
// }
|
|
|
@ -1,82 +0,0 @@
|
||||||
|
|
||||||
//DECLARING VARIABLES AND GRABBING VALUES FROM FORM.
|
|
||||||
|
|
||||||
let uname = document.querySelector('#uname').value;
|
|
||||||
let pin = document.querySelector('#pin').value;
|
|
||||||
let selected = document.querySelector('#selected').value;
|
|
||||||
let custom = document.querySelector('#custom').value;
|
|
||||||
let pronouns = ''
|
|
||||||
const form = document.querySelector('form');
|
|
||||||
|
|
||||||
//SUBMIT FUNCTION & CHECKING IF USERNAME IS TAKEN
|
|
||||||
|
|
||||||
form.addEventListener("submit", async function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
const formData = new FormData(form);
|
|
||||||
|
|
||||||
uname = formData.get('uname');
|
|
||||||
pin = formData.get('pin');
|
|
||||||
selected = formData.get('selected');
|
|
||||||
custom = formData.get('custom')
|
|
||||||
|
|
||||||
if (custom === '' && selected === 'none') {
|
|
||||||
pronouns = ''
|
|
||||||
} else if (custom !== '') {
|
|
||||||
pronouns = custom
|
|
||||||
} else {
|
|
||||||
pronouns = selected
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//IF THE API SUCCESSFULLY REGISTERS A USER THEN DO THIS
|
|
||||||
try {
|
|
||||||
const regRes = await isUnameTaken();
|
|
||||||
|
|
||||||
if (regRes == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (regRes.status === 'ok') {
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'Registered!'
|
|
||||||
window.location.replace("../html/login.html")
|
|
||||||
} else {
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'Failed to register. Try again later.'
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'An Error has Occurred. Try again later. ' + e.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
//CHECKS IF A USERNAME IS TAKEN
|
|
||||||
async function isUnameTaken() {
|
|
||||||
|
|
||||||
const response = await fetch(`/api/users/${uname}/`);
|
|
||||||
const isTaken = await response.json();
|
|
||||||
|
|
||||||
//YES THIS IS CONFUSING I KNOW.
|
|
||||||
if (isTaken.status === "fail") {
|
|
||||||
return await register()
|
|
||||||
} else {
|
|
||||||
document.querySelector('#errormessage').innerHTML = `${uname} is already taken.`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//FETCH FUNCTIONS. GETTING USERNAME FROM API & REGISTERING USER ASSIGNED NAME AND PIN.
|
|
||||||
|
|
||||||
async function register() {
|
|
||||||
let sendRegisterInfo = { "name": uname, "pin": pin, "pronouns": pronouns }
|
|
||||||
const response = await fetch('../api/register/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(sendRegisterInfo),
|
|
||||||
});
|
|
||||||
return await response.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
// function errorMessage() {
|
|
||||||
// document.querySelector("#errormessage").innerHTML = 'An error has occurrred. Please try again later.'
|
|
||||||
// }
|
|
|
@ -7,8 +7,8 @@
|
||||||
<meta name="description" content="Chat Login">
|
<meta name="description" content="Chat Login">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<link rel="icon" href="../assets/favicon.svg">
|
<link rel="icon" href="/favicon.svg">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../js/login.js"></script>
|
<script src="login.js"></script>
|
||||||
|
|
||||||
<div id="errormessage"></div>
|
<div id="errormessage"></div>
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
let uname = document.querySelector('#uname').value;
|
let uname = document.querySelector('#uname').value;
|
||||||
let pin = document.querySelector('#pin').value;
|
let pin = document.querySelector('#pin').value;
|
||||||
const form = document.querySelector('form');
|
const form = document.querySelector('form');
|
||||||
let username = localStorage.getItem('username');
|
|
||||||
|
|
||||||
// SUBMIT FORM FUNCTION. AND FETCH USERNAME AND PIN FROM API.
|
// SUBMIT FORM FUNCTION. AND FETCH USERNAME AND PIN FROM API.
|
||||||
|
|
||||||
|
@ -15,43 +14,24 @@ form.addEventListener("submit", async function (event) {
|
||||||
uname = formData.get('uname');
|
uname = formData.get('uname');
|
||||||
pin = formData.get('pin');
|
pin = formData.get('pin');
|
||||||
|
|
||||||
try {
|
const response = await fetch(`/api/users/${uname}/${pin}`);
|
||||||
const loginInfo = await loginFetch();
|
const loginInfo = await response.json();
|
||||||
|
|
||||||
if (loginInfo.status === 'ok') {
|
if (loginInfo.status === "ok") {
|
||||||
login()
|
login()
|
||||||
} else {
|
} else {
|
||||||
incorrectLogin()
|
incorrectLogin()
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'An Error has Occurred. Try again later. ' + e.toString();
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// LOGIN FETCH
|
|
||||||
|
|
||||||
async function loginFetch() {
|
|
||||||
let sendLoginInfo = { "name": uname, "pin": pin }
|
|
||||||
const res = await fetch('/api/login/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(sendLoginInfo),
|
|
||||||
});
|
|
||||||
return await res.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FUNCTIONS FOR WHETHER THE LOGIN WAS A SUCCESS OR FAILURE
|
// FUNCTIONS FOR WHETHER THE LOGIN WAS A SUCCESS OR FAILURE
|
||||||
|
|
||||||
function login() {
|
function login() {
|
||||||
document.querySelector("#errormessage").innerHTML = ''
|
console.log('You have logged in!')
|
||||||
localStorage.setItem('username', `${uname}`);
|
|
||||||
document.querySelector("#username").innerHTML = `Logged in as ${uname}`
|
document.querySelector("#username").innerHTML = `Logged in as ${uname}`
|
||||||
window.location.replace("/index.html")
|
document.querySelector("#errormessage").innerHTML = ''
|
||||||
|
localStorage.setItem("username", `${uname}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function incorrectLogin() {
|
function incorrectLogin() {
|
|
@ -7,8 +7,8 @@
|
||||||
<meta name="description" content="Chat Register">
|
<meta name="description" content="Chat Register">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<link rel="icon" href="../assets/favicon.svg">
|
<link rel="icon" href="/favicon.svg">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<h1>Register:</h1>
|
<h1>Register:</h1>
|
||||||
|
@ -24,12 +24,12 @@
|
||||||
|
|
||||||
<label for="selected">Pronouns:</label><br>
|
<label for="selected">Pronouns:</label><br>
|
||||||
<select id="selected" name="selected">
|
<select id="selected" name="selected">
|
||||||
<option value="none"></option>
|
<option value="nothing"></option>
|
||||||
<option value="she/her">she/her</option>
|
<option value="she.her">she/her</option>
|
||||||
<option value="he/him">he/him</option>
|
<option value="he.him">he/him</option>
|
||||||
<option value="they/them">they/them</option>
|
<option value="they.them">they/them</option>
|
||||||
<option value="it/its">it/its</option>
|
<option value="it.its">it/its</option>
|
||||||
<option value="fae/faer">fae/faer</option>
|
<option value="fae.faer">fae/faer</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<p>Or.</p>
|
<p>Or.</p>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
<div id="errormessage"></div>
|
<div id="errormessage"></div>
|
||||||
|
|
||||||
<script src="../js/register.js"></script>
|
<script src="register.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
//DECLARING VARIABLES AND GRABBING VALUES FROM FORM.
|
||||||
|
|
||||||
|
let uname = document.querySelector('#uname').value;
|
||||||
|
let pin = document.querySelector('#pin').value;
|
||||||
|
let selected = document.querySelector('#selected').value;
|
||||||
|
let custom = document.querySelector('#custom').value;
|
||||||
|
let pronouns = ''
|
||||||
|
let responseText;
|
||||||
|
const form = document.querySelector('form');
|
||||||
|
|
||||||
|
//SUBMIT FUNCTION &CHECKING IF USERNAME IS TAKEN
|
||||||
|
|
||||||
|
form.addEventListener("submit", async function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
const formData = new FormData(form);
|
||||||
|
|
||||||
|
uname = formData.get('uname');
|
||||||
|
pin = formData.get('pin');
|
||||||
|
selected = formData.get('selected');
|
||||||
|
custom = formData.get('custom')
|
||||||
|
|
||||||
|
if (custom !== '') {
|
||||||
|
pronouns = custom
|
||||||
|
} else {
|
||||||
|
pronouns = selected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const isNotTaken = await getUname();
|
||||||
|
|
||||||
|
if (isNotTaken.status === "fail") {
|
||||||
|
register()
|
||||||
|
} else {
|
||||||
|
document.querySelector("#errormessage").innerHTML = `${uname} is already taken.`
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
document.querySelector("#errormessage").innerHTML = 'An Error has Occurred. Try again later.'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//FETCH FUNCTIONS. GETTING USERNAME FROM API & REGISTERING USER ASSIGNED NAME AND PIN.
|
||||||
|
|
||||||
|
async function getUname() {
|
||||||
|
let response = await fetch(`/api/users/${uname}`);
|
||||||
|
responseJson = await response.json();
|
||||||
|
return responseJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function register() {
|
||||||
|
let sendRegisterInfo = { "name": uname, "pin": pin, "pronouns": pronouns }
|
||||||
|
fetch('/api/register/', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(sendRegisterInfo),
|
||||||
|
});
|
||||||
|
document.querySelector("#errormessage").innerHTML = 'Registered!'
|
||||||
|
window.location.replace("/login.html")
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
html {
|
||||||
|
background: #F7A8B8;
|
||||||
|
text-align: center;
|
||||||
|
font-family: "Lucida Console", "Courier New", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin-top: 3%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#streamchat {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#stream {
|
||||||
|
background-color: white;
|
||||||
|
padding: 5%;
|
||||||
|
box-shadow: 10px 10px 10px black;
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-right: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 4em;
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ form {
|
||||||
}
|
}
|
||||||
|
|
||||||
#box {
|
#box {
|
||||||
background-color: rgb(255, 199, 207);
|
background-color: white;
|
||||||
padding: 5%;
|
padding: 5%;
|
||||||
box-shadow: 10px 10px 10px black;
|
box-shadow: 10px 10px 10px black;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -25,10 +25,6 @@ form {
|
||||||
padding-top: 1%;
|
padding-top: 1%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#logoutlink {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-family: "Lucida Console", "Courier New", monospace;
|
font-family: "Lucida Console", "Courier New", monospace;
|
||||||
}
|
}
|
|
@ -7,8 +7,8 @@
|
||||||
<meta name="description" content="Chat Login Change">
|
<meta name="description" content="Chat Login Change">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<link rel="icon" href="../assets/favicon.svg">
|
<link rel="icon" href="/favicon.svg">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../js/updateinfo.js"></script>
|
<script src="updateinfo.js"></script>
|
||||||
|
|
||||||
<div id="errormessage"></div>
|
<div id="errormessage"></div>
|
||||||
</body>
|
</body>
|
|
@ -8,6 +8,7 @@ let newPin = document.querySelector('#newpin').value;
|
||||||
const form = document.querySelector('form');
|
const form = document.querySelector('form');
|
||||||
let selected = document.querySelector('#selected').value;
|
let selected = document.querySelector('#selected').value;
|
||||||
let custom = document.querySelector('#custom').value;
|
let custom = document.querySelector('#custom').value;
|
||||||
|
let responseText;
|
||||||
let updateEvent = ''
|
let updateEvent = ''
|
||||||
let newEvent = ''
|
let newEvent = ''
|
||||||
let newPronouns = ''
|
let newPronouns = ''
|
||||||
|
@ -26,8 +27,6 @@ form.addEventListener("submit", async function (event) {
|
||||||
selected = formData.get('selected');
|
selected = formData.get('selected');
|
||||||
custom = formData.get('custom')
|
custom = formData.get('custom')
|
||||||
|
|
||||||
|
|
||||||
//SETS NEWPRONOUNS DEPENDING ON WHAT THE USER SELECTED/TYPED
|
|
||||||
if (custom === '' && selected === 'none') {
|
if (custom === '' && selected === 'none') {
|
||||||
newPronouns = ''
|
newPronouns = ''
|
||||||
} else if (custom !== '') {
|
} else if (custom !== '') {
|
||||||
|
@ -36,116 +35,79 @@ form.addEventListener("submit", async function (event) {
|
||||||
newPronouns = selected
|
newPronouns = selected
|
||||||
}
|
}
|
||||||
|
|
||||||
unameCheck()
|
//CHECKS IF THE USER IS CHANGING MORE THAN ONE TEXT FIELD AT A TIME
|
||||||
|
let onlyChangeOne = document.querySelector("#errormessage").innerHTML = 'You can only change one at a time!'
|
||||||
//CHECKS IF THE USER IS CHANGING MORE THAN ONE TEXT FIELD AT A TIME
|
|
||||||
if (newUname !== '' && newPin !== '') {
|
if (newUname !== '' && newPin !== '') {
|
||||||
document.querySelector("#errormessage").innerHTML = 'You can only change one at a time!'
|
onlyChangeOne
|
||||||
return;
|
|
||||||
} else if (newUname !== '' && newPronouns !== '') {
|
} else if (newUname !== '' && newPronouns !== '') {
|
||||||
document.querySelector("#errormessage").innerHTML = 'You can only change one at a time!'
|
onlyChangeOne
|
||||||
return;
|
|
||||||
} else if (newPin !== '' && newPronouns !== '') {
|
} else if (newPin !== '' && newPronouns !== '') {
|
||||||
document.querySelector("#errormessage").innerHTML = 'You can only change one at a time!'
|
onlyChangeOne
|
||||||
return;
|
|
||||||
} else if (newUname !== '' && newPin !== '' && newPronouns !== '') {
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'You can only change one at a time!'
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
|
checkLoginInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ASSIGNS VARIABLES TO BE SENT TO API
|
// ASSIGNS VARIABLES TO BE SENT TO API
|
||||||
if (newUname === '' && newPin === '' && newPronouns !== '') {
|
if (newUname === '' && newPin === '' && newPronouns !== '') {
|
||||||
newEvent = newPronouns
|
newEvent = newPronouns
|
||||||
updateEvent = 'Pronouns'
|
updateEvent = 'pronouns'
|
||||||
} else if (newUname === '' && newPronouns === '' && newPin !== '') {
|
} else if (newUname === '' && newPronouns === '' && newPin !== '') {
|
||||||
newEvent = newPin
|
newEvent = newPin
|
||||||
updateEvent = 'Pin'
|
updateEvent = 'pin'
|
||||||
} else if (newPin === '' && newPronouns === '' && newUname !== '') {
|
} else if (newPin === '' && newPronouns === '' && newUname !== '') {
|
||||||
newEvent = newUname
|
newEvent = newUname
|
||||||
updateEvent = 'Name'
|
updateEvent = 'name'
|
||||||
} else if (newPin === '' && newUname === '' && newPronouns === '') {
|
} else if (newPin === '' && newUname === '' && newPronouns === '') {
|
||||||
document.querySelector("#errormessage").innerHTML = 'Please enter a new name, pin, or pronouns!'
|
document.querySelector("#errormessage").innerHTML = 'Please enter a new name, pin, or pronouns!'
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
|
checkLoginInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//CHECKS IF USERNAME IS TAKEN
|
||||||
|
const isTaken = await getUname();
|
||||||
|
|
||||||
//IF THE API SUCCESSFULLY UPDATES INFO FOR A USER THEN DO THIS
|
if (isTaken.status === 'ok') {
|
||||||
try {
|
document.querySelector("#errormessage").innerHTML = `username ${newUname} is already taken! `
|
||||||
const updateResponse = await loginStatus();
|
|
||||||
|
|
||||||
if (updateResponse == null) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updateResponse.status === 'ok') {
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'Login Changed!'
|
|
||||||
window.location.replace("../html/login.html")
|
|
||||||
} else {
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'Failed to update info. Try again later.'
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
document.querySelector("#errormessage").innerHTML = 'An Error has Occurred. Try again later. ' + e.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
//CHECKS IF A USERNAME IS TAKEN
|
|
||||||
async function unameCheck(){
|
|
||||||
if (newUname !== '') {
|
|
||||||
const response = await fetch(`api/users/${newUname}/`);
|
|
||||||
const isTaken = await response.json();
|
|
||||||
|
|
||||||
if (isTaken.status === "ok") {
|
// FETCH FUNTIONS. FETCHING USERNAME TO SEE IF ITS TAKEN.
|
||||||
document.querySelector('#errormessage').innerHTML = `${newUname} is already taken.`
|
|
||||||
return;
|
async function getUname() {
|
||||||
} else {
|
let response = await fetch(`/api/users/${newUname}`);
|
||||||
}
|
responseJson = await response.json();
|
||||||
}
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CHECKS IF THE LOGIN IS A SUCCESS
|
|
||||||
async function loginStatus() {
|
|
||||||
const loginInfo = await checkLoginInfo();
|
|
||||||
|
|
||||||
if (loginInfo.status === 'ok') {
|
//FETCH FUNCTION TO UPDATE USER INFO
|
||||||
return await updateInfo()
|
|
||||||
|
//TODO ADD CHECKING THE TOKEN with LOGIN IN IF STATEMENT
|
||||||
|
//CHECKING IF THE USER CAN LOGIN WITH GIVEN CURRENT USERNAME AND PIN
|
||||||
|
async function checkLoginInfo() {
|
||||||
|
const response = await fetch(`/api/users/${uname}/${pin}`);
|
||||||
|
const loginInfo = await response.json();
|
||||||
|
|
||||||
|
if (loginInfo.status === "ok") {
|
||||||
|
updateInfo()
|
||||||
} else {
|
} else {
|
||||||
incorrectLogin()
|
incorrectLogin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO ADD CHECKING THE TOKEN WITH LOGIN IN IF STATEMENT
|
|
||||||
//CHECKING IF THE USER CAN LOGIN WITH GIVEN CURRENT USERNAME AND PIN
|
|
||||||
// LOGIN FETCH
|
|
||||||
|
|
||||||
async function checkLoginInfo() {
|
|
||||||
let sendLoginInfo = { "name": uname, "pin": pin }
|
|
||||||
const res = await fetch('/api/login/', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify(sendLoginInfo),
|
|
||||||
});
|
|
||||||
return await res.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
//FETCH FUNCTION TO UPDATE USER INFO
|
|
||||||
|
|
||||||
async function updateInfo() {
|
async function updateInfo() {
|
||||||
let sendUpdateInfo = { "name": uname, "pin": pin, "changed_event": updateEvent, "new_event": newEvent }
|
let sendUpdateInfo = { "name": uname, "pin": pin, "changed_event": updateEvent, "new_event": newEvent }
|
||||||
const response = await fetch('/api/change', {
|
fetch('/api/users/change', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(sendUpdateInfo),
|
body: JSON.stringify(sendUpdateInfo),
|
||||||
});
|
});
|
||||||
return await response.json()
|
//document.querySelector("#errormessage").innerHTML = 'Login Changed!'
|
||||||
|
//window.location.replace("/login.html")
|
||||||
}
|
}
|
||||||
|
|
||||||
function incorrectLogin() {
|
function incorrectLogin() {
|
138
src/auth.rs
138
src/auth.rs
|
@ -1,5 +1,4 @@
|
||||||
extern crate log;
|
extern crate log;
|
||||||
use uuid::Uuid;
|
|
||||||
use crate::file_io::*;
|
use crate::file_io::*;
|
||||||
use rocket::http::{Cookie, Cookies};
|
use rocket::http::{Cookie, Cookies};
|
||||||
use crate::user::*;
|
use crate::user::*;
|
||||||
|
@ -20,18 +19,14 @@ pub fn register(data: Json<RegisterEvent>) -> JsonValue {
|
||||||
} else {
|
} else {
|
||||||
let pin_hashed = sha1::Sha1::from(&data.pin).digest().to_string(); // hash the pin
|
let pin_hashed = sha1::Sha1::from(&data.pin).digest().to_string(); // hash the pin
|
||||||
|
|
||||||
let mut new_user: User = User {
|
let new_user: User = User {
|
||||||
name: data.name.to_string().to_lowercase(),
|
name: data.name.to_string().to_lowercase(),
|
||||||
pin_hashed,
|
pin_hashed,
|
||||||
pronouns: data.pronouns.to_string().to_lowercase(),
|
pronouns: data.pronouns.to_string().to_lowercase(),
|
||||||
session_token: "NULL".to_string(),
|
session_token: "NULL".to_string(),
|
||||||
role: UserType::Normal,
|
role: UserType::Normal,
|
||||||
id: Uuid::new_v4(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if new_user.name == "admin".to_string() { // if name is admin, make them an admin
|
};
|
||||||
new_user.role = UserType::Admin;
|
|
||||||
}
|
|
||||||
db_add(&new_user);
|
db_add(&new_user);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
|
@ -277,7 +272,6 @@ pub fn get_user(name: String) -> JsonValue {
|
||||||
"name": user.name.to_lowercase(),
|
"name": user.name.to_lowercase(),
|
||||||
"pronouns": user.pronouns,
|
"pronouns": user.pronouns,
|
||||||
"role": user.role,
|
"role": user.role,
|
||||||
"id": user.id.to_string(),
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -287,117 +281,6 @@ pub fn get_user(name: String) -> JsonValue {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make a user into a moderator
|
|
||||||
fn premote(name: &str) -> JsonValue {
|
|
||||||
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
|
|
||||||
if user.role != UserType::Admin { // make sure mods can't demote admins ;3
|
|
||||||
user.role = UserType::Moderator;
|
|
||||||
db_remove(&user);
|
|
||||||
db_add(&user);
|
|
||||||
info!("succesfully premoted user {}", &user.name);
|
|
||||||
return json!({
|
|
||||||
"status": "ok",
|
|
||||||
"reason": "premoted user",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
warn!("user is an admin, cannot make moderator");
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user is admin",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("could not premote {}, user not found", &name);
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a user into a normal user
|
|
||||||
fn demote(name: &str) -> JsonValue {
|
|
||||||
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
|
|
||||||
if user.role != UserType::Admin { // make sure mods can't demote admins ;3
|
|
||||||
user.role = UserType::Normal;
|
|
||||||
db_remove(&user);
|
|
||||||
db_add(&user);
|
|
||||||
info!("succesfully demoted user {}", &user.name);
|
|
||||||
return json!({
|
|
||||||
"status": "ok",
|
|
||||||
"reason": "demoted user",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
warn!("user is an admin, cannot demote");
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user is admin",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("could not demote {}, user not found", &name);
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kick a user (temporarilly log them out for a certain amount of time)
|
|
||||||
fn kick(name: &str) -> JsonValue {
|
|
||||||
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
|
|
||||||
if user.role != UserType::Admin { // make sure mods can't kick admins
|
|
||||||
user.session_token = "NULL".to_string();
|
|
||||||
db_remove(&user);
|
|
||||||
db_add(&user);
|
|
||||||
info!("succesfully kicked user {}", &user.name);
|
|
||||||
return json!({
|
|
||||||
"status": "ok",
|
|
||||||
"reason": "kicked user",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
warn!("user is an admin, cannot kick");
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user is admin",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("could not kick {}, user not found", &name);
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ban a user (remove their account)
|
|
||||||
fn ban(name: &str) -> JsonValue {
|
|
||||||
if let Some(mut user) = db_read_user(&name.to_lowercase()).ok().flatten() {
|
|
||||||
if user.role != UserType::Admin { // make sure mods can't kick admins
|
|
||||||
db_remove(&user);
|
|
||||||
info!("succesfully banned user {}", &user.name);
|
|
||||||
return json!({
|
|
||||||
"status": "ok",
|
|
||||||
"reason": "banned user",
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
warn!("user is an admin, cannot ban");
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user is admin",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("could not ban {}, user not found", &name);
|
|
||||||
return json!({
|
|
||||||
"status": "fail",
|
|
||||||
"reason": "user not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* User Management */
|
/* User Management */
|
||||||
#[post("/mod", format = "json", data = "<data>")]
|
#[post("/mod", format = "json", data = "<data>")]
|
||||||
|
@ -420,15 +303,18 @@ pub fn moderation_actions(data: Json<ModerationAction>, mut cookies: Cookies) ->
|
||||||
"reason": "NULL token",
|
"reason": "NULL token",
|
||||||
});
|
});
|
||||||
} else if user.session_token == token.value() { // if token matches
|
} else if user.session_token == token.value() { // if token matches
|
||||||
if user.role == UserType::Moderator || user.role == UserType::Admin {
|
if user.role == UserType::Normal {
|
||||||
match data.action {
|
match data.action {
|
||||||
ModActions::Kick => kick(&data.target),
|
ModActions::Kick => {
|
||||||
ModActions::Ban => ban(&data.target),
|
info!("kicked user {}", data.target)
|
||||||
ModActions::Demote => demote(&data.target),
|
},
|
||||||
ModActions::Premote => premote(&data.target),
|
ModActions::Ban => info!("banned user {}", data.target),
|
||||||
_ => return json!({"status":"fail","reason":"bad command"}),
|
_ => info!("F"),
|
||||||
};
|
};
|
||||||
return json!({"status":"fail","reason":"idk"});
|
return json!({
|
||||||
|
"status": "ok",
|
||||||
|
"reason": "completed action",
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
warn!("user does not have sufficient permissions to perform that action!");
|
warn!("user does not have sufficient permissions to perform that action!");
|
||||||
return json!({
|
return json!({
|
||||||
|
|
|
@ -42,7 +42,6 @@ fn create_message(message: Json<MessageInput>, user: &User) -> JsonValue {
|
||||||
id: Uuid::new_v4(),
|
id: Uuid::new_v4(),
|
||||||
event_type,
|
event_type,
|
||||||
user: user.name.to_lowercase().to_owned(),
|
user: user.name.to_lowercase().to_owned(),
|
||||||
pronouns: user.pronouns.to_lowercase().to_owned(),
|
|
||||||
body: message.body.to_string(),
|
body: message.body.to_string(),
|
||||||
created_at: Utc::now(),
|
created_at: Utc::now(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
extern crate log;
|
extern crate log;
|
||||||
use crate::user::User;
|
use crate::user::User;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
type MyErrorType = Box<dyn std::error::Error>;
|
type MyErrorType = Box<dyn std::error::Error>;
|
||||||
|
static DB: Lazy<Mutex<sled::Db>> = Lazy::new(|| Mutex::new(sled::Db::open("users_db").unwrap()));
|
||||||
|
|
||||||
// add a user to the database
|
// add a user to the database
|
||||||
pub fn db_add(user: &User) {
|
pub fn db_add(user: &User) {
|
||||||
|
@ -13,7 +16,7 @@ pub fn db_add(user: &User) {
|
||||||
|
|
||||||
// write all changed users to database
|
// write all changed users to database
|
||||||
pub fn db_write(users_list: &Vec<User>) {
|
pub fn db_write(users_list: &Vec<User>) {
|
||||||
let db: sled::Db = sled::open("users_db").unwrap();
|
let db = DB.lock().unwrap();
|
||||||
for i in users_list {
|
for i in users_list {
|
||||||
let bytes = bincode::serialize(&i).unwrap();
|
let bytes = bincode::serialize(&i).unwrap();
|
||||||
db.insert(&i.name, bytes).unwrap();
|
db.insert(&i.name, bytes).unwrap();
|
||||||
|
@ -24,13 +27,13 @@ pub fn db_write(users_list: &Vec<User>) {
|
||||||
|
|
||||||
// remove a user from the database
|
// remove a user from the database
|
||||||
pub fn db_remove(user: &User) {
|
pub fn db_remove(user: &User) {
|
||||||
let db: sled::Db = sled::open("users_db").unwrap();
|
let db = DB.lock().unwrap();
|
||||||
db.remove(&user.name);
|
db.remove(&user.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read all users from the database
|
// read all users from the database
|
||||||
pub fn db_read() -> Vec<User> {
|
pub fn db_read() -> Vec<User> {
|
||||||
let db: sled::Db = sled::open("users_db").unwrap();
|
let db = DB.lock().unwrap();
|
||||||
let mut users: Vec<User> = Vec::new();
|
let mut users: Vec<User> = Vec::new();
|
||||||
for (_, bytes) in db.iter().filter_map(|r| r.ok()) {
|
for (_, bytes) in db.iter().filter_map(|r| r.ok()) {
|
||||||
let read_user: User = bincode::deserialize(&bytes).unwrap();
|
let read_user: User = bincode::deserialize(&bytes).unwrap();
|
||||||
|
@ -42,7 +45,7 @@ pub fn db_read() -> Vec<User> {
|
||||||
|
|
||||||
// read one user from the database
|
// read one user from the database
|
||||||
pub fn db_read_user(user: &str) -> std::result::Result<Option<User>, MyErrorType> {
|
pub fn db_read_user(user: &str) -> std::result::Result<Option<User>, MyErrorType> {
|
||||||
let db: sled::Db = sled::open("users_db")?;
|
let db = DB.lock().unwrap();
|
||||||
let entry = db.get(user)?;
|
let entry = db.get(user)?;
|
||||||
if let Some(user_entry) = entry {
|
if let Some(user_entry) = entry {
|
||||||
let read_user: User = bincode::deserialize(&user_entry)?;
|
let read_user: User = bincode::deserialize(&user_entry)?;
|
||||||
|
|
|
@ -21,7 +21,6 @@ pub struct Message {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub event_type: MessageType,
|
pub event_type: MessageType,
|
||||||
pub user: String,
|
pub user: String,
|
||||||
pub pronouns: String,
|
|
||||||
pub body: String,
|
pub body: String,
|
||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
/* User Data */
|
/* User Data */
|
||||||
// enum of different user types
|
// enum of different user types
|
||||||
|
@ -18,7 +17,6 @@ pub struct User {
|
||||||
pub pronouns: String, // user's pronouns
|
pub pronouns: String, // user's pronouns
|
||||||
pub session_token: String, // generated session token
|
pub session_token: String, // generated session token
|
||||||
pub role: UserType, // type/role of user
|
pub role: UserType, // type/role of user
|
||||||
pub id: Uuid,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Moderation Data */
|
/* Moderation Data */
|
||||||
|
|
Loading…
Reference in New Issue