Add legal consent and reliable external redirects
This commit is contained in:
@@ -27,6 +27,7 @@ var registration_username_input: LineEdit
|
||||
var registration_email_input: LineEdit
|
||||
var registration_password_input: LineEdit
|
||||
var registration_confirm_input: LineEdit
|
||||
var registration_legal_check: CheckBox
|
||||
var reset_login_input: LineEdit
|
||||
var reset_code_input: LineEdit
|
||||
var reset_password_input: LineEdit
|
||||
@@ -36,6 +37,8 @@ var steam_action: OptionButton
|
||||
var steam_username_input: LineEdit
|
||||
var steam_email_input: LineEdit
|
||||
var steam_password_input: LineEdit
|
||||
var steam_legal_check: CheckBox
|
||||
var panel_gutter: MarginContainer
|
||||
var submit_buttons: Array[Button] = []
|
||||
var fields: Array[LineEdit] = []
|
||||
var requests: Dictionary = {}
|
||||
@@ -182,10 +185,14 @@ func _build_ui() -> void:
|
||||
var scroll := ScrollContainer.new()
|
||||
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
auth_panel.add_child(scroll)
|
||||
panel_gutter = MarginContainer.new()
|
||||
panel_gutter.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
panel_gutter.add_theme_constant_override("margin_right", 28)
|
||||
scroll.add_child(panel_gutter)
|
||||
panel_content = VBoxContainer.new()
|
||||
panel_content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
panel_content.add_theme_constant_override("separation", 24)
|
||||
scroll.add_child(panel_content)
|
||||
panel_gutter.add_child(panel_content)
|
||||
|
||||
var panel_header := HBoxContainer.new()
|
||||
panel_header.add_theme_constant_override("separation", 18)
|
||||
@@ -221,6 +228,11 @@ func _build_ui() -> void:
|
||||
message_label.add_theme_font_size_override("font_size", 14)
|
||||
message_label.add_theme_font_override("font", Brand.font)
|
||||
panel_content.add_child(message_label)
|
||||
var legal_footer := HBoxContainer.new()
|
||||
legal_footer.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
legal_footer.add_theme_constant_override("separation", 12)
|
||||
panel_content.add_child(legal_footer)
|
||||
_add_legal_links(legal_footer)
|
||||
|
||||
|
||||
func _build_login_view() -> VBoxContainer:
|
||||
@@ -259,6 +271,7 @@ func _build_register_view() -> VBoxContainer:
|
||||
registration_password_input = _add_field(view, "Password", "At least 8 characters", true)
|
||||
registration_confirm_input = _add_field(view, "Confirm password", "Re-enter your password", true)
|
||||
_add_show_password(view, [registration_password_input, registration_confirm_input])
|
||||
registration_legal_check = _add_legal_consent(view)
|
||||
_add_primary_button(view, "Create Account", _on_register_pressed)
|
||||
_add_back_button(view, "Already have an account? Sign in", "login")
|
||||
registration_confirm_input.text_submitted.connect(func(_text: String): _on_register_pressed())
|
||||
@@ -297,11 +310,37 @@ func _build_steam_view() -> VBoxContainer:
|
||||
steam_email_input = _add_field(view, "Email", "[email protected]")
|
||||
steam_password_input = _add_field(view, "Password", "At least 8 characters", true)
|
||||
_add_show_password(view, [steam_password_input])
|
||||
steam_legal_check = _add_legal_consent(view)
|
||||
_add_primary_button(view, "Continue", _complete_steam)
|
||||
_add_back_button(view, "Cancel Steam sign in", "login")
|
||||
return view
|
||||
|
||||
|
||||
func _add_legal_consent(parent: VBoxContainer) -> CheckBox:
|
||||
var check := CheckBox.new()
|
||||
check.text = "I agree to the Terms of Service and acknowledge the Privacy Policy."
|
||||
check.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
parent.add_child(check)
|
||||
var links := HBoxContainer.new()
|
||||
links.add_theme_constant_override("separation", 12)
|
||||
parent.add_child(links)
|
||||
_add_legal_links(links)
|
||||
return check
|
||||
|
||||
|
||||
func _add_legal_links(parent: HBoxContainer) -> void:
|
||||
for spec in [["Terms of Service", "terms"], ["Privacy Policy", "privacy"]]:
|
||||
var link := Button.new()
|
||||
link.text = spec[0]
|
||||
link.flat = true
|
||||
link.pressed.connect(_open_legal_document.bind(str(spec[1])))
|
||||
parent.add_child(link)
|
||||
|
||||
|
||||
func _open_legal_document(kind: String) -> void:
|
||||
main.open_legal_document(kind)
|
||||
|
||||
|
||||
func _new_form() -> VBoxContainer:
|
||||
var form := VBoxContainer.new()
|
||||
form.add_theme_constant_override("separation", 16)
|
||||
@@ -446,12 +485,14 @@ func _update_responsive_layout() -> void:
|
||||
theme_button.position = Vector2(-190, 20)
|
||||
theme_button.add_theme_font_size_override("font_size", 64)
|
||||
auth_panel.custom_minimum_size = Vector2(1700, 2300)
|
||||
panel_gutter.add_theme_constant_override("margin_right", 96)
|
||||
_apply_compact_scale(panel_content, 3.8)
|
||||
else:
|
||||
theme_button.custom_minimum_size = Vector2(44, 44)
|
||||
theme_button.position = Vector2(-58, 14)
|
||||
theme_button.add_theme_font_size_override("font_size", 20)
|
||||
auth_panel.custom_minimum_size = Vector2(640, 790) if compact_desktop else Vector2(710, 820)
|
||||
panel_gutter.add_theme_constant_override("margin_right", 28)
|
||||
_apply_compact_scale(panel_content, 1.0)
|
||||
_apply_theme()
|
||||
layout_updating = false
|
||||
@@ -559,8 +600,10 @@ func _on_register_pressed() -> void:
|
||||
var password := registration_password_input.text
|
||||
var error := _validate_account(username, email, password, registration_confirm_input.text)
|
||||
if not error.is_empty(): return _show_error(error)
|
||||
if not registration_legal_check.button_pressed:
|
||||
return _show_error("Agree to the Terms of Service and acknowledge the Privacy Policy to create an account.")
|
||||
login_attempt_username = username
|
||||
_send_json("register", "/register", {"username": username, "email": email, "password": password}, "Creating account...")
|
||||
_send_json("register", "/register", {"username": username, "email": email, "password": password, "acceptLegal": true}, "Creating account...")
|
||||
|
||||
|
||||
func _on_register_completed(result: int, code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
@@ -608,7 +651,7 @@ func _on_reset_confirmed(result: int, code: int, _headers: PackedStringArray, bo
|
||||
func _start_steam() -> void:
|
||||
if OS.has_feature("web"):
|
||||
var popup_result: Variant = JavaScriptBridge.eval(
|
||||
"window.localStorage.removeItem('%s'); window.ranazeSteamWindow = window.open('about:blank', 'ranaze_steam'); if (window.ranazeSteamWindow) { var ranazeSteamWaitingWindow = window.ranazeSteamWindow; ranazeSteamWaitingWindow.document.title = 'RanaZe Steam sign in'; ranazeSteamWaitingWindow.document.body.innerHTML = '<main id=\"ranaze-steam-login\" style=\"font:16px system-ui;padding:48px;color:#172033\"><strong>Opening Steam sign in...</strong><p>This window will continue to Steam.</p></main>'; ranazeSteamWaitingWindow.setInterval(function () { var steamAuthUrl = ranazeSteamWaitingWindow.localStorage.getItem('%s'); if (steamAuthUrl) { var steamLogin = ranazeSteamWaitingWindow.document.getElementById('ranaze-steam-login'); steamLogin.innerHTML = '<strong>Steam sign in is ready.</strong><p><a id=\"ranaze-steam-link\" style=\"color:#2563eb;font-weight:600\">Continue to Steam</a></p>'; ranazeSteamWaitingWindow.document.getElementById('ranaze-steam-link').href = steamAuthUrl; ranazeSteamWaitingWindow.localStorage.removeItem('%s'); ranazeSteamWaitingWindow.location.replace(steamAuthUrl); } }, 150); } window.ranazeSteamWindow !== null;" % [STEAM_AUTH_STORAGE_KEY, STEAM_AUTH_STORAGE_KEY, STEAM_AUTH_STORAGE_KEY],
|
||||
"window.localStorage.removeItem('%s'); var ranazeSteamBridge = new URL('/external-redirect.html?key=%s&provider=Steam', window.location.origin).href; window.ranazeSteamWindow = window.open(ranazeSteamBridge, 'ranaze_steam'); window.ranazeSteamWindow !== null;" % [STEAM_AUTH_STORAGE_KEY, STEAM_AUTH_STORAGE_KEY],
|
||||
true
|
||||
)
|
||||
steam_popup_opened = bool(popup_result)
|
||||
@@ -630,7 +673,7 @@ func _on_steam_started(result: int, code: int, _headers: PackedStringArray, body
|
||||
return _show_error("Steam returned an invalid sign-in response.")
|
||||
if OS.has_feature("web"):
|
||||
JavaScriptBridge.eval(
|
||||
"var ranazeSteamAuthUrl = %s; window.localStorage.setItem('%s', ranazeSteamAuthUrl); if (window.ranazeSteamWindow && !window.ranazeSteamWindow.closed) { window.ranazeSteamWindow.focus(); } else { var ranazeSteamPopup = window.open(ranazeSteamAuthUrl, 'ranaze_steam'); if (ranazeSteamPopup) { window.ranazeSteamWindow = ranazeSteamPopup; ranazeSteamPopup.focus(); } else { window.location.assign(ranazeSteamAuthUrl); } }" % [JSON.stringify(auth_url), STEAM_AUTH_STORAGE_KEY],
|
||||
"var ranazeSteamAuthUrl = %s; window.localStorage.setItem('%s', ranazeSteamAuthUrl); if (window.ranazeSteamWindow && !window.ranazeSteamWindow.closed) { try { window.ranazeSteamWindow.location.replace(ranazeSteamAuthUrl); } catch (_) {} window.ranazeSteamWindow.focus(); } else { var ranazeSteamPopup = window.open(ranazeSteamAuthUrl, 'ranaze_steam'); if (ranazeSteamPopup) { window.ranazeSteamWindow = ranazeSteamPopup; ranazeSteamPopup.focus(); } else { window.location.assign(ranazeSteamAuthUrl); } }" % [JSON.stringify(auth_url), STEAM_AUTH_STORAGE_KEY],
|
||||
true
|
||||
)
|
||||
else:
|
||||
@@ -674,6 +717,7 @@ func _on_steam_status(result: int, code: int, _headers: PackedStringArray, body:
|
||||
|
||||
func _on_steam_action_changed(index: int) -> void:
|
||||
steam_email_input.visible = index == 0
|
||||
steam_legal_check.visible = index == 0
|
||||
steam_username_input.placeholder_text = "Choose a username" if index == 0 else "Existing email or username"
|
||||
|
||||
|
||||
@@ -682,12 +726,14 @@ func _complete_steam() -> void:
|
||||
if action == "create":
|
||||
var validation := _validate_account(steam_username_input.text.strip_edges(), steam_email_input.text.strip_edges(), steam_password_input.text, steam_password_input.text)
|
||||
if not validation.is_empty(): return _show_error(validation)
|
||||
if not steam_legal_check.button_pressed:
|
||||
return _show_error("Agree to the Terms of Service and acknowledge the Privacy Policy to create an account.")
|
||||
elif steam_username_input.text.strip_edges().is_empty() or steam_password_input.text.is_empty():
|
||||
return _show_error("Enter your existing account credentials.")
|
||||
_send_json("steam_complete", "/steam/complete", {
|
||||
"transactionId": steam_transaction_id, "action": action,
|
||||
"username": steam_username_input.text.strip_edges(), "email": steam_email_input.text.strip_edges(),
|
||||
"password": steam_password_input.text
|
||||
"password": steam_password_input.text, "acceptLegal": action == "create"
|
||||
}, "Connecting account...")
|
||||
|
||||
|
||||
@@ -718,12 +764,14 @@ func _accept_session(body: PackedByteArray, fallback_username: String) -> void:
|
||||
var response := _parse_dictionary(body)
|
||||
var token := str(response.get("accessToken", ""))
|
||||
if token.is_empty(): return _show_error("Sign in response did not include an access token.")
|
||||
var legal_value: Variant = response.get("legal", {})
|
||||
var legal: Dictionary = legal_value if typeof(legal_value) == TYPE_DICTIONARY else {}
|
||||
AuthState.set_session(str(response.get("username", fallback_username)), token,
|
||||
str(response.get("refreshToken", "")), str(response.get("role", "")), str(response.get("exp", "")))
|
||||
str(response.get("refreshToken", "")), str(response.get("role", "")), str(response.get("exp", "")), legal)
|
||||
password_input.text = ""
|
||||
_set_busy(false)
|
||||
UISoundService.play_sound("correct")
|
||||
main.show_screen("dashboard")
|
||||
main.show_screen("legal_consent" if AuthState.requires_legal_acceptance else "dashboard")
|
||||
|
||||
|
||||
func _create_request(key: String, callback: Callable) -> void:
|
||||
|
||||
Reference in New Issue
Block a user