From a763c8cb589dbeebfae174fe7c74498af6a2e626 Mon Sep 17 00:00:00 2001
From: Paul Makles <paulmakles@gmail.com>
Date: Sun, 16 Feb 2020 16:31:23 +0000
Subject: [PATCH] Misc changes.

---
 Cargo.lock            | 27 +++++++++++++++++++++++++
 Cargo.toml            |  1 +
 src/main.rs           | 10 +++++++++-
 src/routes/account.rs | 28 +++++++++++++++++++++++++-
 src/routes/channel.rs | 46 ++++++++++++++++++++++++++++++++-----------
 src/routes/mod.rs     |  2 +-
 src/routes/user.rs    | 29 ++++++++++++++++-----------
 src/websocket/mod.rs  |  9 ++++++++-
 8 files changed, 126 insertions(+), 26 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 4ebb944..74e7170 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1564,6 +1564,7 @@ dependencies = [
  "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket_cors 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1631,6 +1632,21 @@ dependencies = [
  "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rocket_cors"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase_serde 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rocket_http"
 version = "0.4.2"
@@ -2313,6 +2329,15 @@ dependencies = [
  "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "unicase_serde"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.3.4"
@@ -2819,6 +2844,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "42c1e9deb3ef4fa430d307bfccd4231434b707ca1328fae339c43ad1201cc6f7"
 "checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4"
 "checksum rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f"
+"checksum rocket_cors 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "270a960cba5a0b7928ad74268db7773ce932da6b550478383cefebe9f46c4e13"
 "checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817"
 "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@@ -2889,6 +2915,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ulid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "66239d1f7f19c9af37383f4a28e112727f1a77f6b13dca86faf75c40038e6dd3"
 "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
 "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
+"checksum unicase_serde 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef53697679d874d69f3160af80bc28de12730a985d57bdf2b47456ccb8b11f1"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
 "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
 "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
diff --git a/Cargo.toml b/Cargo.toml
index 0e77517..f9c50dd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -25,3 +25,4 @@ num_enum = "0.4.2"
 ws = "0.9.1"
 hashbrown = "0.7.0"
 serde_json = "1.0.47"
+rocket_cors = "0.5.1"
diff --git a/src/main.rs b/src/main.rs
index 3af5ff4..1a27d93 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,6 +10,7 @@ pub mod email;
 
 use dotenv;
 use std::thread;
+use rocket_cors::AllowedOrigins;
 
 fn main() {
 	dotenv::dotenv().ok();
@@ -19,5 +20,12 @@ fn main() {
 		websocket::launch_server();
 	});
 
-	routes::mount(rocket::ignite()).launch();
+    let cors = rocket_cors::CorsOptions {
+        allowed_origins: AllowedOrigins::All,
+        ..Default::default()
+    }.to_cors().unwrap();
+
+	routes::mount(rocket::ignite())
+		.attach(cors)
+		.launch();
 }
diff --git a/src/routes/account.rs b/src/routes/account.rs
index 7d94e59..41d4a1a 100644
--- a/src/routes/account.rs
+++ b/src/routes/account.rs
@@ -267,7 +267,8 @@ pub fn login(info: Json<Login>) -> JsonValue {
 
 						json!({
 							"success": true,
-							"access_token": token
+							"access_token": token,
+							"id": user.id
 						})
 					},
 					false => json!({
@@ -282,3 +283,28 @@ pub fn login(info: Json<Login>) -> JsonValue {
 			})
 		}
 }
