From 7f5246af5972e8df3cbecc541a4a9e8146956633 Mon Sep 17 00:00:00 2001
From: Torgrim <sir_alexiner@hotmail.com>
Date: Mon, 22 Apr 2024 13:15:05 +0200
Subject: [PATCH] Endpoints updated to log remote address of request. README.md
 updated with additional Roadmap feature.

---
 Go/internal/handlers/empty_handler.go         | 12 ++---
 .../dashboard/dashboards_id_handler.go        | 10 ++--
 .../dashboard/notifications_handler.go        | 14 +++---
 .../dashboard/notifications_id_handler.go     | 18 +++----
 .../dashboard/registrations_handler.go        | 16 +++----
 .../dashboard/registrations_id_handler.go     | 48 +++++++++----------
 .../endpoint/dashboard/status_handler.go      | 12 ++---
 .../handlers/endpoint/util/apikey_handler.go  | 14 +++---
 .../endpoint/util/user_delete_handler.go      | 12 ++---
 .../endpoint/util/user_register_handler.go    | 20 ++++----
 Go/internal/utils/constants/constants.go      | 10 ++--
 README.md                                     |  1 +
 12 files changed, 94 insertions(+), 93 deletions(-)

diff --git a/Go/internal/handlers/empty_handler.go b/Go/internal/handlers/empty_handler.go
index a6d4780..cdaa338 100644
--- a/Go/internal/handlers/empty_handler.go
+++ b/Go/internal/handlers/empty_handler.go
@@ -27,23 +27,23 @@ func EmptyHandler(w http.ResponseWriter, r *http.Request) {
 
 	file, err := os.Open(filePath) // Open the "root.html" file.
 	if err != nil {
-		log.Print("Error opening root file: ", err)        // Log error if file opening fails.
-		http.Error(w, ISE, http.StatusInternalServerError) // Return a 500 Internal Server Error if the file cannot be opened.
+		log.Printf("%s: Error opening root file: %v", r.RemoteAddr, err) // Log error if file opening fails.
+		http.Error(w, ISE, http.StatusInternalServerError)               // Return a 500 Internal Server Error if the file cannot be opened.
 		return
 	}
 	defer func(file *os.File) { // Ensure the file is closed after serving it.
 		err := file.Close()
 		if err != nil {
-			log.Print("Error closing root file: ", err)        // Log error if file closing fails.
-			http.Error(w, ISE, http.StatusInternalServerError) // Return a 500 Internal Server Error
+			log.Printf("%s: Error closing root file: %v", r.RemoteAddr, err) // Log error if file closing fails.
+			http.Error(w, ISE, http.StatusInternalServerError)               // Return a 500 Internal Server Error
 			// if the file cannot be closed.
 		}
 	}(file)
 
 	_, err = io.Copy(w, file) // Copy the file content to the response writer.
 	if err != nil {
-		log.Print("Error copying root file to ResponseWriter: ", err) // Log error if copying fails.
-		http.Error(w, ISE, http.StatusInternalServerError)            // Return a 500 Internal Server Error
+		log.Printf("%s: Error copying root file to ResponseWriter: %v", r.RemoteAddr, err) // Log error if copying fails.
+		http.Error(w, ISE, http.StatusInternalServerError)                                 // Return a 500 Internal Server Error
 		// if content cannot be copied.
 		return
 	}
diff --git a/Go/internal/handlers/endpoint/dashboard/dashboards_id_handler.go b/Go/internal/handlers/endpoint/dashboard/dashboards_id_handler.go
index db30e52..903c63e 100644
--- a/Go/internal/handlers/endpoint/dashboard/dashboards_id_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/dashboards_id_handler.go
@@ -27,7 +27,7 @@ func DashboardsIdHandler(w http.ResponseWriter, r *http.Request) {
 		handleDashboardGetRequest(w, r)
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.DashboardsID, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.DashboardsID, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint is:\n"+http.MethodGet, http.StatusNotImplemented)
 		return
 	}
@@ -39,26 +39,26 @@ func handleDashboardGetRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Retrieve token from URL query parameters.
 	if token == "" {            // Check if a token is provided.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.DashboardsID)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.DashboardsID)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with API token.
 	if UUID == "" {                 // Check if UUID is retrieved.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.DashboardsID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.DashboardsID)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	if ID == "" || ID == " " { // Check if the ID is valid.
-		log.Printf(constants.ClientConnectNoID, r.Method, Endpoints.DashboardsID)
+		log.Printf(constants.ClientConnectNoID, r.RemoteAddr, r.Method, Endpoints.DashboardsID)
 		http.Error(w, ProvideID, http.StatusBadRequest)
 		return
 	}
 
 	reg, err := db.GetSpecificRegistration(ID, UUID) // Retrieve registration by ID for user (UUID).
 	if err != nil {
-		log.Printf("Error getting registration: %v", err)
+		log.Printf("%s: Error getting registration: %v", r.RemoteAddr, err)
 		err := fmt.Sprintf("Dashboard doesn't exist: %v", err)
 		http.Error(w, err, http.StatusNotFound)
 		return
diff --git a/Go/internal/handlers/endpoint/dashboard/notifications_handler.go b/Go/internal/handlers/endpoint/dashboard/notifications_handler.go
index 28687ed..f5464e1 100644
--- a/Go/internal/handlers/endpoint/dashboard/notifications_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/notifications_handler.go
@@ -22,7 +22,7 @@ func NotificationsHandler(w http.ResponseWriter, r *http.Request) {
 		handleNotifGetAllRequest(w, r)
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.Notifications, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.Notifications, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint is:\n"+http.MethodPost+"\n"+http.MethodGet, http.StatusNotImplemented)
 		return
 	}
@@ -33,20 +33,20 @@ func handleNotifPostRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Retrieve token from the URL query parameters.
 	if token == "" {            // Check if a token is provided.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Notifications)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.Notifications)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with the API token.
 	if UUID == "" {                 // Check if UUID is valid.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Notifications)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.Notifications)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 
 	if r.Body == nil { // Check if request body is empty.
-		log.Printf(constants.ClientConnectEmptyBody, r.Method, Endpoints.Notifications)
+		log.Printf(constants.ClientConnectEmptyBody, r.RemoteAddr, r.Method, Endpoints.Notifications)
 		err := fmt.Sprintf("Please send a request body")
 		http.Error(w, err, http.StatusBadRequest)
 		return
@@ -100,20 +100,20 @@ func handleNotifGetAllRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Retrieve token from the URL query parameters.
 	if token == "" {            // Check if a token is provided.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Notifications)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.Notifications)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with the API token.
 	if UUID == "" {                 // Check if UUID is valid.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Notifications)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.Notifications)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	regs, err := db.GetWebhooksUser(UUID) // Retrieve all webhooks associated with the user (UUID).
 	if err != nil {
-		log.Printf("Error retrieving webhooks from database: %v", err)
+		log.Printf("%s: Error retrieving webhooks from database: %v", r.RemoteAddr, err)
 		errmsg := fmt.Sprint("Error retrieving webhooks from database: ", err)
 		http.Error(w, errmsg, http.StatusInternalServerError)
 		return
diff --git a/Go/internal/handlers/endpoint/dashboard/notifications_id_handler.go b/Go/internal/handlers/endpoint/dashboard/notifications_id_handler.go
index 22ad4d7..bff6ee5 100644
--- a/Go/internal/handlers/endpoint/dashboard/notifications_id_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/notifications_id_handler.go
@@ -20,7 +20,7 @@ func NotificationsIdHandler(w http.ResponseWriter, r *http.Request) {
 		handleNotifDeleteRequest(w, r)
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.NotificationsID, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.NotificationsID, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint are:\n"+http.MethodGet+"\n"+http.MethodDelete, http.StatusNotImplemented)
 		return
 	}
@@ -32,26 +32,26 @@ func handleNotifGetRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Retrieve token from the URL query parameters.
 	if token == "" {            // Check if a token is provided.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.NotificationsID)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.NotificationsID)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with the API token.
 	if UUID == "" {                 // Check if UUID is valid.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.NotificationsID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.NotificationsID)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	if ID == "" || ID == " " { // Check if the ID is valid.
-		log.Printf(constants.ClientConnectNoID, r.Method, Endpoints.NotificationsID)
+		log.Printf(constants.ClientConnectNoID, r.RemoteAddr, r.Method, Endpoints.NotificationsID)
 		http.Error(w, ProvideID, http.StatusBadRequest)
 		return
 	}
 
 	hook, err := db.GetSpecificWebhook(ID, UUID) // Retrieve the specific webhook by ID and UUID.
 	if err != nil {
-		log.Printf("Error getting webhook from database: %v", err)
+		log.Printf("%s: Error getting webhook from database: %v", r.RemoteAddr, err)
 		err := fmt.Sprintf("Error getting webhook from database: %v", err)
 		http.Error(w, err, http.StatusNotFound)
 		return
@@ -75,26 +75,26 @@ func handleNotifDeleteRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Retrieve token from the URL query parameters.
 	if token == "" {            // Check if a token is provided.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.NotificationsID)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.NotificationsID)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve UUID associated with the API token.
 	if UUID == "" {                 // Check if UUID is valid.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.NotificationsID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.NotificationsID)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	if ID == "" || ID == " " { // Check if the ID is valid.
-		log.Printf(constants.ClientConnectNoID, r.Method, Endpoints.NotificationsID)
+		log.Printf(constants.ClientConnectNoID, r.RemoteAddr, r.Method, Endpoints.NotificationsID)
 		http.Error(w, ProvideID, http.StatusBadRequest)
 		return
 	}
 
 	err := db.DeleteWebhook(ID, UUID) // Delete the specific webhook by ID and UUID from the database.
 	if err != nil {
-		log.Printf("Error deleting data from database: %v", err)
+		log.Printf(" %s: Error deleting data from database: %v", r.RemoteAddr, err)
 		err := fmt.Sprintf("Error deleting data from database: %v", err)
 		http.Error(w, err, http.StatusInternalServerError)
 		return
diff --git a/Go/internal/handlers/endpoint/dashboard/registrations_handler.go b/Go/internal/handlers/endpoint/dashboard/registrations_handler.go
index b382dc3..e5cab6a 100644
--- a/Go/internal/handlers/endpoint/dashboard/registrations_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/registrations_handler.go
@@ -32,7 +32,7 @@ func RegistrationsHandler(w http.ResponseWriter, r *http.Request) {
 		handleRegGetAllRequest(w, r) // Handle GET requests
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.Registrations, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.Registrations, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint is:\n"+http.MethodPost+"\n"+http.MethodGet+"\n"+http.MethodPatch, http.StatusNotImplemented)
 		return
 	}
@@ -58,20 +58,20 @@ func handleRegPostRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Extract the 'token' parameter from the query.
 	if token == "" {            // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Registrations)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.Registrations)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve the UUID for the API key.
 	if UUID == "" {                 // Validate UUID presence.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Registrations)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.Registrations)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 
 	if r.Body == nil { // Validate that the request body is not empty.
-		log.Printf(constants.ClientConnectEmptyBody, r.Method, Endpoints.Registrations)
+		log.Printf(constants.ClientConnectEmptyBody, r.RemoteAddr, r.Method, Endpoints.Registrations)
 		err := fmt.Sprintf("Please send a request body")
 		http.Error(w, err, http.StatusBadRequest)
 		return
@@ -79,7 +79,7 @@ func handleRegPostRequest(w http.ResponseWriter, r *http.Request) {
 
 	ci, err := DecodeCountryInfo(r.Body) // Decode request body into CountryInfoInternal struct.
 	if err != nil {
-		log.Printf("Error decoding request body: %v", err)
+		log.Printf("%s: Error decoding request body: %v", r.RemoteAddr, err)
 		err := fmt.Sprintf("Error decoding request body: %v", err)
 		http.Error(w, err, http.StatusBadRequest)
 		return
@@ -136,20 +136,20 @@ func handleRegGetAllRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Extract the 'token' parameter from the query.
 	if token == "" {            // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Registrations)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.Registrations)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Extract the UUID parameter from the API token.
 	if UUID == "" {                 // Validate UUID presence.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Registrations)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.Registrations)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	regs, err := db.GetRegistrations(UUID) // Retrieve the user's Registrations.
 	if err != nil {
-		log.Printf("Error retrieving documents from database: %s", err)
+		log.Printf("%s: Error retrieving documents from database: %s", r.RemoteAddr, err)
 		errmsg := fmt.Sprint("Error retrieving documents from database: ", err)
 		http.Error(w, errmsg, http.StatusInternalServerError)
 		return
diff --git a/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go b/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go
index 98ebc1b..2ae36ac 100644
--- a/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/registrations_id_handler.go
@@ -18,9 +18,9 @@ import (
 
 // Constants for error and informational messages.
 const (
-	ProvideID                 = "Please Provide ID"               // Message to request ID provision when missing.
-	RegistrationRetrivalError = "Error getting registration: %v"  // Error message template for retrieval issues.
-	RegistrationPatchError    = "Error patching registration: %v" // Error message template for patching issues.
+	ProvideID                 = "Please Provide ID"                   // Message to request ID provision when missing.
+	RegistrationRetrivalError = "%s: Error getting registration: %v"  // Error message template for retrieval issues.
+	RegistrationPatchError    = "%s: Error patching registration: %v" // Error message template for patching issues.
 )
 
 // RegistrationsIdHandler handles requests for the /registrations/{ID} endpoint.
@@ -34,7 +34,7 @@ func RegistrationsIdHandler(w http.ResponseWriter, r *http.Request) {
 		handleRegDeleteRequest(w, r)
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.RegistrationsID, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.RegistrationsID, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint is:\n"+http.MethodGet+"\n"+http.MethodPatch+"\n"+http.MethodDelete, http.StatusNotImplemented)
 		return
 	}
@@ -46,26 +46,26 @@ func handleRegGetRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Extract the 'token' parameter from the query.
 	if token == "" {            // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve the UUID for the API key.
 	if UUID == "" {                 // Validate UUID presence.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	if ID == "" || ID == " " { // Validate ID presence.
-		log.Printf(constants.ClientConnectNoID, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectNoID, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		http.Error(w, ProvideID, http.StatusBadRequest)
 		return
 	}
 
 	reg, err := db.GetSpecificRegistration(ID, UUID) // Retrieve registration data from the database.
 	if err != nil {
-		log.Printf(RegistrationRetrivalError, err)
+		log.Printf(RegistrationRetrivalError, r.RemoteAddr, err)
 		http.Error(w, "Error retrieving data from database", http.StatusNotFound)
 		return
 	}
@@ -97,25 +97,25 @@ func handleRegPatchRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Extract the 'token' parameter from the query.
 	if token == "" {            // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve the UUID for the API key.
 	if UUID == "" {                 // Validate UUID presence.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	if ID == "" || ID == " " { // Validate ID presence.
-		log.Printf(constants.ClientConnectNoID, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectNoID, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		http.Error(w, ProvideID, http.StatusBadRequest)
 		return
 	}
 
 	if r.Body == nil { // Validate that the request body is not empty.
-		log.Printf(constants.ClientConnectEmptyBody, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectEmptyBody, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		err := fmt.Sprintf("Please send a request body")
 		http.Error(w, err, http.StatusBadRequest)
 		return
@@ -123,23 +123,23 @@ func handleRegPatchRequest(w http.ResponseWriter, r *http.Request) {
 
 	ci, err, errcode := patchCountryInformation(r, ID, UUID) // Process the patch request.
 	if err != nil {
-		log.Printf(RegistrationPatchError, err)
-		err := fmt.Sprintf(RegistrationPatchError, err)
+		log.Printf(RegistrationPatchError, r.RemoteAddr, err)
+		err := fmt.Sprintf("Error patching registration: %v", err)
 		http.Error(w, err, errcode)
 		return
 	}
 
 	err = _func.ValidateCountryInfo(ci) // Validate the patched country information.
 	if err != nil {
-		log.Printf(RegistrationPatchError, err)
-		err := fmt.Sprintf(RegistrationPatchError, err)
+		log.Printf(RegistrationPatchError, r.RemoteAddr, err)
+		err := fmt.Sprintf("Error patching registration: %v", err)
 		http.Error(w, err, http.StatusBadRequest)
 		return
 	}
 
 	err = db.UpdateRegistration(ID, UUID, ci) // Update the registration in the database.
 	if err != nil {
-		log.Printf("Error saving patched data to database: %v", err)
+		log.Printf("%s: Error saving patched data to database: %v", r.RemoteAddr, err)
 		err := fmt.Sprintf("Error saving patched data to database: %v", err)
 		http.Error(w, err, http.StatusInternalServerError)
 		return
@@ -147,7 +147,7 @@ func handleRegPatchRequest(w http.ResponseWriter, r *http.Request) {
 
 	reg, err := db.GetSpecificRegistration(ID, UUID) // Retrieve the updated registration.
 	if err != nil {
-		log.Printf(RegistrationRetrivalError, err)
+		log.Printf(RegistrationRetrivalError, r.RemoteAddr, err)
 		err := fmt.Sprint("Error retrieving updated document: ", err)
 		http.Error(w, err, http.StatusNotFound)
 		return
@@ -181,7 +181,7 @@ func handleRegPatchRequest(w http.ResponseWriter, r *http.Request) {
 func patchCountryInformation(r *http.Request, ID, UUID string) (*structs.CountryInfoInternal, error, int) {
 	reg, err := db.GetSpecificRegistration(ID, UUID) // Retrieve the specific registration.
 	if err != nil {
-		log.Printf(RegistrationRetrivalError, err)
+		log.Printf(RegistrationRetrivalError, r.RemoteAddr, err)
 		return nil, err, http.StatusNotFound
 	}
 
@@ -271,26 +271,26 @@ func handleRegDeleteRequest(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()      // Extract the query parameters.
 	token := query.Get("token") // Extract the 'token' parameter from the query.
 	if token == "" {            // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		http.Error(w, ProvideAPI, http.StatusUnauthorized)
 		return
 	}
 	UUID := db.GetAPIKeyUUID(token) // Retrieve the UUID for the API key.
 	if UUID == "" {                 // Validate UUID presence.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		err := fmt.Sprintf(APINotAccepted)
 		http.Error(w, err, http.StatusNotAcceptable)
 		return
 	}
 	if ID == "" || ID == " " { // Validate ID presence.
-		log.Printf(constants.ClientConnectNoID, r.Method, Endpoints.RegistrationsID)
+		log.Printf(constants.ClientConnectNoID, r.RemoteAddr, r.Method, Endpoints.RegistrationsID)
 		http.Error(w, ProvideID, http.StatusBadRequest)
 		return
 	}
 
 	reg, err := db.GetSpecificRegistration(ID, UUID) // Retrieve the specific registration to be deleted.
 	if err != nil {
-		log.Printf(RegistrationRetrivalError, err)
+		log.Printf(RegistrationRetrivalError, r.RemoteAddr, err)
 		err := fmt.Sprint("Error getting registration: ", err)
 		http.Error(w, err, http.StatusNotFound)
 		return
@@ -298,7 +298,7 @@ func handleRegDeleteRequest(w http.ResponseWriter, r *http.Request) {
 
 	err = db.DeleteRegistration(ID, UUID) // Delete the registration from the database.
 	if err != nil {
-		log.Printf("Error deleting registration from database: %v", err)
+		log.Printf("%s: Error deleting registration from database: %v", r.RemoteAddr, err)
 		err := fmt.Sprintf("Error deleting registration from database: %v", err)
 		http.Error(w, err, http.StatusInternalServerError)
 		return
diff --git a/Go/internal/handlers/endpoint/dashboard/status_handler.go b/Go/internal/handlers/endpoint/dashboard/status_handler.go
index 11dc1a1..e51190b 100644
--- a/Go/internal/handlers/endpoint/dashboard/status_handler.go
+++ b/Go/internal/handlers/endpoint/dashboard/status_handler.go
@@ -18,7 +18,7 @@ import (
 func getEndpointStatus(endpointURL string) string {
 	r, err := http.NewRequest(http.MethodGet, endpointURL, nil) // Create a new GET request for the endpoint URL.
 	if err != nil {
-		log.Printf("error in creating request: %v", err)
+		log.Printf("%s: Error in creating request: %v", r.RemoteAddr, err)
 		return "Failed to create request"
 	}
 
@@ -29,7 +29,7 @@ func getEndpointStatus(endpointURL string) string {
 
 	res, err := client.Do(r) // Execute the request.
 	if err != nil {
-		log.Printf("error in receiving response: %v", err)
+		log.Printf("%s: Error in receiving response: %v", r.RemoteAddr, err)
 		return "Failed to connect"
 	}
 	// Ensure the response body is closed after the function exits, checking for errors.
@@ -49,7 +49,7 @@ func StatusHandler(w http.ResponseWriter, r *http.Request) {
 		handleStatusGetRequest(w, r) // Handle GET requests with handleStatusGetRequest.
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.Status, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.Status, r.Method)
 		http.Error(w, fmt.Sprintf("REST Method: %s not supported. Only GET is supported for this endpoint", r.Method), http.StatusNotImplemented)
 	}
 }
@@ -58,21 +58,21 @@ func StatusHandler(w http.ResponseWriter, r *http.Request) {
 func handleStatusGetRequest(w http.ResponseWriter, r *http.Request) {
 	token := r.URL.Query().Get("token") // Retrieve the API token from query parameters.
 	if token == "" {                    // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.Status)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.Status)
 		http.Error(w, "Please provide API Token", http.StatusUnauthorized)
 		return
 	}
 
 	UUID := db.GetAPIKeyUUID(token) // Retrieve the UUID associated with the API token.
 	if UUID == "" {                 // Validate UUID presence.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.Status)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.Status)
 		http.Error(w, "API key not accepted", http.StatusNotAcceptable)
 		return
 	}
 
 	webhooksUser, err := db.GetWebhooksUser(UUID) // Retrieve user data associated with webhooks.
 	if err != nil {
-		log.Printf("Error retrieving user's webhooks: %v", err)
+		log.Printf("%s: Error retrieving user's webhooks: %v", r.RemoteAddr, err)
 		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
 		return
 	}
diff --git a/Go/internal/handlers/endpoint/util/apikey_handler.go b/Go/internal/handlers/endpoint/util/apikey_handler.go
index 206c158..1b2ee78 100644
--- a/Go/internal/handlers/endpoint/util/apikey_handler.go
+++ b/Go/internal/handlers/endpoint/util/apikey_handler.go
@@ -23,7 +23,7 @@ func APIKeyHandler(w http.ResponseWriter, r *http.Request) {
 		handleApiKeyDeleteRequest(w, r)
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.ApiKey, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.ApiKey, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint are: GET, DELETE", http.StatusNotImplemented)
 		return
 	}
@@ -40,21 +40,21 @@ func handleApiKeyDeleteRequest(w http.ResponseWriter, r *http.Request) {
 
 	_, err := authenticate.Client.GetUser(ctx, UUID) // Verify the UUID with Firebase Authentication.
 	if err != nil {
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.ApiKey)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.ApiKey)
 		log.Printf("Error verifying UUID: %v\n", err)
 		http.Error(w, "Not Authorized", http.StatusUnauthorized) // Respond with unauthorized if UUID is invalid.
 		return
 	}
 
 	if token == "" || token == " " { // Validate token presence.
-		log.Printf(constants.ClientConnectNoToken, r.Method, Endpoints.ApiKey)
+		log.Printf(constants.ClientConnectNoToken, r.RemoteAddr, r.Method, Endpoints.ApiKey)
 		http.Error(w, "Please specify API Key to delete: '?token={API_Key}'", http.StatusBadRequest)
 		return
 	}
 
 	err = db.DeleteApiKey(UUID, token) // Attempt to delete the API key.
 	if err != nil {
-		log.Printf("Error deleting API Key: %v", err)
+		log.Printf("%s: Error deleting API Key: %v", r.RemoteAddr, err)
 		http.Error(w, err.Error(), http.StatusInternalServerError) // Respond with internal server error if deletion fails.
 		return
 	}
@@ -75,15 +75,15 @@ func handleApiKeyGetRequest(w http.ResponseWriter, r *http.Request) {
 
 	_, err := authenticate.Client.GetUser(ctx, UUID) // Verify the UUID with Firebase Authentication.
 	if err != nil {
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.ApiKey)
-		log.Printf("Error verifying UUID: %v\n", err)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.ApiKey)
+		log.Printf("%s: Error verifying UUID: %v\n", r.RemoteAddr, err)
 		http.Error(w, "Not Authorized", http.StatusUnauthorized) // Respond with unauthorized if UUID is invalid.
 		return
 	}
 
 	err = db.AddApiKey(UDID, UUID, key) // Attempt to add the new API key to the database.
 	if err != nil {
-		log.Printf("Error creating API Key: %v", err)
+		log.Printf("%s: Error creating API Key: %v", r.RemoteAddr, err)
 		errorMessage := fmt.Sprintf("Error creating API Key: %v", err)
 		http.Error(w, errorMessage, http.StatusInternalServerError) // Respond with internal server error if addition fails.
 		return
diff --git a/Go/internal/handlers/endpoint/util/user_delete_handler.go b/Go/internal/handlers/endpoint/util/user_delete_handler.go
index 3f94479..28f3ea0 100644
--- a/Go/internal/handlers/endpoint/util/user_delete_handler.go
+++ b/Go/internal/handlers/endpoint/util/user_delete_handler.go
@@ -17,7 +17,7 @@ func UserDeletionHandler(w http.ResponseWriter, r *http.Request) {
 		deleteUser(w, r) // Handle DELETE requests
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.UserDeletionID, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.UserDeletionID, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported method for this endpoint is:\n"+http.MethodDelete, http.StatusNotImplemented)
 		return
 	}
@@ -27,7 +27,7 @@ func UserDeletionHandler(w http.ResponseWriter, r *http.Request) {
 func deleteUser(w http.ResponseWriter, r *http.Request) {
 	ID := r.PathValue("ID")    // Extract user ID from the URL path.
 	if ID == "" || ID == " " { // Check if the user ID is provided.
-		log.Printf(constants.ClientConnectUnauthorized, r.Method, Endpoints.UserDeletionID)
+		log.Printf(constants.ClientConnectUnauthorized, r.RemoteAddr, r.Method, Endpoints.UserDeletionID)
 		http.Error(w, "Please provide User ID", http.StatusBadRequest) // Return an error if user ID is missing.
 		return
 	}
@@ -36,11 +36,11 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
 
 	err := authenticate.Client.DeleteUser(ctx, ID) // Attempt to delete user in Firebase.
 	if err != nil {
-		log.Printf("Error deleting user: %v\n", err)               // Log the error.
-		http.Error(w, err.Error(), http.StatusInternalServerError) // Report deletion error.
+		log.Printf("%s: Error deleting user: %v\n", r.RemoteAddr, err) // Log the error.
+		http.Error(w, err.Error(), http.StatusInternalServerError)     // Report deletion error.
 		return
 	}
 
-	w.WriteHeader(http.StatusNoContent)               // Set HTTP status to 204 No Content on successful deletion.
-	log.Printf("Successfully deleted user: %v\n", ID) // Log successful deletion.
+	w.WriteHeader(http.StatusNoContent)                                 // Set HTTP status to 204 No Content on successful deletion.
+	log.Printf("%s: Successfully deleted user: %v\n", r.RemoteAddr, ID) // Log successful deletion.
 }
diff --git a/Go/internal/handlers/endpoint/util/user_register_handler.go b/Go/internal/handlers/endpoint/util/user_register_handler.go
index f6939c4..5de96c6 100644
--- a/Go/internal/handlers/endpoint/util/user_register_handler.go
+++ b/Go/internal/handlers/endpoint/util/user_register_handler.go
@@ -26,7 +26,7 @@ func UserRegistrationHandler(w http.ResponseWriter, r *http.Request) {
 		registerUser(w, r) // Handle POST requests
 	default:
 		// Log and return an error for unsupported HTTP methods
-		log.Printf(constants.ClientConnectUnsupported, Endpoints.UserRegistration, r.Method)
+		log.Printf(constants.ClientConnectUnsupported, r.RemoteAddr, Endpoints.UserRegistration, r.Method)
 		http.Error(w, "REST Method: "+r.Method+" not supported. Only supported methods for this endpoint is:\n"+http.MethodPost, http.StatusNotImplemented)
 		return
 	}
@@ -40,14 +40,14 @@ func registerUser(w http.ResponseWriter, r *http.Request) {
 
 	if !isValidEmail(email) { // Validate the email.
 		// Log a message indicating that a client attempted to register using a malformed email.
-		log.Printf("Client attempted to register a user with malformed email.")
+		log.Printf("%s attempted to register a user with malformed email.", r.RemoteAddr)
 		http.Error(w, "Invalid email format", http.StatusBadRequest)
 		return
 	}
 
 	if !isValidPassword(password) { // Validate password strength.
 		// Log a message indicating that a client attempted to register using a weak password.
-		log.Printf("Client attempted to register a user with a weak password.")
+		log.Printf("%s attempted to register a user with a weak password.", r.RemoteAddr)
 		http.Error(w, "Password does not meet complexity requirements", http.StatusBadRequest)
 		return
 	}
@@ -62,8 +62,8 @@ func registerUser(w http.ResponseWriter, r *http.Request) {
 
 	u, err := authenticate.Client.CreateUser(ctx, params) // Attempt to create user in Firebase.
 	if err != nil {
-		log.Printf("Error creating user: %v\n", err)               // Log the error.
-		http.Error(w, err.Error(), http.StatusInternalServerError) // Report creation error.
+		log.Printf("%s: Error creating user: %v\n", r.RemoteAddr, err) // Log the error.
+		http.Error(w, err.Error(), http.StatusInternalServerError)     // Report creation error.
 		return
 	}
 
@@ -74,8 +74,8 @@ func registerUser(w http.ResponseWriter, r *http.Request) {
 
 	err = db.AddApiKey(UDID, u.UID, key) // Store the new API key in the database.
 	if err != nil {
-		log.Printf("Error saving API Key: %v\n", err)      // Log the error.
-		http.Error(w, ISE, http.StatusInternalServerError) // Report API key storage error.
+		log.Printf("%s Error saving API Key: %v\n", r.RemoteAddr, err) // Log the error.
+		http.Error(w, ISE, http.StatusInternalServerError)             // Report API key storage error.
 		return
 	}
 
@@ -93,13 +93,13 @@ func registerUser(w http.ResponseWriter, r *http.Request) {
 	encoder := json.NewEncoder(w)  // Initialize JSON encoder.
 	err = encoder.Encode(response) // Encode the response as JSON.
 	if err != nil {
-		log.Printf("Error encoding JSON response: %v\n", err) // Log encoding error.
-		http.Error(w, ISE, http.StatusInternalServerError)    // Report encoding error.
+		log.Printf("%s: Error encoding JSON response: %v\n", r.RemoteAddr, err) // Log encoding error.
+		http.Error(w, ISE, http.StatusInternalServerError)                      // Report encoding error.
 		return
 	}
 
 	// Log successful creation events.
-	log.Printf("Successfully created user: %v with API Key: %v\n", response.UserID, response.Token)
+	log.Printf("%s: Successfully created user: %v with API Key: %v\n", r.RemoteAddr, response.UserID, response.Token)
 }
 
 // isValidEmail checks if the provided email string matches the expected format.
diff --git a/Go/internal/utils/constants/constants.go b/Go/internal/utils/constants/constants.go
index ea1de77..3732e00 100644
--- a/Go/internal/utils/constants/constants.go
+++ b/Go/internal/utils/constants/constants.go
@@ -8,13 +8,13 @@ const (
 	IdLength     = 20   // IdLength specifies the length of general purpose identifiers.
 
 	// ClientConnectUnsupported formats an error message for when a client tries to connect using an unsupported method.
-	ClientConnectUnsupported = "Client attempted to connect to %s with unsupported method: %s\n"
+	ClientConnectUnsupported = "%s attempted to connect to %s with unsupported method: %s\n"
 	// ClientConnectNoToken formats an error message for connection attempts where no token is provided.
-	ClientConnectNoToken = "Failed %s attempt to %s: No Token.\n"
+	ClientConnectNoToken = "%s: Failed %s attempt to %s: No Token.\n"
 	// ClientConnectNoID formats an error message for connection attempts where no ID is provided.
-	ClientConnectNoID = "Failed %s attempt to %s: No ID.\n"
+	ClientConnectNoID = "%s: Failed %s attempt to %s: No ID.\n"
 	// ClientConnectUnauthorized formats an error message for unauthorized connection attempts.
-	ClientConnectUnauthorized = "Unauthorized %s attempted to %s.\n"
+	ClientConnectUnauthorized = "%s: Unauthorized %s attempted to %s.\n"
 	// ClientConnectEmptyBody formats an error message for connection attempts with no body content.
-	ClientConnectEmptyBody = "Failed %s attempt to %s: No Body.\n"
+	ClientConnectEmptyBody = "%s: Failed %s attempt to %s: No Body.\n"
 )
diff --git a/README.md b/README.md
index 579238b..a980059 100644
--- a/README.md
+++ b/README.md
@@ -732,6 +732,7 @@ cd globeboard/Go/
 - Implement more secure registration for users to the application.
   - Actual authentication of users before registration.
   - Implement check if user has authenticated before registration.
+- Allow user groups to share API token.
       
 ## Contributing
 
-- 
GitLab