Skip to main content

Overview

Authentication in GlobalTV Roku is credential-based. The user enters a username and password on the LoginScreen, and AuthTask calls the backend to validate them. On success, credentials are saved to the Roku Registry and used for auto-login on the next launch. A background session check re-authenticates at a fixed interval while the app is running.

AuthTask

Background task that performs the HTTP auth request and writes result fields

RegistryManager

Persists and retrieves credentials under the GlobalTV registry section

LoginScreen

Captures username and password using Roku’s on-device keyboard dialog

GTV_AuthClassifyFailure

Classifies every auth failure into one of five reason codes

Auth flow

1

User enters credentials

LoginScreen opens a StandardKeyboardDialog for the username field, then another for the password field. On submit, it calls TryLogin(), which first requests the Roku email via ChannelStore.getUserData (RFI), then starts AuthTask.
2

Server resolution

AuthTask calls GTV_ResolveServerForAuth(), which iterates the server probe list — LAN servers first, then the public WAN server — using health-check pings. The first server that responds becomes the active server for this session and is saved to the Registry (lastServer key).
3

Auth HTTP request

AuthTask issues a GET to the auth endpoint with URL-encoded credentials:
authUrl = server + "/auth/" + encUser + "/" + encPass
resp = GTV_HttpGet(authUrl, c.TIMEOUT_AUTH)
The endpoint pattern (from AppConstants.PATH_AUTH_TPL) is:
/auth/{user}/{pass}
4

Response parsing

On HTTP 2xx, the task parses the JSON body and checks the subscriberStatus, subscriber_active, or active fields to confirm the subscriber is active. If any field signals an inactive account, the task classifies the failure and exits without saving credentials.
5

Success: credentials saved

On a fully successful auth, AuthTask saves credentials to the Registry and sets global state:
GTV_RegSaveCredentials(username, password)  ' saves username + password keys
m.global.activeServer     = server
m.global.isAuthenticated  = true
m.global.subscriberActive = true
6

LoginScreen receives result

LoginScreen observes AuthTask.done. On success, it emits loginSucceeded = true with loginResult (username, password, rokuEmail). MainScene handles the rest of the launch sequence.

Auth endpoint

The endpoint template is defined in AppConstants as PATH_AUTH_TPL:
PATH_AUTH_TPL : "/auth/{user}/{pass}"
At runtime, AuthTask builds the URL by URL-encoding both values:
encUser = GTV_UrlEncode(username)
encPass = GTV_UrlEncode(password)
authUrl = server + "/auth/" + encUser + "/" + encPass

Auto-login

On every app launch, MainScene checks whether credentials exist in the Registry before showing the LoginScreen:
' RegistryManager.brs
function GTV_RegHasCredentials() as Boolean
    c = AppConstants()
    u = GTV_RegRead(c.REG_KEY_USER)
    p = GTV_RegRead(c.REG_KEY_PASS)
    return (u <> "" and p <> "")
end function

function GTV_RegLoadCredentials() as Object
    c = AppConstants()
    u = GTV_RegRead(c.REG_KEY_USER)
    p = GTV_RegRead(c.REG_KEY_PASS)
    if u = "" or p = ""
        return invalid
    end if
    return {username: u, password: p}
end function
If credentials are found, MainScene skips the LoginScreen and starts AuthTask directly with the saved values.

Registry keys

All registry values are stored under the GlobalTV section (REG_SECTION = "GlobalTV").
ConstantKey stringPurpose
REG_KEY_USERusernameSaved username
REG_KEY_PASSpasswordSaved password
REG_KEY_SERVERlastServerLast resolved server URL
REG_KEY_CHANNELlastChannelIndexLast viewed channel index (for resume)

Session re-auth check

After a successful launch, MainScene runs a periodic re-auth check to detect expired or revoked sessions while the app is in use.
SESSION_AUTH_CHECK_MS : 420000   ' 7 minutes
If re-auth fails with a credential or inactive reason code, the user is sent back to the LoginScreen with a pre-populated error notice.

Timeouts and retries

