diff --git a/components/config/ConfigList.brs b/components/config/ConfigList.brs index f2c4f49ce..56cf87432 100644 --- a/components/config/ConfigList.brs +++ b/components/config/ConfigList.brs @@ -27,7 +27,7 @@ sub onItemSelected() i = m.top.itemSelected itemField = m.top.content.getchild(i) - show_dialog(itemField) + showDialog(itemField) end sub function onDialogButton() @@ -46,7 +46,7 @@ function onDialogButton() end function -sub show_dialog(configField) +sub showDialog(configField) dialog = createObject("roSGNode", "StandardKeyboardDialog") m.configField = configField dialog.title = configField.label diff --git a/source/Main.brs b/source/Main.brs index 83400c6e4..347f4b632 100644 --- a/source/Main.brs +++ b/source/Main.brs @@ -61,10 +61,6 @@ sub Main (args as dynamic) as void end if end if - ' migrate registry if needed - runGlobalMigrations() - runUserMigrations() - ' Save the global last run version of the app if m.global.app.version <> m.global.app.lastRunVersion ' update global LastRunVersion diff --git a/source/ShowScenes.brs b/source/ShowScenes.brs index ff80ef669..fec53fcd1 100644 --- a/source/ShowScenes.brs +++ b/source/ShowScenes.brs @@ -43,19 +43,48 @@ function LoginFlow() print "No active user found in registry" user_select: SendPerformanceBeacon("AppDialogInitiate") ' Roku Performance monitoring - Dialog Starting + publicUsers = GetPublicUsers() + savedUsers = getSavedUsers() + numPubUsers = publicUsers.count() - if numPubUsers > 0 + numSavedUsers = savedUsers.count() + + if numPubUsers > 0 or numSavedUsers > 0 publicUsersNodes = [] - for each item in publicUsers - user = CreateObject("roSGNode", "PublicUserData") - user.id = item.Id - user.name = item.Name - if isValid(item.PrimaryImageTag) - user.ImageURL = UserImageURL(user.id, { "tag": item.PrimaryImageTag }) - end if - publicUsersNodes.push(user) - end for + publicUserIds = [] + ' load public users + if numPubUsers > 0 + for each item in publicUsers + user = CreateObject("roSGNode", "PublicUserData") + user.id = item.Id + user.name = item.Name + if isValid(item.PrimaryImageTag) + user.ImageURL = UserImageURL(user.id, { "tag": item.PrimaryImageTag }) + end if + publicUsersNodes.push(user) + publicUserIds.push(user.id) + end for + end if + ' load saved users for this server id + if numSavedUsers > 0 + for each savedUser in savedUsers + if isValid(savedUser.serverId) and savedUser.serverId = m.global.session.server.id + ' only show unique userids on screen. + if not arrayHasValue(publicUserIds, savedUser.Id) + user = CreateObject("roSGNode", "PublicUserData") + user.id = savedUser.Id + + if isValid(savedUser.username) + user.name = savedUser.username + end if + + publicUsersNodes.push(user) + end if + end if + end for + end if + ' push all users to the user select view userSelected = CreateUserSelectGroup(publicUsersNodes) SendPerformanceBeacon("AppDialogComplete") ' Roku Performance monitoring - Dialog Closed @@ -89,7 +118,7 @@ function LoginFlow() unset_user_setting("username") else print "Success! Auth token is still valid" - session.user.Login(currentUser) + session.user.Login(currentUser, true) LoadUserPreferences() LoadUserAbilities() return true @@ -102,7 +131,7 @@ function LoginFlow() userData = get_token(userSelected, "") if isValid(userData) print "login success!" - session.user.Login(userData) + session.user.Login(userData, true) LoadUserPreferences() LoadUserAbilities() return true @@ -145,7 +174,7 @@ function LoginFlow() userData = get_token(userSelected, "") if isValid(userData) print "login success!" - session.user.Login(userData) + session.user.Login(userData, true) LoadUserPreferences() LoadUserAbilities() return true @@ -158,7 +187,7 @@ function LoginFlow() end if else print "Success! Auth token is still valid" - session.user.Login(currentUser) + session.user.Login(currentUser, true) end if else print "No auth token found in registry" @@ -451,11 +480,14 @@ function CreateSigninGroup(user = "") ' Validate credentials activeUser = get_token(username.value, password.value) if isValid(activeUser) - session.user.Login(activeUser) - ' save credentials + print "activeUser=", activeUser if checkbox.checkedState[0] = true + ' save credentials + session.user.Login(activeUser, true) set_user_setting("token", activeUser.token) set_user_setting("username", username.value) + else + session.user.Login(activeUser) end if return "true" end if diff --git a/source/api/userauth.brs b/source/api/userauth.brs index ce00984b9..3c6970472 100644 --- a/source/api/userauth.brs +++ b/source/api/userauth.brs @@ -32,7 +32,7 @@ function AboutMe(id = "" as string) end function sub SignOut(deleteSavedEntry = true as boolean) - if m.global.session.user.id <> invalid and deleteSavedEntry = true + if deleteSavedEntry = true unset_user_setting("token") unset_user_setting("username") end if diff --git a/source/migrations.bs b/source/migrations.bs index f73dbbbe0..389ee214c 100644 --- a/source/migrations.bs +++ b/source/migrations.bs @@ -1,3 +1,5 @@ +import "pkg:/source/utils/misc.brs" + ' Functions that update the registry based on the last run version and the currently running version ' Run all necessary registry mirations on the "global" Jellyfin registry section @@ -8,6 +10,21 @@ sub runGlobalMigrations() print "Running 1.7.0 global registry migrations" ' no longer saving raw password to registry ' auth token and username are now stored in user settings and not global settings + + savedUserId = get_setting("active_user") + if isValid(savedUserId) + registry_write("serverId", m.global.session.server.id, savedUserId) + ' copy saved credentials to user block + savedUsername = get_setting("username") + if isValid(savedUsername) + registry_write("username", savedUsername, savedUserId) + end if + + savedToken = get_setting("token") + if isValid(savedToken) + registry_write("token", savedToken, savedUserId) + end if + end if unset_setting("port") unset_setting("token") unset_setting("username") @@ -26,24 +43,25 @@ sub runGlobalMigrations() set_setting("saved_servers", FormatJson(newServers)) end if end if - ' now saving LastRunVersion globally and per user so that we can run user specific registry migrations - ' duplicate LastRunVersion to all user settings in the registry so that we can run user specific migrations - regSections = getRegistrySections() - for each section in regSections - if section <> "Jellyfin" - registry_write("LastRunVersion", m.global.app.version, section) - end if - end for + end if + if m.global.app.lastRunVersion <> invalid + runRegistryUserMigrations(m.global.app.lastRunVersion) end if end sub -' Run all necessary registry mirations on the user specific registry section -sub runUserMigrations() - ' User registry migrations - if m.global.session.user.lastRunVersion <> invalid and not versionChecker(m.global.session.user.lastRunVersion, "1.7.0") - ' last run version was less than 1.7.0 - print "Running 1.7.0 user registry migrations" - ' no longer saving password to registry - unset_user_setting("password") - end if +sub runRegistryUserMigrations(version as string) + regSections = getRegistrySections() + for each section in regSections + if section <> "Jellyfin" + if version = "1.7.0" + print "Running User Registry Migration for 1.7.0" + ' now saving LastRunVersion globally and per user so that we can run user specific registry migrations + ' duplicate LastRunVersion to all user settings in the registry so that we can run user specific migrations + ' + ' no longer saving password to registry + registry_write("LastRunVersion", m.global.app.version, section) + registry_delete("password", section) + end if + end if + end for end sub diff --git a/source/utils/config.brs b/source/utils/config.brs index 5827e4b9c..879e2aa55 100644 --- a/source/utils/config.brs +++ b/source/utils/config.brs @@ -100,3 +100,40 @@ function findConfigTreeKey(key as string, tree) return invalid end function + +' Returns an array of saved users from the registry +' that belong to the active server +function getSavedUsers() as object + registrySections = getRegistrySections() + + savedUsers = [] + for each section in registrySections + if section <> "Jellyfin" + savedUsers.push(section) + end if + end for + + savedServerUsers = [] + for each userId in savedUsers + userArray = { + id: userId + } + token = registry_read("token", userId) + + username = registry_read("username", userId) + if username <> invalid + userArray["username"] = username + end if + + serverId = registry_read("serverId", userId) + if serverId <> invalid + userArray["serverId"] = serverId + end if + + if username <> invalid and token <> invalid and serverId <> invalid and serverId = m.global.session.server.id + savedServerUsers.push(userArray) + end if + end for + + return savedServerUsers +end function diff --git a/source/utils/session.bs b/source/utils/session.bs index 8cbd69194..47850afd8 100644 --- a/source/utils/session.bs +++ b/source/utils/session.bs @@ -1,6 +1,7 @@ ' these are needed for ServerInfo() inside session.server.Populate() import "pkg:/source/api/userauth.brs" import "pkg:/source/api/baserequest.brs" +import "pkg:/source/migrations.bs" namespace session ' Initialize the global session array @@ -71,6 +72,9 @@ namespace session session.server.Delete() end if + ' migrate registry if needed + runGlobalMigrations() + return success end function @@ -122,7 +126,7 @@ namespace session ' Update the global session after user is authenticated. ' Accepts a UserData.xml object from get_token() or an assocArray from AboutMe() - sub Login(userData as object) + sub Login(userData as object, saveCredentials = false as boolean) ' validate parameters if userData = invalid or userData.id = invalid then return ' make copy of global user session array @@ -163,7 +167,9 @@ namespace session print "m.global.session.user.settings = ", m.global.session.user.settings end if - if m.global.session.user.settings["global.rememberme"] + set_user_setting("serverId", m.global.session.server.id) + + if saveCredentials set_user_setting("token", tmpSession.user.authToken) set_user_setting("username", tmpSession.user.name) end if