Members

(static, constant) QC_FAIL_DISABLED

The server says Quick Connect is switched off. Actionable: stop trying here.

Default Value
  • disabled

(static, constant) QC_FAIL_SPENT

The secret is unknown, expired, or already spent. Actionable: get a new code.

Default Value
  • spent

(static, constant) QC_FAIL_UNAVAILABLE

The server is starting or temporarily down. Actionable: try again shortly.

Default Value
  • unavailable

(static, constant) QC_MAX_CONSECUTIVE_FAILURES

How many CONSECUTIVE failed polls end the session.

Not a deadline on the flow — a live-but-unapproved code polls indefinitely on purpose, because the only thing that has to happen is the user walking to another device, and the dialog's Cancel button is the way out of that. This is the tolerance for a transient blip: one dropped request on Wi-Fi must not kill a sign-in that is otherwise fine, and a server that has genuinely stopped answering must not spin forever.

HOW LONG THAT IS DEPENDS ON HOW THE POLLS FAIL, and the two bounds are an order of magnitude apart. Failures that come back immediately (connection refused) give up in ~6s — three polls separated by two 3s timer gaps. Failures that are TIMEOUTS give up in ~42s, because apiPromise allows each request timeouts.API_WAIT_MS (12s) before it rejects. The second number is the one to hold in mind: a server that has stopped answering rather than refusing is exactly the case this cap exists for, and the user watches a code dialog with no feedback for the whole of it.

Default Value
  • 3

(static, constant) QC_POLL_APPROVED

Outcomes of one poll. Strings rather than an enum because they cross into a component field and are read in log lines; the set is closed and asserted.

Default Value
  • approved

(static, constant) QC_POLL_EXPIRED

Default Value
  • expired

(static, constant) QC_POLL_FAILED

Default Value
  • failed

(static, constant) QC_POLL_PENDING

Default Value
  • pending

Methods

(static) quickConnectExchangeFailure(res) → {string}

Why did /Users/AuthenticateWithQuickConnect refuse?

The spec declares only 400 Missing token (plus 503 from 10.11.0), but a live 10.11.11 answered 404 for a secret it had not seen approved — an UNDECLARED code. So this deliberately does not enumerate: anything that is not the transient 503 means the secret cannot be exchanged, and the user needs a new code rather than an explanation of which 4xx it was.

Parameters:
NameTypeDescription
resdynamic
Returns:
Type: 
string

(static) quickConnectHasSession(json) → {boolean}

Does an /Users/AuthenticateWithQuickConnect response carry a session the app can actually finish signing in with?

A 200 IS NOT A SESSION. The exchange can answer OK with a body naming neither a token nor a user, and the coordinator that receives it has nowhere to report that — by then the code dialog is gone and the intent has drained, so the user answers the save-credentials question and then gets no screen and no message. UserSelect is the last point in the flow still on a screen that can say something, which is why this is checked there and not only downstream.

The fields are the ones the DOWNSTREAM chain requires, not a plausible subset. User.Id is load-bearing and easy to under-check: UserData.loadFromJSON reads json.User.id directly, user.Login() refuses a payload whose User carries no Id (session.bs hasValidId) — and loginRouter calls finishLogin() whether or not Login took, so a missing Id lands on Home with nobody signed in. Guarding only AccessToken + User would move that failure rather than close it.

userDataFromAuthResult (source/api/userAuth.bs) guards the same payload one layer down, on the main thread, for the node it builds. Keep the two in step.

Parameters:
NameTypeDescription
jsondynamic

the parsed AuthenticationResult, or invalid

Returns:

true only when a sign-in can actually complete from this payload

Type: 
boolean

(static) quickConnectInitiateFailure(res) → {string}

Why did /QuickConnect/Initiate refuse?

401 Quick connect is not active on this server is the ONLY code that means the feature is off, and it means that on every version 10.7.0 -> 10.11.8. 503 The server is currently starting or is temporarily not available was added at 10.11.0 and is TRANSIENT — reporting it as "disabled" would tell a user whose server is still booting to give up on a feature that works.

Everything else is treated as not-reachable rather than not-available, which is the safe direction: it invites a retry instead of closing the door.

Parameters:
NameTypeDescription
resdynamic
Returns:
Type: 
string

(static) quickConnectPollOutcome(res) → {string}

Classify one /QuickConnect/Connect response.

res is the pool response AA — { ok, statusCode, json, text } — or invalid for a transport failure / timeout (the .catch side of the promise contract), which is a failure like any other non-answer.

Parameters:
NameTypeDescription
resdynamic
Returns:
Type: 
string

(static) quickConnectSession(json) → {dynamic}

Pull the two fields the flow needs out of a /QuickConnect/Initiate response.

Returns invalid unless BOTH are present and non-empty: the Secret is what every later request is keyed on, and the Code is the only thing the user can act on, so a response missing either cannot start a session. (The old sync path checked only the Secret, and would have opened a dialog showing an empty code.)

Parameters:
NameTypeDescription
jsondynamic

the parsed QuickConnectResult, or invalid

Returns:

an AA of { secret, code }, or invalid

Type: 
dynamic

(static) quickConnectShouldGiveUp(consecutiveFailures) → {boolean}

Should the dialog stop polling after this many consecutive failures?

Parameters:
NameTypeDescription
consecutiveFailuresinteger
Returns:
Type: 
boolean

(static) spokenQuickConnectCode(code) → {string}

The code as the screen reader should SAY it: one digit at a time.

A Quick Connect code is a string the listener has to transcribe onto another device, and "523522" has two plausible pronunciations — six digits, or "five hundred twenty-three thousand five hundred twenty-two". Only one of those is usable, and a space-separated form has exactly that one on any engine, so this is a choice about ambiguity rather than a guess about Roku's synthesiser. (The unspaced rendering has not been listened to on device; it does not need to be, because the spaced form is correct either way.)

Only the SPOKEN form is spaced. The code stays intact on screen, where the user is reading it rather than hearing it.

Parameters:
NameTypeDescription
codestring
Returns:
Type: 
string