ConstantValueDescription
TIMEOUT_AUTH15000 msMaximum wait time for the auth HTTP response
TIMEOUT_HTTP12000 msGeneral HTTP timeout used for non-auth requests
TIMEOUT_HEALTH2500 msServer ping timeout during server resolution
RETRY_MAX3Maximum retry attempts for network-level failures
SERVER_LAN_FORCE_RETRIES3Number of LAN probe retries before failing over to WAN
The LoginScreen also arms a guard timer to cancel a hung auth attempt. The guard duration is computed as:
function GTV_LoginGuardDurationSeconds() as Integer
    c = AppConstants()
    totalMs = (c.TIMEOUT_HEALTH * (c.SERVER_LAN_FORCE_RETRIES + 1)) + c.TIMEOUT_AUTH + 5000
    if totalMs < 20000 then totalMs = 20000
    return Int((totalMs + 999) / 1000)
end function

Failure classification

GTV_AuthClassifyFailure maps every auth error to one of five integer reason codes. Both AuthTask and PlaylistTask call this function to decide how to present errors to the user and whether to clear credentials.

Reason codes

ConstantValueMeaning
AUTH_REASON_NONE0No failure — auth succeeded
AUTH_REASON_NETWORK_DOWN460Network unavailable or HTTP timeout (code = -1)
AUTH_REASON_CREDENTIALS401Wrong username or password
AUTH_REASON_INACTIVE470Account exists but subscriber is inactive
AUTH_REASON_PASSWORD_CHANGED471Password was changed or session was revoked

Function signature

function GTV_AuthClassifyFailure(
    httpCode      as Integer,
    reasonText    = invalid as Dynamic,
    bodyText      = invalid as Dynamic,
    subscriberActive = invalid as Dynamic
) as Integer
Parameters:
  • httpCode — The HTTP response code. -1 immediately returns AUTH_REASON_NETWORK_DOWN.
  • reasonText — A string hint from the response (e.g. the reason or message field). May be invalid.
  • bodyText — The raw response body string or parsed object. The function extracts signal text from nested JSON keys (message, reason, error, detail, status, user_inactive_reason, subscriberDisabledReason).
  • subscriberActive — Boolean hint from a parsed subscriber status field. If explicitly false, returns AUTH_REASON_INACTIVE.

Classification logic

function GTV_AuthClassifyFailure(httpCode as Integer, reasonText = invalid as Dynamic, bodyText = invalid as Dynamic, subscriberActive = invalid as Dynamic) as Integer
    c = AppConstants()

    if httpCode = -1
        return c.AUTH_REASON_NETWORK_DOWN
    end if

    signal = GTV_AuthToText(reasonText)
    signal = GTV_AuthConcatSignal(signal, GTV_AuthToText(bodyText))
    signal = GTV_AuthConcatSignal(signal, GTV_AuthExtractSignalFromBody(bodyText))
    signal = GTV_AuthNormalizeSignal(signal)

    if GTV_AuthLooksInactive(signal, subscriberActive)
        return c.AUTH_REASON_INACTIVE
    end if

    if GTV_AuthLooksCredentialFailure(signal)
        return c.AUTH_REASON_CREDENTIALS
    end if

    if GTV_AuthLooksPasswordChanged(signal)
        return c.AUTH_REASON_PASSWORD_CHANGED
    end if

    if httpCode = 401 or httpCode = 403 or httpCode = 404
        return c.AUTH_REASON_CREDENTIALS
    end if

    return c.AUTH_REASON_NONE
end function
Signal text is Unicode-normalized (accented characters stripped) and lowercased before pattern matching, so Spanish and English error messages from the backend are handled identically.

How LoginScreen reacts to each code

CodeUI behavior
AUTH_REASON_CREDENTIALSClears the password field, focuses password input, shows error message
AUTH_REASON_PASSWORD_CHANGEDClears the password field, focuses password input, shows error message
AUTH_REASON_INACTIVEClears the password field, focuses the login button, shows error message
AUTH_REASON_NETWORK_DOWNShows the server timeout error, focuses the login button
AUTH_REASON_NONE (unexpected)Shows generic error, focuses the login button