diff --git a/Cargo.lock b/Cargo.lock
index 7e2e1c2eb9c2cd41bdf84fc1baeac8b82c8f3c69..726f8a1c11f204f6cde1a5418c7d7d92075e7eab 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2309,7 +2309,7 @@ dependencies = [
 [[package]]
 name = "rauth"
 version = "0.2.2"
-source = "git+https://gitlab.insrt.uk/insert/rauth?rev=1e5f671144772a28f3faac55dd98647235736923#1e5f671144772a28f3faac55dd98647235736923"
+source = "git+https://gitlab.insrt.uk/insert/rauth?rev=73fd602f0aba3d3689307fb1f811f211422fb4d3#73fd602f0aba3d3689307fb1f811f211422fb4d3"
 dependencies = [
  "chrono",
  "handlebars",
@@ -2453,7 +2453,7 @@ dependencies = [
 
 [[package]]
 name = "revolt"
-version = "0.3.3-alpha.2"
+version = "0.3.3-alpha.1"
 dependencies = [
  "async-std",
  "async-tungstenite",
diff --git a/Cargo.toml b/Cargo.toml
index 3b7f57b9563f8a698578b5eaebef7abbabbc907c..be0b430e6ebb0e64c350117e2608b46b499760a1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "revolt"
-version = "0.3.3-alpha.2"
+version = "0.3.3-alpha.1"
 authors = ["Paul Makles <paulmakles@gmail.com>"]
 edition = "2018"
 
@@ -13,7 +13,7 @@ many-to-many = "0.1.2"
 ctrlc = { version = "3.0", features = ["termination"] }
 async-std = { version = "1.8.0", features = ["tokio02", "attributes"] }
 async-tungstenite = { version = "0.10.0", features = ["async-std-runtime"] }
-rauth = { git = "https://gitlab.insrt.uk/insert/rauth", rev = "1e5f671144772a28f3faac55dd98647235736923" }
+rauth = { git = "https://gitlab.insrt.uk/insert/rauth", rev = "73fd602f0aba3d3689307fb1f811f211422fb4d3" }
 
 hive_pubsub = { version = "0.4.3", features = ["mongo"] }
 rocket_cors = { git = "https://github.com/insertish/rocket_cors", branch = "master" }
diff --git a/Dockerfile b/Dockerfile
index 16c5c47ea3ef0998ea008a5f10744b219e596430..56763d7de512acd1adc2181747208ee04155a45c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,6 +5,7 @@ WORKDIR /home/rust/src
 RUN USER=root cargo new --bin revolt
 WORKDIR /home/rust/src/revolt
 COPY Cargo.toml Cargo.lock ./
+COPY assets/templates ./assets/templates
 COPY src ./src
 RUN cargo build --release
 
diff --git a/src/main.rs b/src/main.rs
index aa0bc4d49f693f93168a2ae81a27d23c6af7949f..019ca0a68f7e3dfaca44cd726630364db0e7fc95 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -26,7 +26,7 @@ use rauth::options::{EmailVerification, Options, SMTP};
 use rocket_cors::AllowedOrigins;
 use rocket_prometheus::PrometheusMetrics;
 use util::variables::{
-    PUBLIC_URL, SMTP_FROM, SMTP_HOST, SMTP_PASSWORD, SMTP_USERNAME, USE_EMAIL, USE_PROMETHEUS, APP_URL
+    PUBLIC_URL, SMTP_FROM, SMTP_HOST, SMTP_PASSWORD, SMTP_USERNAME, USE_EMAIL, USE_PROMETHEUS, APP_URL, INVITE_ONLY
 };
 
 #[async_std::main]
@@ -63,7 +63,12 @@ async fn launch_web() {
 
     let auth = Auth::new(
         database::get_collection("accounts"),
-        Options::new()
+        if *INVITE_ONLY {
+            Options::new()
+                .invite_only_collection(database::get_collection("invites"))
+        } else {
+            Options::new()
+        }
             .base_url(format!("{}/auth", *PUBLIC_URL))
             .email_verification(if *USE_EMAIL {
                 EmailVerification::Enabled {
diff --git a/src/routes/root.rs b/src/routes/root.rs
index a247f8abcfca4c5dc4581835199cec59bc232e9f..8cf197d31e7214644150f198ff61dac65af5bafc 100644
--- a/src/routes/root.rs
+++ b/src/routes/root.rs
@@ -1,5 +1,5 @@
 use crate::util::variables::{
-    DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, USE_EMAIL, USE_HCAPTCHA,
+    DISABLE_REGISTRATION, EXTERNAL_WS_URL, HCAPTCHA_SITEKEY, USE_EMAIL, USE_HCAPTCHA, INVITE_ONLY
 };
 
 use mongodb::bson::doc;
@@ -8,7 +8,7 @@ use rocket_contrib::json::JsonValue;
 #[get("/")]
 pub async fn root() -> JsonValue {
     json!({
-        "revolt": "0.3.3-alpha.2",
+        "revolt": "0.3.3-alpha.1",
         "features": {
             "registration": !*DISABLE_REGISTRATION,
             "captcha": {
@@ -16,6 +16,7 @@ pub async fn root() -> JsonValue {
                 "key": HCAPTCHA_SITEKEY.to_string()
             },
             "email": *USE_EMAIL,
+            "invite_only": *INVITE_ONLY
         },
         "ws": *EXTERNAL_WS_URL,
     })
diff --git a/src/util/mod.rs b/src/util/mod.rs
index a22135dc198ddff54b3814e012eb1679de0fd5e9..7743f0ec127dd8b19d6e6ef95f4fc0ce4420d49f 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -1,17 +1,2 @@
-use rand::{distributions::Alphanumeric, Rng};
-use std::collections::HashSet;
-use std::iter::FromIterator;
-
 pub mod result;
 pub mod variables;
-
-pub fn vec_to_set<T: Clone + Eq + std::hash::Hash>(data: &[T]) -> HashSet<T> {
-    HashSet::from_iter(data.iter().cloned())
-}
-
-pub fn gen_token(l: usize) -> String {
-    rand::thread_rng()
-        .sample_iter(&Alphanumeric)
-        .take(l)
-        .collect::<String>()
-}
diff --git a/src/util/variables.rs b/src/util/variables.rs
index 37acdce1aab5536888f0c749ab2291d827cc8f21..00f3d020d30fabdf7ca46c2d65518c53395aa407 100644
--- a/src/util/variables.rs
+++ b/src/util/variables.rs
@@ -22,6 +22,7 @@ lazy_static! {
 
     // Application Flags
     pub static ref DISABLE_REGISTRATION: bool = env::var("REVOLT_DISABLE_REGISTRATION").map_or(false, |v| v == "1");
+    pub static ref INVITE_ONLY: bool = env::var("REVOLT_INVITE_ONLY").map_or(false, |v| v == "1");
     pub static ref USE_EMAIL: bool = env::var("REVOLT_USE_EMAIL_VERIFICATION").map_or(
         env::var("REVOLT_SMTP_HOST").is_ok()
             && env::var("REVOLT_SMTP_USERNAME").is_ok()