+
+
+#[derive(Serialize, Deserialize)]
+pub struct Token {
+	token: String,
+}
+
+/// login to a Revolt account via token
+#[post("/token", data = "<info>")]
+pub fn token(info: Json<Token>) -> JsonValue {
+	let col = database::get_collection("users");
+
+	if let Some(u) =
+		col.find_one(doc! { "access_token": info.token.clone() }, None).expect("Failed user lookup") {
+			json!({
+				"success": true,
+				"id": u.get_str("_id").unwrap(),
+			})
+		} else {
+			json!({
+				"success": false,
+				"error": "Invalid token!",
+			})
+		}
+}
diff --git a/src/routes/channel.rs b/src/routes/channel.rs
index 7c0b5d9..134e82e 100644
--- a/src/routes/channel.rs
+++ b/src/routes/channel.rs
@@ -53,7 +53,8 @@ pub fn channel(user: User, target: Channel) -> Option<JsonValue> {
 	Some(
 		json!({
 			"id": target.id,
-			"type": target.channel_type
+			"type": target.channel_type,
+			"recipients": get_recipients(&target),
 		}
 	))
 }
@@ -158,10 +159,12 @@ pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) ->
 				get_recipients(&target),
 				json!({
 					"type": "message",
-					"id": id.clone(),
-					"channel": target.id,
-					"author": user.id,
-					"content": message.content.clone(),
+					"data": {
+						"id": id.clone(),
+						"channel": target.id,
+						"author": user.id,
+						"content": message.content.clone(),
+					},
 				}).to_string()
 			);
 
@@ -178,6 +181,23 @@ pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) ->
 		})
 }
 
+/// get a message
+#[get("/<target>/messages/<message>")]
+pub fn get_message(user: User, target: Channel, message: Message) -> Option<JsonValue> {
+	if !has_permission(&user, &target) {
+		return None
+	}
+
+	Some(
+		json!({
+			"id": message.id,
+			"author": message.author,
+			"content": message.content,
+			"edited": if let Some(t) = message.edited { Some(t.timestamp()) } else { None }
+		})
+	)
+}
+
 #[derive(Serialize, Deserialize)]
 pub struct EditMessage {
 	content: String,
@@ -215,10 +235,12 @@ pub fn edit_message(user: User, target: Channel, message: Message, edit: Json<Se
 						get_recipients(&target),
 						json!({
 							"type": "message_update",
-							"id": message.id,
-							"channel": target.id,
-							"content": message.content.clone(),
-							"edited": edited.timestamp()
+							"data": {
+								"id": message.id,
+								"channel": target.id,
+								"content": edit.content.clone(),
+								"edited": edited.timestamp()
+							},
 						}).to_string()
 					);
 
@@ -261,8 +283,10 @@ pub fn delete_message(user: User, target: Channel, message: Message) -> Option<J
 						get_recipients(&target),
 						json!({
 							"type": "message_delete",
-							"id": message.id,
-							"channel": target.id
+							"data": {
+								"id": message.id,
+								"channel": target.id
+							},
 						}).to_string()
 					);
 
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index ef4de33..d1ec62a 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -6,7 +6,7 @@ pub mod channel;
 
 pub fn mount(rocket: Rocket) -> Rocket {
 	rocket
-		.mount("/api/account", routes![ account::create, account::verify_email, account::resend_email, account::login ])
+		.mount("/api/account", routes![ account::create, account::verify_email, account::resend_email, account::login, account::token ])
 		.mount("/api/users", routes![ user::me, user::user, user::lookup, user::dms, user::dm, user::get_friends, user::get_friend, user::add_friend, user::remove_friend ])
 		.mount("/api/channels", routes![ channel::channel, channel::delete, channel::messages, channel::send_message, channel::edit_message, channel::delete_message ])
 }
diff --git a/src/routes/user.rs b/src/routes/user.rs
index a1b6259..43d8890 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -15,14 +15,17 @@ pub fn me(user: User) -> JsonValue {
 		"username": user.username,
 		"email": user.email,
 		"verified": user.email_verification.verified,
-		"created_timestamp": Ulid::from_string(&user.id).unwrap().datetime().timestamp(),
 	})
 }
 
 /// retrieve another user's information
