Fix cookie persistence: save dict as JSON, verify via HTTP on restart
All checks were successful
Build plugin / build (push) Successful in 1m11s
All checks were successful
Build plugin / build (push) Successful in 1m11s
This commit is contained in:
parent
2b07195789
commit
1931ae143a
1 changed files with 36 additions and 18 deletions
|
|
@ -385,23 +385,41 @@ func _login_with_password(username: String, password: String) -> void:
|
||||||
return
|
return
|
||||||
profile = res.get("profile", {})
|
profile = res.get("profile", {})
|
||||||
is_logged_in = true
|
is_logged_in = true
|
||||||
# Persist the cookie so we can re-authenticate on restart without the
|
# Persist the cookie so we can re-authenticate on restart. Butlerd
|
||||||
# password. Butlerd stores tokens in its own DB, but we need the cookie
|
# stores tokens in its own DB, but we re-send the cookie on subsequent
|
||||||
# to verify the session on subsequent startups.
|
# startups so butlerd can refresh the session if needed.
|
||||||
var cookie: String = res.get("cookie", "")
|
var cookie_dict: Dictionary = res.get("cookie", {})
|
||||||
if cookie != "":
|
if not cookie_dict.is_empty():
|
||||||
emit_signal.call_deferred("login_cookies_saved", username, cookie)
|
var cookie_json := JSON.stringify(cookie_dict)
|
||||||
|
emit_signal.call_deferred("login_cookies_saved", username, cookie_json)
|
||||||
emit_signal.call_deferred("logged_in", LOGIN_STATUS.OK, profile)
|
emit_signal.call_deferred("logged_in", LOGIN_STATUS.OK, profile)
|
||||||
|
|
||||||
|
|
||||||
## Re-authenticates using a previously saved cookie. The cookie is verified
|
## Re-authenticates using a previously saved cookie. The cookie is a JSON
|
||||||
## against itch.io's API directly (bypassing butlerd) because butlerd does
|
## dict of name-value pairs from Profile.LoginWithPassword. We send it to
|
||||||
## not expose a "login with cookie" method.
|
## itch.io's API directly to verify the session — butlerd doesn't expose a
|
||||||
func login_with_cookie(cookie: String) -> void:
|
## "login with cookie" method, but it stores the credentials internally so
|
||||||
await thread_group.exec(_login_with_cookie.bind(cookie))
|
## subsequent butlerd calls will work once we've verified the session.
|
||||||
|
func login_with_cookie(cookie_json: String) -> void:
|
||||||
|
await thread_group.exec(_login_with_cookie.bind(cookie_json))
|
||||||
|
|
||||||
|
|
||||||
func _login_with_cookie(cookie: String) -> void:
|
func _login_with_cookie(cookie_json: String) -> void:
|
||||||
|
var cookie_dict: Dictionary = {}
|
||||||
|
var json := JSON.new()
|
||||||
|
if json.parse(cookie_json) == OK and typeof(json.data) == TYPE_DICTIONARY:
|
||||||
|
cookie_dict = json.data
|
||||||
|
if cookie_dict.is_empty():
|
||||||
|
is_logged_in = false
|
||||||
|
emit_signal.call_deferred("logged_in", LOGIN_STATUS.INVALID_KEY, {})
|
||||||
|
return
|
||||||
|
|
||||||
|
# Build Cookie header from the dict: "name1=value1; name2=value2"
|
||||||
|
var pairs: PackedStringArray = []
|
||||||
|
for key in cookie_dict:
|
||||||
|
pairs.append(str(key) + "=" + str(cookie_dict[key]))
|
||||||
|
var cookie_header := "; ".join(pairs)
|
||||||
|
|
||||||
var http := HTTPClient.new()
|
var http := HTTPClient.new()
|
||||||
var err := http.connect_to_host("api.itch.io", 443, TLSOptions.client())
|
var err := http.connect_to_host("api.itch.io", 443, TLSOptions.client())
|
||||||
if err != OK:
|
if err != OK:
|
||||||
|
|
@ -424,7 +442,7 @@ func _login_with_cookie(cookie: String) -> void:
|
||||||
return
|
return
|
||||||
|
|
||||||
var headers := PackedStringArray([
|
var headers := PackedStringArray([
|
||||||
"Authorization: Bearer " + cookie,
|
"Cookie: " + cookie_header,
|
||||||
"User-Agent: opencode-itch-plugin/1.0",
|
"User-Agent: opencode-itch-plugin/1.0",
|
||||||
])
|
])
|
||||||
http.request(HTTPClient.METHOD_GET, "/profile", headers)
|
http.request(HTTPClient.METHOD_GET, "/profile", headers)
|
||||||
|
|
@ -454,19 +472,19 @@ func _login_with_cookie(cookie: String) -> void:
|
||||||
http.close()
|
http.close()
|
||||||
|
|
||||||
var response_code := http.get_response_code()
|
var response_code := http.get_response_code()
|
||||||
var json_text := body.get_string_from_utf8()
|
var response_text := body.get_string_from_utf8()
|
||||||
if response_code != 200 or json_text.is_empty():
|
if response_code != 200 or response_text.is_empty():
|
||||||
is_logged_in = false
|
is_logged_in = false
|
||||||
emit_signal.call_deferred("logged_in", LOGIN_STATUS.INVALID_KEY, {})
|
emit_signal.call_deferred("logged_in", LOGIN_STATUS.INVALID_KEY, {})
|
||||||
return
|
return
|
||||||
|
|
||||||
var json := JSON.new()
|
var resp_json := JSON.new()
|
||||||
if json.parse(json_text) != OK:
|
if resp_json.parse(response_text) != OK:
|
||||||
is_logged_in = false
|
is_logged_in = false
|
||||||
emit_signal.call_deferred("logged_in", LOGIN_STATUS.INVALID_KEY, {})
|
emit_signal.call_deferred("logged_in", LOGIN_STATUS.INVALID_KEY, {})
|
||||||
return
|
return
|
||||||
|
|
||||||
var data: Dictionary = json.data
|
var data: Dictionary = resp_json.data
|
||||||
profile = data.get("user", data)
|
profile = data.get("user", data)
|
||||||
is_logged_in = true
|
is_logged_in = true
|
||||||
emit_signal.call_deferred("logged_in", LOGIN_STATUS.OK, profile)
|
emit_signal.call_deferred("logged_in", LOGIN_STATUS.OK, profile)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue