diff --git a/.forgejo/workflows/build+release.yml b/.forgejo/workflows/build+release.yml
index dd35a7c..c473e32 100644
--- a/.forgejo/workflows/build+release.yml
+++ b/.forgejo/workflows/build+release.yml
@@ -7,12 +7,25 @@ on:
             - '[0-9]+.[0-9]+.[0-9]+'
             - '[0-9]+.[0-9]+.[0-9]+rc[0-9]+'
 jobs:
-    run-tests:
+    test:
         runs-on: docker
         steps:
+            -
+                name: Checking Out Repository Code
+                uses: https://code.forgejo.org/actions/checkout@v3
             -
                 name: Placeholder
                 run: echo Placeholder Job
+            -
+                name: Check if Version in Cargo.toml matches Tag
+                run: |
+                    VERSION=$(cat Cargo.toml | grep -E "(^|\|)version =" | cut -f2- -d= | tr -d \" | tr -d " ")
+                    if test $VERSION != "${{  github.ref_name }}"; then 
+                        echo "Expected Version is: '${{  github.ref_name }}' actual Version is: '$VERSION'"; 
+                        exit 1
+                    else 
+                        echo "Version is: '$VERSION'"; 
+                    fi
 
     build:
         needs: test
diff --git a/Cargo.lock b/Cargo.lock
index 53947cb..ca617a4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -397,7 +397,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "chellaris-rust-api"
-version = "1.0.3"
+version = "1.2.4"
 dependencies = [
  "actix-web",
  "chrono",
diff --git a/Cargo.toml b/Cargo.toml
index 7a9019a..f901372 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "chellaris-rust-api"
-version = "1.0.3"
+version = "1.2.4"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/src/main.rs b/src/main.rs
index f1df875..6a3a574 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,7 @@ use chrono::Local;
 use actix_web::{middleware::Logger, web, App, HttpServer};
 use serde::{Deserialize, Serialize};
 use sqlx::{PgPool, Pool, Postgres, Connection};
+use tokio::signal::unix::SignalKind;
 use utoipa::{OpenApi, openapi::security::{SecurityScheme, ApiKey, ApiKeyValue}, Modify};
 use utoipa_swagger_ui::{Config, SwaggerUi, Url};
 
@@ -220,9 +221,9 @@ async fn main() {
     struct ApiDocV1;
 
     let openapi_urls = vec![
-        Url::new("v1", concat!(api_base_1!(), "/openapi.json")),
-        Url::new("v2-L", concat!(api_base_2!(), "/openapi.json")),
-        Url::new("v3-L", concat!(api_base_3!(), "/openapi.json")),
+        Url::new("v1", concat!(api_base!(), "-docs/openapi1.json")),
+        Url::new("v2-L", concat!(api_base!(), "-docs/openapi2l.json")),
+        Url::new("v3-L", concat!(api_base!(), "-docs/openapi3l.json")),
     ];
 
     loop {
@@ -249,8 +250,13 @@ async fn main() {
 
         let watchdog_thread = tokio::spawn(async move { postgres_watchdog(pool_copy, shutdown_clone).await });
         tokio::spawn(async move {
-            actix_web::rt::signal::ctrl_c().await.unwrap();
-            println!("Ctrl-C received, killing Server");
+            actix_web::rt::signal::unix::signal(SignalKind::terminate()).unwrap().recv().await;
+            println!("SIGTERM received, killing Server");
+            abort()
+        });
+        tokio::spawn(async move {
+            actix_web::rt::signal::unix::signal(SignalKind::interrupt()).unwrap().recv().await;
+            println!("SIGINT received, killing Server");
             abort()
         });
 
@@ -293,15 +299,15 @@ async fn main() {
                     SwaggerUi::new(concat!(api_base!(), "/swagger/{_:.*}"))
                         .urls(vec![
                             (
-                                Url::new("v1", concat!(api_base_1!(), "/openapi.json")),
+                                Url::new("v1", concat!(api_base!(), "-docs/openapi1.json")),
                                 openapi_v1.clone(),
                             ),
                             (
-                                Url::new("v2-l", concat!(api_base_2!(), "/openapi.json")),
+                                Url::new("v2-l", concat!(api_base!(), "-docs/openapi2l.json")),
                                 openapi_v2_l.clone(),
                             ),
                             (
-                                Url::new("v3-l", concat!(api_base_3!(), "/openapi.json")),
+                                Url::new("v3-l", concat!(api_base!(), "-docs/openapi3l.json")),
                                 openapi_v3_l.clone(),
                             ),
                         ])
diff --git a/src/v1/mod.rs b/src/v1/mod.rs
index cddfbba..4c0fb1b 100644
--- a/src/v1/mod.rs
+++ b/src/v1/mod.rs
@@ -48,7 +48,7 @@ async fn verify_user_auth(data: &web::Data<AppState>, auth_token: &str, user_tok
 
 // User Endpoints
 #[utoipa::path(
-    request_body = schemas::GetUserParams,
+    request_body = GetUserParams,
     responses(
         (status = 200, description = "OK", body = User),
         (status = 403, description = "Unauthorized"),
@@ -58,8 +58,8 @@ async fn verify_user_auth(data: &web::Data<AppState>, auth_token: &str, user_tok
         ("api_key" = [])
     ),
 )]
-#[get("/api/v1/user")]
-async fn get_user(
+#[post("/api/v1/user")]
+pub(crate) async fn get_user(
     data: web::Data<AppState>,
     params: web::Json<schemas::GetUserParams>,
     req: HttpRequest,
@@ -116,7 +116,7 @@ async fn get_user(
         (status = 500, description = "Internal Server Error")
     ),
 )]
-#[post("/api/v1/user")]
+#[post("/api/v1/user/create")]
 pub(crate) async fn create_user(
     data: web::Data<AppState>,
 ) -> impl Responder {
@@ -195,9 +195,17 @@ pub(crate) async fn update_user(
         None => return HttpResponse::Unauthorized().finish(),
     };
 
+    let mut user_permissions: HashMap<String, bool> = HashMap::new();
+    match params.permissions {
+        Some(data) => {user_permissions = data.clone()},
+        None => {},
+    }
+
     let mut elevated_auth = false;
-    if params.permissions["game_permissions"] || params.permissions["empire_permissions"] || params.permissions["data_permissions"] || params.permissions["user_permissions"] {
-        elevated_auth = true;
+    if user_permissions.len() != 0 {
+        if user_permissions["game_permissions"] || user_permissions["empire_permissions"] || user_permissions["data_permissions"] || user_permissions["user_permissions"] {
+            elevated_auth = true;
+        }
     }
 
     let auth = verify_user_auth(&data, &auth_token, &params.user_token, schemas::TablePermission::User, elevated_auth).await;
@@ -225,41 +233,43 @@ pub(crate) async fn update_user(
             any_param_present = true;
         }
 
-        for (entry, value) in params.permissions.iter() {
-            match entry.deref() {
-                "game_permissions" => {
-                    user_query_separated.push( " game_permissions = ");
-                    match any_param_present {
-                        true => user_query_separated.push_bind(value),
-                        false => user_query_separated.push_bind_unseparated(value)
-                    };
-                    any_param_present = true;
-                },
-                "empire_permissions" => {
-                    user_query_separated.push( " empire_permissions = ");
-                    match any_param_present {
-                        true => user_query_separated.push_bind(value),
-                        false => user_query_separated.push_bind_unseparated(value)
-                    };
-                    any_param_present = true;
-                },
-                "data_permissions" => {
-                    user_query_separated.push( " data_permissions = ");
-                    match any_param_present {
-                        true => user_query_separated.push_bind(value),
-                        false => user_query_separated.push_bind_unseparated(value)
-                    };
-                    any_param_present = true;
-                },
-                "user_permissions" => {
-                    user_query_separated.push( " user_permissions = ");
-                    match any_param_present {
-                        true => user_query_separated.push_bind(value),
-                        false => user_query_separated.push_bind_unseparated(value)
-                    };
-                    any_param_present = true;
-                },
-                _ => {}
+        if user_permissions.len() != 0 {
+            for (entry, value) in user_permissions.iter() {
+                match entry.deref() {
+                    "game_permissions" => {
+                        user_query_separated.push( " game_permissions = ");
+                        match any_param_present {
+                            true => user_query_separated.push_bind(value),
+                            false => user_query_separated.push_bind_unseparated(value)
+                        };
+                        any_param_present = true;
+                    },
+                    "empire_permissions" => {
+                        user_query_separated.push( " empire_permissions = ");
+                        match any_param_present {
+                            true => user_query_separated.push_bind(value),
+                            false => user_query_separated.push_bind_unseparated(value)
+                        };
+                        any_param_present = true;
+                    },
+                    "data_permissions" => {
+                        user_query_separated.push( " data_permissions = ");
+                        match any_param_present {
+                            true => user_query_separated.push_bind(value),
+                            false => user_query_separated.push_bind_unseparated(value)
+                        };
+                        any_param_present = true;
+                    },
+                    "user_permissions" => {
+                        user_query_separated.push( " user_permissions = ");
+                        match any_param_present {
+                            true => user_query_separated.push_bind(value),
+                            false => user_query_separated.push_bind_unseparated(value)
+                        };
+                        any_param_present = true;
+                    },
+                    _ => {}
+                }
             }
         }
 
@@ -308,7 +318,7 @@ pub(crate) async fn update_user(
 }
 
 #[utoipa::path(
-    request_body = schemas::DeleteUserParams,
+    request_body = DeleteUserParams,
     responses(
         (status = 200, description = "OK"),
         (status = 403, description = "Unauthorized"),
diff --git a/src/v1/schemas.rs b/src/v1/schemas.rs
index d6d9d65..81c23c3 100644
--- a/src/v1/schemas.rs
+++ b/src/v1/schemas.rs
@@ -1,6 +1,6 @@
 use std::collections::HashMap;
 use serde::{Deserialize, Serialize};
-use utoipa::{ToSchema};
+use utoipa::{IntoParams, ToSchema};
 
 // DB Permission Enums
 
@@ -54,7 +54,7 @@ pub struct UpdateUserParams {
         [\"user_permissions\"]: false,
     }\
     ")]
-    pub permissions: HashMap<String, bool>,
+    pub permissions: Option<HashMap<String, bool>>,
 }
 
 #[derive(Serialize, Deserialize, ToSchema, Debug)]