-#[get("/<_target>")]
-pub fn user(_user: User, _target: User) -> JsonValue {
-	json!([])
+#[get("/<target>")]
+pub fn user(user: User, target: User) -> JsonValue {
+	json!({
+		"id": target.id,
+		"username": target.username,
+		"relationship": get_relationship(&user, &target) as u8
+	})
 }
 
 #[derive(Serialize, Deserialize)]
@@ -33,7 +36,7 @@ pub struct Query {
 /// lookup a user on Revolt
 /// currently only supports exact username searches
 #[post("/lookup", data = "<query>")]
-pub fn lookup(_user: User, query: Json<Query>) -> JsonValue {
+pub fn lookup(user: User, query: Json<Query>) -> JsonValue {
 	let col = database::get_collection("users");
 
 	let users = col.find(
@@ -42,12 +45,13 @@ pub fn lookup(_user: User, query: Json<Query>) -> JsonValue {
 	).expect("Failed user lookup");
 
 	let mut results = Vec::new();
-	for user in users {
-		let u: User = from_bson(bson::Bson::Document(user.unwrap())).expect("Failed to unwrap user.");
+	for item in users {
+		let u: User = from_bson(bson::Bson::Document(item.unwrap())).expect("Failed to unwrap user.");
 		results.push(
 			json!({
 				"id": u.id,
-				"username": u.username
+				"username": u.username,
+				"relationship": get_relationship(&user, &u) as u8
 			})
 		);
 	}
@@ -98,11 +102,12 @@ pub fn dm(user: User, target: User) -> JsonValue {
 	let col = database::get_collection("channels");
 
 	match col.find_one(
-		doc! { "type": channel::ChannelType::DM as i32, "recipients": [ user.id.clone(), target.id.clone() ] },
+		doc! { "type": channel::ChannelType::DM as i32, "recipients": { "$all": [ user.id.clone(), target.id.clone() ] } },
 		None
 	).expect("Failed channel lookup") {
 		Some(channel) =>
 			json!({
+				"success": true,
 				"id": channel.get_str("_id").unwrap()
 			}),
 		None => {
@@ -244,7 +249,8 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
 			).expect("Failed update query.");
 
 			json!({
-				"success": true
+				"success": true,
+				"status": Relationship::FRIEND as u8,
 			})
 		},
 		Relationship::BLOCKED =>
@@ -289,7 +295,8 @@ pub fn add_friend(user: User, target: User) -> JsonValue {
 			).expect("Failed update query.");
 
 			json!({
-				"success": true
+				"success": true,
+				"status": Relationship::OUTGOING as u8,
 			})
 		},
 		Relationship::SELF =>
diff --git a/src/websocket/mod.rs b/src/websocket/mod.rs
index 5204050..d0fbdf5 100644
--- a/src/websocket/mod.rs
+++ b/src/websocket/mod.rs
@@ -40,6 +40,8 @@ impl Handler for Server {
 						if let Some(_) = self.id {
 							self.out.send(
 								json!({
+									"type": "authenticate",
+									"success": false,
 									"error": "Already authenticated!"
 								})
 								.to_string()
@@ -71,6 +73,7 @@ impl Handler for Server {
 									self.id = Some(id.to_string());
 									self.out.send(
 										json!({
+											"type": "authenticate",
 											"success": true
 										})
 										.to_string()
@@ -79,6 +82,8 @@ impl Handler for Server {
 								None =>
 									self.out.send(
 										json!({
+											"type": "authenticate",
+											"success": false,
 											"error": "Invalid authentication token."
 										})
 										.to_string()
@@ -87,6 +92,8 @@ impl Handler for Server {
 						} else {
 							self.out.send(
 								json!({
+									"type": "authenticate",
+									"success": false,
 									"error": "Missing authentication token."
 								})
 								.to_string()
@@ -141,7 +148,7 @@ pub fn launch_server() {
 		}
 	}
 
-	listen("127.0.0.1:3012", |out| { Server { out: out, id: None, internal: Ulid::new().to_string() } }).unwrap()
+	listen("192.168.0.10:9999", |out| { Server { out: out, id: None, internal: Ulid::new().to_string() } }).unwrap()
 }
 
 pub fn send_message(id: String, message: String) -> std::result::Result<(), ()> {
-- 
GitLab