From 462f1e1f6ce8e5f64c319777fbf8555a1ec14546 Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Mon, 4 Jan 2021 19:05:58 +0000 Subject: [PATCH] A bit of GDPR compliance stuff (#15237) * Moves TOS consent to /client instead of /mob * Only store cookies if the client allows it --- code/modules/client/client_defines.dm | 11 ++++++ code/modules/client/client_procs.dm | 40 ++++++++++++++++++++- code/modules/mob/new_player/new_player.dm | 43 ++++++----------------- goon/code/datums/browserOutput.dm | 4 ++- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 9a85ba171b2..11c8307cfe1 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -105,3 +105,14 @@ /// Last world/time that a PM was sent to the player by an admin var/received_discord_pm = -99999 // Yes this super low number is intentional + + /// Has the client accepted the TOS about data collection and other stuff + var/tos_consent = FALSE + +/client/vv_edit_var(var_name, var_value) + switch(var_name) + // I know we will never be in a world where admins are editing client vars to let people bypass TOS + // But guess what, if I have the ability to overengineer something, I am going to do it + if("tos_consent") + return FALSE + return ..() diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index e7fe0710a05..261f1986ff0 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -293,6 +293,9 @@ if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps) fps = prefs.clientfps + // Check if the client has or has not accepted TOS + check_tos_consent() + // This has to go here to avoid issues // If you sleep past this point, you will get SSinput errors as well as goonchat errors // DO NOT STUFF RANDOM SQL QUERIES BELOW THIS POINT WITHOUT USING `INVOKE_ASYNC()` OR SIMILAR @@ -1044,7 +1047,6 @@ * Arguments: * * notify - Do we notify admins of this new accounts date */ - /client/proc/get_byond_account_date(notify = FALSE) // First we see if the client has a saved date in the DB var/datum/db_query/query_date = SSdbcore.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey=:ckey", list( @@ -1101,6 +1103,42 @@ /client/proc/show_update_notice() to_chat(src, "Your BYOND client (v: [byond_version].[byond_build]) is out of date. This can cause glitches. We highly suggest you download the latest client from byond.com before playing. You can also update via the BYOND launcher application.") +/** + * Checks if the client has accepted TOS + * + * Runs some checks against vars and the DB to see if the client has accepted TOS. + * Returns TRUE or FALSE if they have or have not + */ +/client/proc/check_tos_consent() + // If there is no TOS, auto accept + if(!GLOB.join_tos) + tos_consent = TRUE + return TRUE + + // If theres no DB, assume yes + if(!SSdbcore.IsConnected()) + tos_consent = TRUE + return TRUE + + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("privacy")] WHERE ckey=:ckey AND consent=1", list( + "ckey" = ckey + )) + if(!query.warn_execute()) + qdel(query) + // If our query failed, just assume yes + tos_consent = TRUE + return TRUE + + // If we returned a row, they accepted + while(query.NextRow()) + qdel(query) + tos_consent = TRUE + return TRUE + + qdel(query) + // If we are here, they have not accepted, and need to read it + return FALSE + #undef LIMITER_SIZE #undef CURRENT_SECOND #undef SECOND_COUNT diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index e90b06614e1..09f794c8f98 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -3,7 +3,6 @@ var/spawning = 0 //Referenced when you want to delete the new_player later on in the code. var/totalPlayers = 0 //Player counts for the Lobby tab var/totalPlayersReady = 0 - var/tos_consent = FALSE universal_speak = 1 invisibility = 101 @@ -23,35 +22,11 @@ /mob/new_player/verb/new_player_panel() set src = usr - if(handle_tos_consent()) + if(client.tos_consent) new_player_panel_proc() + else + privacy_consent() -/mob/new_player/proc/handle_tos_consent() - if(!GLOB.join_tos) - tos_consent = TRUE - return TRUE - - if(!SSdbcore.IsConnected()) - tos_consent = TRUE - return TRUE - - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("privacy")] WHERE ckey=:ckey AND consent=1", list( - "ckey" = ckey - )) - if(!query.warn_execute()) - qdel(query) - // If our query failed, just assume yes - tos_consent = TRUE - return TRUE - - while(query.NextRow()) - qdel(query) - tos_consent = TRUE - return TRUE - - qdel(query) - privacy_consent() - return FALSE /mob/new_player/proc/privacy_consent() src << browse(null, "window=playersetup") @@ -147,10 +122,12 @@ query.warn_execute() qdel(query) src << browse(null, "window=privacy_consent") - tos_consent = 1 + client.tos_consent = TRUE + // Now they have accepted TOS, we can log data + client.chatOutput.sendClientData() new_player_panel_proc() if(href_list["consent_rejected"]) - tos_consent = 0 + client.tos_consent = FALSE to_chat(usr, "You must consent to the terms of service before you can join!") var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list( "ckey" = ckey @@ -164,7 +141,7 @@ return TRUE if(href_list["ready"]) - if(!tos_consent) + if(!client.tos_consent) to_chat(usr, "You must consent to the terms of service before you can join!") return FALSE if(client.version_blocked) @@ -182,7 +159,7 @@ new_player_panel_proc() if(href_list["observe"]) - if(!tos_consent) + if(!client.tos_consent) to_chat(usr, "You must consent to the terms of service before you can join!") return FALSE if(client.version_blocked) @@ -227,7 +204,7 @@ return FALSE if(href_list["late_join"]) - if(!tos_consent) + if(!client.tos_consent) to_chat(usr, "You must consent to the terms of service before you can join!") return FALSE if(client.version_blocked) diff --git a/goon/code/datums/browserOutput.dm b/goon/code/datums/browserOutput.dm index 314c101d797..b572b18256e 100644 --- a/goon/code/datums/browserOutput.dm +++ b/goon/code/datums/browserOutput.dm @@ -120,7 +120,9 @@ var/list/chatResources = list( to_chat(owner, message) messageQueue = null - src.sendClientData() + // We can only store a cookie on the client if they actually accept TOS because GDPR is GDPR + if(owner.tos_consent) + sendClientData() pingLoop()