Skip to content

Commit

Permalink
add support for saving credentials for private users
Browse files Browse the repository at this point in the history
  • Loading branch information
cewert committed Sep 23, 2023
1 parent 1c8af7f commit 5b2b2ba
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 42 deletions.
4 changes: 2 additions & 2 deletions components/config/ConfigList.brs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down
4 changes: 0 additions & 4 deletions source/Main.brs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
64 changes: 48 additions & 16 deletions source/ShowScenes.brs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion source/api/userauth.brs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 35 additions & 17 deletions source/migrations.bs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
Expand All @@ -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
37 changes: 37 additions & 0 deletions source/utils/config.brs
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 8 additions & 2 deletions source/utils/session.bs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -71,6 +72,9 @@ namespace session
session.server.Delete()
end if

' migrate registry if needed
runGlobalMigrations()

return success
end function

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 5b2b2ba

Please sign in to comment.