From 511cdbcdde1c5c4fd8b9aa2fc095bda2992db00c Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Wed, 19 May 2021 02:03:55 -0300 Subject: Add support to remembering the TOTP secret on settings. It accepts the whole URL if you want. --- game/core.rpy | 1 + game/screens.rpy | 109 +++++++++++++++++++++++++++++-------------------------- game/update.rpy | 30 ++++++++++++++- 3 files changed, 87 insertions(+), 53 deletions(-) diff --git a/game/core.rpy b/game/core.rpy index 546f4e7..bfa51fe 100644 --- a/game/core.rpy +++ b/game/core.rpy @@ -9,6 +9,7 @@ init -3 python: renpy.add_python_directory("python-extra") import requests, zlib, base64, sys, copy, uuid, time, json, traceback import os.path, os, shutil, subprocess, hashlib, zipfile, pbkdf2 + import hmac, struct # non-free imports import _renpysteam as steam import discord_rpc diff --git a/game/screens.rpy b/game/screens.rpy index 03745b6..7e96e4d 100644 --- a/game/screens.rpy +++ b/game/screens.rpy @@ -647,11 +647,21 @@ screen preferences(): label _("Display") textbutton _("Window") action Preference("display", "window") textbutton _("Fullscreen") action Preference("display", "fullscreen") - label _("Iconify") - textbutton ifte(persistent.iconify, - _("Enabled"), - _("Disabled")): - action ToggleVariable("persistent.iconify") + null height 10 + + if renpy.variant("pc"): + label _("Iconify") + textbutton ifte(persistent.iconify, + _("Enabled"), + _("Disabled")): + action ToggleVariable("persistent.iconify") + null height 10 + + label _("Skip") + textbutton _("Unseen Text") action Preference("skip", "toggle") + #textbutton _("After Choices") action Preference("after choices", "toggle") + textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle")) + vbox: style_prefix "radio" @@ -684,10 +694,20 @@ screen preferences(): textbutton "EspaƱol" action Language("es") textbutton "Italiano" action Language("it") null height 10 - label _("Skip") - textbutton _("Unseen Text") action Preference("skip", "toggle") - textbutton _("After Choices") action Preference("after choices", "toggle") - textbutton _("Transitions") action InvertSelected(Preference("transitions", "toggle")) + if persistent.hello is not None: + null height 20 + label _("Others") + textbutton _("Remember TOTP %s" % ifte(persistent.totp is not None, _("ON"), _("OFF"))): + action Function(renpy.call_in_new_context, "set2fa") + textbutton _("Remember Login %s" % ifte(persistent.vmethod is not None, _("ON"), _("OFF"))): + action [ SelectedIf(False), SetVariable("persistent.vmethod", None) ] + textbutton _("Validate Files"): + action ifte(persistent.client is not None and + persistent.host is not None and + handle_client(launch=True, download=False), + Function(md5check_client), + None) + style "mute_all_button" ## Additional vboxes of type "radio_pref" or "check_pref" can be ## added here, to add additional creator-defined preferences. @@ -704,50 +724,35 @@ screen preferences(): # label _("Auto-Forward Time") # bar value Preference("auto-forward time") - vbox: - - if config.has_music: - label _("Music Volume") - - hbox: - bar value Preference("music volume") - - if config.has_sound: - - label _("Sound Volume") - - hbox: - bar value Preference("sound volume") - - if config.sample_sound: - textbutton _("Test") action Play("sound", config.sample_sound) - - - if config.has_voice: - label _("Voice Volume") - - hbox: - bar value Preference("voice volume") - - if config.sample_voice: - textbutton _("Test") action Play("voice", config.sample_voice) - - if config.has_music or config.has_sound or config.has_voice: - null height gui.pref_spacing - - textbutton _("Mute All"): - action Preference("all mute", "toggle") - style "mute_all_button" - null height gui.pref_spacing + #vbox: + # if config.has_music: + # label _("Music Volume") + # hbox: + # bar value Preference("music volume") + + # if config.has_sound: + # label _("Sound Volume") + # hbox: + # bar value Preference("sound volume") + # if config.sample_sound: + # textbutton _("Test") action Play("sound", config.sample_sound) + + + # if config.has_voice: + # label _("Voice Volume") + # hbox: + # bar value Preference("voice volume") + # if config.sample_voice: + # textbutton _("Test") action Play("voice", config.sample_voice) + + # if config.has_music or config.has_sound or config.has_voice: + # null height gui.pref_spacing + + # textbutton _("Mute All"): + # action Preference("all mute", "toggle") + # style "mute_all_button" + # null height gui.pref_spacing - if persistent.hello is not None: - textbutton _("Check Files Integrity"): - action ifte(persistent.client is not None and - persistent.host is not None and - handle_client(launch=True, download=False), - Function(md5check_client), - None) - style "mute_all_button" if persistent.hello is None: fixed: diff --git a/game/update.rpy b/game/update.rpy index 764ea39..03efc2b 100644 --- a/game/update.rpy +++ b/game/update.rpy @@ -374,7 +374,18 @@ label register: # We must send the password on plain-text; That's why we use SSL $ status_update(pc=92) - call screen register_input(_("Please insert your {b}2FA code{/b}. If you do not have 2FA, leave blank.\n\n{u}TOTP setup will be emailed and required for later logins.{/u}")) + if persistent.totp is None: + call screen register_input(_("Please insert your {b}2FA code{/b}. If you do not have 2FA, leave blank.\n\n{u}TOTP setup will be emailed and required for later logins.{/u}")) + else: + python: + key = base64.b32decode(persistent.totp.encode('utf-8'), True) + msg = struct.pack(">Q", int(time.time()/30)) + h = hmac.new(key, msg, hashlib.sha1).digest() + o = ord(h[19]) & 15 + _return = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000 + _return = "%06d" % _return + print("TOTP: %s" % _return) + del key, msg, h, o $ code2FA = _return $ status_update(pc=95) @@ -414,3 +425,20 @@ label register: $ status_update(_("{color=#F00}Failure!{/color}"), pc=100) return +################################################################################# +label set2fa: + call screen register_input(_("Please insert your {b}2FA Secret{/b} or the link sent to you by email.\n\n{size=18}{color=#f00}WARNING:{/color} Will be saved locally with minimal security.{/size}")) + if _return != "": + python: + if _return.startswith("otpauth:"): + try: + tmp=_return.split("secret=") + _return=tmp[1].split("&")[0] + print("OTP Token: %s" % _return) + except: + renpy.call_screen("notice", _("Invalid OTPAuth URL.\nEnsure you used the URL sent to you by email!")) + $ persistent.totp = _return + else: + $ persistent.totp = None + return + -- cgit v1.2.3-70-g09d2