From 454de3b8cdad5cf08258a5c633919104d4909841 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Wed, 13 Sep 2023 17:44:33 -0400 Subject: [PATCH 01/10] fix bug on user select screen preventing the back button from working --- components/data/SceneManager.brs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/components/data/SceneManager.brs b/components/data/SceneManager.brs index e876957f5..882a4f23b 100755 --- a/components/data/SceneManager.brs +++ b/components/data/SceneManager.brs @@ -1,4 +1,6 @@ import "pkg:/source/roku_modules/log/LogMixin.brs" +import "pkg:/source/utils/config.brs" +import "pkg:/source/utils/session.bs" sub init() m.log = log.Logger("SceneManager") @@ -77,16 +79,22 @@ end sub sub popScene() group = m.groups.pop() if group <> invalid - if group.isSubType("JFGroup") + groupType = group.subtype() + if groupType = "JFGroup" unregisterOverhangData(group) - else if group.isSubType("JFVideo") + else if groupType = "JFVideo" ' Stop video to make sure app communicates stop playstate to server group.control = "stop" + else if groupType = "UserSelect" + ' user pressed back on the UserSelect screen and wants to select a server + ' wipe the current server session data + session.server.Delete() + unset_setting("server") end if group.visible = false - if group.isSubType("JFScreen") + if groupType = "JFScreen" group.callFunc("OnScreenHidden") end if else From b5bd893241ef6739f34b7d882137f09dad63bfef Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Wed, 13 Sep 2023 22:20:50 -0400 Subject: [PATCH 02/10] fix back bug on login and remove recursive function --- components/data/SceneManager.brs | 5 ----- source/ShowScenes.brs | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/components/data/SceneManager.brs b/components/data/SceneManager.brs index 882a4f23b..9faa36bb8 100755 --- a/components/data/SceneManager.brs +++ b/components/data/SceneManager.brs @@ -85,11 +85,6 @@ sub popScene() else if groupType = "JFVideo" ' Stop video to make sure app communicates stop playstate to server group.control = "stop" - else if groupType = "UserSelect" - ' user pressed back on the UserSelect screen and wants to select a server - ' wipe the current server session data - session.server.Delete() - unset_setting("server") end if group.visible = false diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs index a07715a4e..093d50b56 100644 --- a/source/ShowScenes.brs +++ b/source/ShowScenes.brs @@ -1,4 +1,4 @@ -function LoginFlow(startOver = false as boolean) +function LoginFlow() 'Collect Jellyfin server and user information start_login: @@ -41,9 +41,11 @@ function LoginFlow(startOver = false as boolean) activeUser = get_setting("active_user") if activeUser = invalid print "No active user found in registry" + user_select: SendPerformanceBeacon("AppDialogInitiate") ' Roku Performance monitoring - Dialog Starting publicUsers = GetPublicUsers() - if publicUsers.count() + numPubUsers = publicUsers.count() + if numPubUsers > 0 publicUsersNodes = [] for each item in publicUsers user = CreateObject("roSGNode", "PublicUserData") @@ -57,7 +59,9 @@ function LoginFlow(startOver = false as boolean) userSelected = CreateUserSelectGroup(publicUsersNodes) if userSelected = "backPressed" SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed - return LoginFlow(true) + session.server.Delete() + unset_setting("server") + goto start_login else 'Try to login without password. If the token is valid, we're done userData = get_token(userSelected, "") @@ -75,8 +79,13 @@ function LoginFlow(startOver = false as boolean) passwordEntry = CreateSigninGroup(userSelected) SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed if passwordEntry = "backPressed" - m.global.sceneManager.callFunc("clearScenes") - return LoginFlow(true) + if numPubUsers > 0 + goto user_select + else + session.server.Delete() + unset_setting("server") + goto start_login + end if end if else print "Active user found in registry" From b9359b8f51373ded5f27b6b8292b94d48e45635b Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Thu, 14 Sep 2023 11:52:32 -0400 Subject: [PATCH 03/10] fix #1372 + fix #310. Add option to "Change User" from home page --- components/data/UserData.brs | 3 -- source/Main.brs | 4 ++ source/ShowScenes.brs | 96 ++++++++++++++++++++++++------------ source/api/userauth.brs | 24 ++------- source/utils/session.bs | 3 -- 5 files changed, 72 insertions(+), 58 deletions(-) diff --git a/components/data/UserData.brs b/components/data/UserData.brs index 564848a6f..54693f168 100644 --- a/components/data/UserData.brs +++ b/components/data/UserData.brs @@ -20,9 +20,6 @@ sub loadFromRegistry(id as string) end sub sub saveToRegistry() - set_user_setting("username", m.top.username) - set_user_setting("token", m.top.token) - users = parseJson(get_setting("available_users", "[]")) this_user = invalid for each user in users diff --git a/source/Main.brs b/source/Main.brs index 298650bd2..474f178ac 100644 --- a/source/Main.brs +++ b/source/Main.brs @@ -524,6 +524,10 @@ sub Main (args as dynamic) as void SignOut(false) sceneManager.callFunc("clearScenes") goto app_start + else if button.id = "change_user" + SignOut(false) + sceneManager.callFunc("clearScenes") + goto app_start else if button.id = "sign_out" SignOut() sceneManager.callFunc("clearScenes") diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs index 093d50b56..c98363401 100644 --- a/source/ShowScenes.brs +++ b/source/ShowScenes.brs @@ -57,20 +57,70 @@ function LoginFlow() publicUsersNodes.push(user) end for userSelected = CreateUserSelectGroup(publicUsersNodes) + + SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed if userSelected = "backPressed" - SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed session.server.Delete() unset_setting("server") goto start_login else + print "A public user was selected with username=" + userSelected + ' save userid to session + for each user in publicUsersNodes + if user.name = userSelected + session.user.Update("id", user.id) + exit for + end if + end for + ' try to login with token from registry + myToken = get_user_setting("token") + if myToken <> invalid + ' check if token is valid + print "Auth token found in registry for selected user" + session.user.Update("authToken", myToken) + print "Attempting to use API with auth token" + currentUser = AboutMe() + if currentUser = invalid + print "Auth token is no longer valid - deleting token" + unset_user_setting("token") + else + print "Success! Auth token is still valid" + session.user.Login(currentUser) + LoadUserPreferences() + LoadUserAbilities() + return true + end if + else + print "No auth token found in registry for selected user" + end if + ' try to login with password from registry + userData = invalid + myPassword = get_user_setting("password") + if isValid(myPassword) + ' saved password found for selected user + print "Saved credentials found for selected user. Attempting to login" + userData = get_token(userSelected, myPassword) + if isValid(userData) + print "login success!" + session.user.Login(userData) + LoadUserPreferences() + LoadUserAbilities() + return true + end if + else + print "No saved credentials found for selected user" + end if 'Try to login without password. If the token is valid, we're done + print "Attempting to login with no password" userData = get_token(userSelected, "") if isValid(userData) + print "login success!" session.user.Login(userData) LoadUserPreferences() LoadUserAbilities() - SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed return true + else + print "Auth failed. Password required" end if end if else @@ -98,10 +148,8 @@ function LoginFlow() print "Attempting to use API with auth token" currentUser = AboutMe() if currentUser = invalid - print "Auth token is no longer valid - restart login flow" + print "Auth token is no longer valid - delete token and restart login flow" unset_user_setting("token") - unset_setting("active_user") - session.user.Logout() goto start_login else print "Success! Auth token is still valid" @@ -109,8 +157,10 @@ function LoginFlow() end if else print "No auth token found in registry" - myUsername = get_setting("username") - myPassword = get_setting("password") + + print "Checking to see if we have saved credentials" + myUsername = get_user_setting("username") + myPassword = get_user_setting("password") userData = invalid if isValid(myUsername) and isValid(myPassword) @@ -119,8 +169,8 @@ function LoginFlow() userData = get_token(myUsername, myPassword) else print "Username in registry is an empty string" - unset_setting("username") - unset_setting("password") + unset_user_setting("username") + unset_user_setting("password") end if else if isValid(myUsername) and not isValid(myPassword) print "Username found in registry but no password" @@ -129,7 +179,7 @@ function LoginFlow() userData = get_token(myUsername, "") else print "Username in registry is an empty string" - unset_setting("username") + unset_user_setting("username") end if else if not isValid(myUsername) and not isValid(myPassword) @@ -371,25 +421,6 @@ function CreateSigninGroup(user = "") group.findNode("prompt").text = tr("Sign In") - 'Load in any saved server data and see if we can just log them in... - server = m.global.session.server.url - if isValid(server) - server = LCase(server)'Saved server data is always lowercase - end if - saved = get_setting("saved_servers") - if isValid(saved) - savedServers = ParseJson(saved) - for each item in savedServers.serverList - if item.baseUrl = server and isValid(item.username) and isValid(item.password) - userData = get_token(item.username, item.password) - if isValid(userData) - session.user.Login(userData) - return "true" - end if - end if - end for - end if - config = group.findNode("configOptions") username_field = CreateObject("roSGNode", "ConfigData") username_field.label = tr("Username") @@ -456,9 +487,11 @@ function CreateSigninGroup(user = "") activeUser = get_token(username.value, password.value) if isValid(activeUser) session.user.Login(activeUser) - set_setting("username", username.value) - set_setting("password", password.value) + ' save credentials if checkbox.checkedState[0] = true + set_user_setting("username", username.value) + set_user_setting("password", password.value) + set_user_setting("token", activeUser.token) 'Update our saved server list, so next time the user can just click and go UpdateSavedServerList() end if @@ -524,6 +557,7 @@ function CreateHomeGroup() new_options = [] options_buttons = [ { "title": "Search", "id": "goto_search" }, + { "title": "Change user", "id": "change_user" }, { "title": "Change server", "id": "change_server" }, { "title": "Sign out", "id": "sign_out" } ] diff --git a/source/api/userauth.brs b/source/api/userauth.brs index 657af4931..cef1d8937 100644 --- a/source/api/userauth.brs +++ b/source/api/userauth.brs @@ -32,28 +32,10 @@ function AboutMe(id = "" as string) end function sub SignOut(deleteSavedEntry = true as boolean) - if m.global.session.user.id <> invalid + if m.global.session.user.id <> invalid and deleteSavedEntry = true unset_user_setting("token") - unset_setting("username") - unset_setting("password") - if deleteSavedEntry = true - 'Also delete any credentials in the "saved servers" list - saved = get_setting("saved_servers") - server = m.global.session.server.url - if server <> invalid - server = LCase(server) - savedServers = ParseJson(saved) - newServers = { serverList: [] } - for each item in savedServers.serverList - if item.baseUrl = server - item.username = "" - item.password = "" - end if - newServers.serverList.Push(item) - end for - set_setting("saved_servers", FormatJson(newServers)) - end if - end if + unset_user_setting("username") + unset_user_setting("password") end if unset_setting("active_user") session.user.Logout() diff --git a/source/utils/session.bs b/source/utils/session.bs index 4f015751b..a62365a4f 100644 --- a/source/utils/session.bs +++ b/source/utils/session.bs @@ -151,9 +151,6 @@ namespace session if m.global.app.isDev print "m.global.session.user.settings = ", m.global.session.user.settings end if - ' ensure registry is updated - set_user_setting("username", tmpSession.user.name) - set_user_setting("token", tmpSession.user.authToken) end sub ' Empty the global user session array and reload defaults From 50020a3f20d11f30720fc6cd083d3ac7dfbbf9fb Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Thu, 14 Sep 2023 17:51:41 -0400 Subject: [PATCH 04/10] create global rememberme setting --- components/data/UserData.brs | 4 +++- components/settings/settings.brs | 33 +++++++++++++++++++++++++++++--- locale/en_US/translations.ts | 20 +++++++++++++++++++ settings/settings.json | 14 ++++++++++++++ source/utils/session.bs | 18 +++++++++++++++++ 5 files changed, 85 insertions(+), 4 deletions(-) diff --git a/components/data/UserData.brs b/components/data/UserData.brs index 54693f168..446abbf38 100644 --- a/components/data/UserData.brs +++ b/components/data/UserData.brs @@ -54,7 +54,9 @@ function setPreference(key as string, value as string) end function sub setActive() - set_setting("active_user", m.top.id) + if m.global.session.user.settings["global.rememberme"] + set_setting("active_user", m.top.id) + end if end sub sub setServer(hostname as string) diff --git a/components/settings/settings.brs b/components/settings/settings.brs index 5809353f4..72a4f6210 100644 --- a/components/settings/settings.brs +++ b/components/settings/settings.brs @@ -1,6 +1,7 @@ import "pkg:/source/utils/config.brs" import "pkg:/source/utils/misc.brs" import "pkg:/source/roku_modules/log/LogMixin.brs" +import "pkg:/source/api/sdk.bs" sub init() m.log = log.Logger("Settings") @@ -160,14 +161,40 @@ end sub sub boolSettingChanged() - if m.boolSetting.focusedChild = invalid then return selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused] if m.boolSetting.checkedItem - set_user_setting(selectedSetting.settingName, "true") + session.user.settings.Save(selectedSetting.settingName, "true") + if Left(selectedSetting.settingName, 7) = "global." + ' global user setting + ' save to main registry block + set_setting(selectedSetting.settingName, "true") + ' setting specific triggers + if selectedSetting.settingName = "global.rememberme" + print "m.global.session.user.id=", m.global.session.user.id + set_setting("active_user", m.global.session.user.id) + end if + else + ' regular user setting + ' save to user specific registry block + set_user_setting(selectedSetting.settingName, "true") + end if else - set_user_setting(selectedSetting.settingName, "false") + session.user.settings.Save(selectedSetting.settingName, "false") + if Left(selectedSetting.settingName, 7) = "global." + ' global user setting + ' save to main registry block + set_setting(selectedSetting.settingName, "false") + ' setting specific triggers + if selectedSetting.settingName = "global.rememberme" + unset_setting("active_user") + end if + else + ' regular user setting + ' save to user specific registry block + set_user_setting(selectedSetting.settingName, "false") + end if end if end sub diff --git a/locale/en_US/translations.ts b/locale/en_US/translations.ts index e4a3d6b0b..2ea904966 100644 --- a/locale/en_US/translations.ts +++ b/locale/en_US/translations.ts @@ -1208,5 +1208,25 @@ Disable the HEVC codec on this device. This may improve playback for some devices (ultra). User Setting - Setting description + + Global + Global + User Setting - Setting title + + + Global settings that affect everyone that uses this Roku device. + Global settings that affect everyone that uses this Roku device. + User Setting - Setting description + + + Remember Me? + Remember Me? + User Setting - Setting title + + + Remember the currently logged in user and try to log them in again next time you start the Jellyfin app. + Remember the currently logged in user and try to log them in again next time you start the Jellyfin app. + User Setting - Setting description + \ No newline at end of file diff --git a/settings/settings.json b/settings/settings.json index f5240e70f..422174741 100644 --- a/settings/settings.json +++ b/settings/settings.json @@ -1,4 +1,18 @@ [ + { + "title": "Global", + "description": "Global settings that affect everyone that uses this Roku device.", + "children": [ + { + "title": "Remember Me?", + "description": "Remember the currently logged in user and try to log them in again next time you start the Jellyfin app.", + "settingName": "global.rememberme", + "type": "bool", + "default": "false" + } + + ] + }, { "title": "Playback", "description": "Settings relating to playback and supported codec and media types.", diff --git a/source/utils/session.bs b/source/utils/session.bs index a62365a4f..53146a3d3 100644 --- a/source/utils/session.bs +++ b/source/utils/session.bs @@ -151,6 +151,10 @@ namespace session if m.global.app.isDev print "m.global.session.user.settings = ", m.global.session.user.settings end if + + if m.global.session.user.settings["global.rememberme"] + set_user_setting("token", tmpSession.user.authToken) + end if end sub ' Empty the global user session array and reload defaults @@ -228,6 +232,20 @@ namespace session end for end if end for + + ' load globals + session.user.settings.LoadGlobals() + end sub + + ' Grab global vars from registry and overwrite defaults + sub LoadGlobals() + ' search main registry block for all keys that start with "global." + jfRegistry = RegistryReadAll("Jellyfin") + for each item in jfRegistry + if Left(item, 7) = "global." + session.user.settings.Save(item, get_setting(item)) + end if + end for end sub ' Saves the user setting to the global session. From f1512dc80a267c2312cd9f3f02b1018f3e64556c Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 16 Sep 2023 18:48:34 -0400 Subject: [PATCH 05/10] don't save username and password --- source/ShowScenes.brs | 90 ----------------------------------------- source/api/userauth.brs | 2 - 2 files changed, 92 deletions(-) diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs index c98363401..81c40edc7 100644 --- a/source/ShowScenes.brs +++ b/source/ShowScenes.brs @@ -93,23 +93,6 @@ function LoginFlow() else print "No auth token found in registry for selected user" end if - ' try to login with password from registry - userData = invalid - myPassword = get_user_setting("password") - if isValid(myPassword) - ' saved password found for selected user - print "Saved credentials found for selected user. Attempting to login" - userData = get_token(userSelected, myPassword) - if isValid(userData) - print "login success!" - session.user.Login(userData) - LoadUserPreferences() - LoadUserAbilities() - return true - end if - else - print "No saved credentials found for selected user" - end if 'Try to login without password. If the token is valid, we're done print "Attempting to login with no password" userData = get_token(userSelected, "") @@ -157,42 +140,6 @@ function LoginFlow() end if else print "No auth token found in registry" - - print "Checking to see if we have saved credentials" - myUsername = get_user_setting("username") - myPassword = get_user_setting("password") - userData = invalid - - if isValid(myUsername) and isValid(myPassword) - if myUsername <> "" - print "Username and password found in registry. Attempting to login" - userData = get_token(myUsername, myPassword) - else - print "Username in registry is an empty string" - unset_user_setting("username") - unset_user_setting("password") - end if - else if isValid(myUsername) and not isValid(myPassword) - print "Username found in registry but no password" - if myUsername <> "" - print "Attempting to login with no password" - userData = get_token(myUsername, "") - else - print "Username in registry is an empty string" - unset_user_setting("username") - end if - - else if not isValid(myUsername) and not isValid(myPassword) - print "Neither username nor password found in registry - restart login flow" - unset_setting("active_user") - session.user.Logout() - goto start_login - end if - - if isValid(userData) - print "login success!" - session.user.Login(userData) - end if end if end if @@ -313,11 +260,6 @@ function CreateServerGroup() m.scene.dialog = dialog serverUrl = standardize_jellyfin_url(screen.serverUrl) - 'If this is a different server from what we know, reset username/password setting - if m.global.session.server.url <> serverUrl - set_setting("username", "") - set_setting("password", "") - end if set_setting("server", serverUrl) isConnected = session.server.UpdateURL(serverUrl) @@ -489,11 +431,7 @@ function CreateSigninGroup(user = "") session.user.Login(activeUser) ' save credentials if checkbox.checkedState[0] = true - set_user_setting("username", username.value) - set_user_setting("password", password.value) set_user_setting("token", activeUser.token) - 'Update our saved server list, so next time the user can just click and go - UpdateSavedServerList() end if return "true" end if @@ -905,34 +843,6 @@ function CreatePersonView(personData as object) as dynamic return person end function -sub UpdateSavedServerList() - server = m.global.session.server.url - username = get_setting("username") - password = get_setting("password") - - if server = invalid or username = invalid or password = invalid - return - end if - - server = LCase(server)'Saved server data is always lowercase - - saved = get_setting("saved_servers") - if isValid(saved) - savedServers = ParseJson(saved) - if isValid(savedServers.serverList) and savedServers.serverList.Count() > 0 - newServers = { serverList: [] } - for each item in savedServers.serverList - if item.baseUrl = server - item.username = username - item.password = password - end if - newServers.serverList.Push(item) - end for - set_setting("saved_servers", FormatJson(newServers)) - end if - end if -end sub - 'Opens dialog asking user if they want to resume video or start playback over only on the home screen sub playbackOptionDialog(time as longinteger, meta as object) diff --git a/source/api/userauth.brs b/source/api/userauth.brs index cef1d8937..c9627e39c 100644 --- a/source/api/userauth.brs +++ b/source/api/userauth.brs @@ -34,8 +34,6 @@ end function sub SignOut(deleteSavedEntry = true as boolean) if m.global.session.user.id <> invalid and deleteSavedEntry = true unset_user_setting("token") - unset_user_setting("username") - unset_user_setting("password") end if unset_setting("active_user") session.user.Logout() From ac1e57b32eeca10d76bf8029f9931ade9d5c38a7 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 16 Sep 2023 19:40:57 -0400 Subject: [PATCH 06/10] save username and append to deviceid in auth header --- source/ShowScenes.brs | 31 +++++++++++++++++++++++++---- source/api/baserequest.brs | 14 ++++++++----- source/api/userauth.brs | 1 + source/utils/deviceCapabilities.brs | 2 +- source/utils/session.bs | 6 ++++++ 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs index 81c40edc7..48a1853db 100644 --- a/source/ShowScenes.brs +++ b/source/ShowScenes.brs @@ -65,6 +65,9 @@ function LoginFlow() goto start_login else print "A public user was selected with username=" + userSelected + session.user.Update("name", userSelected) + regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "") + session.user.Update("friendlyName", regex.ReplaceAll(userSelected, "")) ' save userid to session for each user in publicUsersNodes if user.name = userSelected @@ -83,6 +86,7 @@ function LoginFlow() if currentUser = invalid print "Auth token is no longer valid - deleting token" unset_user_setting("token") + unset_user_setting("username") else print "Success! Auth token is still valid" session.user.Login(currentUser) @@ -124,16 +128,34 @@ function LoginFlow() print "Active user found in registry" session.user.Update("id", activeUser) + myUsername = get_user_setting("username") myAuthToken = get_user_setting("token") - if isValid(myAuthToken) + if isValid(myAuthToken) and isValid(myUsername) print "Auth token found in registry" session.user.Update("authToken", myAuthToken) + session.user.Update("name", myUsername) + regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "") + session.user.Update("friendlyName", regex.ReplaceAll(myUsername, "")) print "Attempting to use API with auth token" currentUser = AboutMe() if currentUser = invalid - print "Auth token is no longer valid - delete token and restart login flow" - unset_user_setting("token") - goto start_login + print "Auth token is no longer valid" + 'Try to login without password. If the token is valid, we're done + print "Attempting to login with no password" + userData = get_token(userSelected, "") + if isValid(userData) + print "login success!" + session.user.Login(userData) + LoadUserPreferences() + LoadUserAbilities() + return true + else + print "Auth failed. Password required" + print "delete token and restart login flow" + unset_user_setting("token") + unset_user_setting("username") + goto start_login + end if else print "Success! Auth token is still valid" session.user.Login(currentUser) @@ -432,6 +454,7 @@ function CreateSigninGroup(user = "") ' save credentials if checkbox.checkedState[0] = true set_user_setting("token", activeUser.token) + set_user_setting("username", username.value) end if return "true" end if diff --git a/source/api/baserequest.brs b/source/api/baserequest.brs index fde121ac1..75710c232 100644 --- a/source/api/baserequest.brs +++ b/source/api/baserequest.brs @@ -203,14 +203,18 @@ function authRequest(request as object) as object if m.global.session.user.id <> invalid auth = auth + ", UserId=" + QUOTE + m.global.session.user.id + QUOTE - auth = auth + ", DeviceId=" + QUOTE + m.global.device.id + QUOTE - if m.global.session.user.authToken <> invalid - auth = auth + ", Token=" + QUOTE + m.global.session.user.authToken + QUOTE - end if + end if + + if m.global.session.user <> invalid and m.global.session.user.friendlyName <> invalid + auth = auth + ", DeviceId=" + QUOTE + m.global.device.id + m.global.session.user.friendlyName + QUOTE else - auth = auth + ", DeviceId=" + QUOTE + m.global.device.uuid + QUOTE + auth = auth + ", DeviceId=" + QUOTE + m.global.device.id + QUOTE end if + if m.global.session.user.authToken <> invalid + auth = auth + ", Token=" + QUOTE + m.global.session.user.authToken + QUOTE + end if + print auth request.AddHeader("Authorization", auth) return request end function diff --git a/source/api/userauth.brs b/source/api/userauth.brs index c9627e39c..ce00984b9 100644 --- a/source/api/userauth.brs +++ b/source/api/userauth.brs @@ -34,6 +34,7 @@ end function sub SignOut(deleteSavedEntry = true as boolean) if m.global.session.user.id <> invalid and deleteSavedEntry = true unset_user_setting("token") + unset_user_setting("username") end if unset_setting("active_user") session.user.Logout() diff --git a/source/utils/deviceCapabilities.brs b/source/utils/deviceCapabilities.brs index 2501bd87b..c8f59ce4a 100644 --- a/source/utils/deviceCapabilities.brs +++ b/source/utils/deviceCapabilities.brs @@ -12,7 +12,7 @@ function getDeviceCapabilities() as object "Photo" ], "SupportedCommands": [], - "SupportsPersistentIdentifier": false, + "SupportsPersistentIdentifier": true, "SupportsMediaControl": false, "SupportsContentUploading": false, "SupportsSync": false, diff --git a/source/utils/session.bs b/source/utils/session.bs index 53146a3d3..9793641d0 100644 --- a/source/utils/session.bs +++ b/source/utils/session.bs @@ -137,6 +137,10 @@ namespace session tmpSession.AddReplace("user", userData.json.User) tmpSession.user.AddReplace("authToken", userData.json.AccessToken) end if + ' remove special characters from name + regex = CreateObject("roRegex", "[^a-zA-Z0-9\ \-\_]", "") + friendlyName = regex.ReplaceAll(tmpSession.user.name, "") + tmpSession.user.AddReplace("friendlyName", friendlyName) tmpSession.user.AddReplace("settings", oldUserSettings) ' update global user session @@ -149,11 +153,13 @@ namespace session end for if m.global.app.isDev + print "m.global.session.user = ", m.global.session.user print "m.global.session.user.settings = ", m.global.session.user.settings end if if m.global.session.user.settings["global.rememberme"] set_user_setting("token", tmpSession.user.authToken) + set_user_setting("username", tmpSession.user.name) end if end sub From a69ee3f2442d278b33c3cfb666d2a77da3296f0e Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 16 Sep 2023 20:08:54 -0400 Subject: [PATCH 07/10] remove debugging --- source/api/baserequest.brs | 2 +- source/utils/session.bs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source/api/baserequest.brs b/source/api/baserequest.brs index 75710c232..103461339 100644 --- a/source/api/baserequest.brs +++ b/source/api/baserequest.brs @@ -214,7 +214,7 @@ function authRequest(request as object) as object if m.global.session.user.authToken <> invalid auth = auth + ", Token=" + QUOTE + m.global.session.user.authToken + QUOTE end if - print auth + request.AddHeader("Authorization", auth) return request end function diff --git a/source/utils/session.bs b/source/utils/session.bs index 9793641d0..01c5712da 100644 --- a/source/utils/session.bs +++ b/source/utils/session.bs @@ -153,7 +153,6 @@ namespace session end for if m.global.app.isDev - print "m.global.session.user = ", m.global.session.user print "m.global.session.user.settings = ", m.global.session.user.settings end if From abbc3c034fd9dbd8b2456aa1aa78fae0edcedf9c Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Sat, 16 Sep 2023 20:10:42 -0400 Subject: [PATCH 08/10] create registry migration - delete deprecated settings --- source/Main.brs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/source/Main.brs b/source/Main.brs index 474f178ac..ed225b28d 100644 --- a/source/Main.brs +++ b/source/Main.brs @@ -62,7 +62,8 @@ sub Main (args as dynamic) as void end if ' Only show the Whats New popup the first time a user runs a new client version. - if m.global.app.version <> get_setting("LastRunVersion") + appLastRunVersion = get_setting("LastRunVersion") + if m.global.app.version <> appLastRunVersion ' Ensure the user hasn't disabled Whats New popups if m.global.session.user.settings["load.allowwhatsnew"] = true set_setting("LastRunVersion", m.global.app.version) @@ -72,6 +73,34 @@ sub Main (args as dynamic) as void end if end if + ' Registry migrations + if isValid(appLastRunVersion) and not versionChecker(appLastRunVersion, "1.7.0") + ' last app version used less than 1.7.0 + ' no longer saving raw password to registry + ' auth token and username are now stored in user settings and not global settings + print "Running 1.7.0 registry migrations" + ' remove global settings + unset_setting("token") + unset_setting("username") + unset_setting("password") + ' remove user settings + unset_user_setting("password") + ' remove saved credentials from saved_servers + saved = get_setting("saved_servers") + if isValid(saved) + savedServers = ParseJson(saved) + if isValid(savedServers.serverList) and savedServers.serverList.Count() > 0 + newServers = { serverList: [] } + for each item in savedServers.serverList + item.Delete("username") + item.Delete("password") + newServers.serverList.Push(item) + end for + set_setting("saved_servers", FormatJson(newServers)) + end if + end if + end if + ' Handle input messages input = CreateObject("roInput") input.SetMessagePort(m.port) From 3f658c719fb9ded528a7d6fd871cffdf21a70029 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Thu, 21 Sep 2023 09:48:52 -0400 Subject: [PATCH 09/10] remove unneeded imports --- components/data/SceneManager.brs | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/data/SceneManager.brs b/components/data/SceneManager.brs index 9faa36bb8..51191bb8d 100755 --- a/components/data/SceneManager.brs +++ b/components/data/SceneManager.brs @@ -1,6 +1,4 @@ import "pkg:/source/roku_modules/log/LogMixin.brs" -import "pkg:/source/utils/config.brs" -import "pkg:/source/utils/session.bs" sub init() m.log = log.Logger("SceneManager") From 43b7e48ba4872855cda61e11751ad221464a41c4 Mon Sep 17 00:00:00 2001 From: Charles Ewert Date: Thu, 21 Sep 2023 09:58:07 -0400 Subject: [PATCH 10/10] Wipe server session when changing server --- source/Main.brs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Main.brs b/source/Main.brs index ed225b28d..4ad8d3d1a 100644 --- a/source/Main.brs +++ b/source/Main.brs @@ -549,7 +549,7 @@ sub Main (args as dynamic) as void group.findNode("SearchBox").findNode("search_Key").active = true else if button.id = "change_server" unset_setting("server") - unset_setting("port") + session.server.Delete() SignOut(false) sceneManager.callFunc("clearScenes") goto app_start