Skip to main content
Nova Stream is a runnable emulator of a product, not of one mechanism. The scenario samples each show a single thing — a sign-in, a confirmation, a step-up; this one strings them together the way a viewer encounters them on a television: a sign-in, the person’s data, recognition on the next visit and a confirmed purchase. The sample lives in the repository (veriqa.app/source) under samples/dotnet/showcase/streaming-tv and listens on https://localhost:7350. Its README.md is the detailed setup guide; this page is the overview.

What the viewer sees

1

Sign-in by QR code from the sofa

The TV redirects to the Veriqa sign-in page, which shows a QR code. The viewer scans it with their phone camera and confirms in the messenger — nothing is typed with the remote.
2

A welcome card from the channel's claims

The card on screen is built from what the channel provides: display name, first and last name, picture, @username and a masked user id (Telegram), a masked phone (WhatsApp), an address (Email) — Nova Stream asks for the contacts at sign-in. Identifiers are masked on the server; the full value never reaches the browser.
3

A date of birth and a favorite genre inside the sign-in

The Veriqa:ScopesClaims catalog declares both, so Veriqa asks for them on its own form inside the sign-in, and the collected claims store remembers the answer. 18+ titles are closed to a viewer under age, and titles of the favorite genre come first. See Progressive claim enrichment.
4

Recognition of a returning viewer

A first-time viewer is welcomed by name; a viewer who has been here before lands straight in the catalog.
5

Step-up when buying a title

Buying a title shows a QR code and is confirmed in the channel by the viewer who asked. A confirmation from anybody else buys nothing.
The two flows leave different receipts in the chat. A sign-in’s question is replaced by “Sign-in to Nova Stream confirmed ✅” (ReplacePrompt); a purchase keeps its question and gets the receipt as a message of its own (NewMessage, set in the backend client’s entry), so what was confirmed stays readable. See OutcomeNotice in Configuration.

The interface on a television

The interface belongs to the fictional service: a ten-foot layout, remote-control navigation and no interaction that needs a pointer. The sign-in page and the confirmation window are Veriqa’s own screens, shown as they are: the sample names its brand beside the Veriqa mark and adapts the arrangement for a big screen through AuthPageDesign:
  • the television shows the QR codes of all enabled channels side by side — the channel layout is Grid, because nobody walks up to a TV to switch a tab;
  • the “Open in …” buttons appear on a phone only — the visibility of the channel buttons is MobileOnly; a phone that opens the page gets the buttons instead of the QR;
  • the QR of the purchase window is drawn at 12 px per module instead of the default 6, so it scans off the screen from across the room;
  • a stylesheet enlarges the card on screens 1600 CSS pixels wide or wider.
A set of channels per browser language. The sign-in client has two ui_config records that differ in Channels; the sample names one of them in the authorize request by the first language of Accept-Language. A record narrows what the host has enabled — it is presentation, not a restriction.

TV browsers

Everything the page ships targets ES2018 and the CSS of Chromium 68 — the engine of Tizen 5.5 and webOS 5 — with fallbacks for the Chromium 53 of webOS 4.x where a layout depends on it. Newer syntax such as ?. or ?? is a parse error there: the script does not load at all. Nothing is loaded from outside the origin.

How it is built

One process plays three roles; splitting them into separate hosts changes nothing but the addresses. The purchase creates a confirmation that names one expected identity — the identity from the channel the current session came through (expected_identities). The title is bought only when the outcome is confirmed and matched_type is the expected type; another type, declined, expired or failed leave the library unchanged. The server remembers which title a transaction pays for, so no browser can buy one title by confirming another.

Running it

  • .NET SDK 10.0+ and a trusted development certificate (dotnet dev-certs https --trust) — the application calls itself over HTTPS.
  • Enable at least one channel and give it credentials. Channels ship disabled with empty credentials; a Telegram bot token is the shortest path:
Open https://localhost:7350. WhatsApp and Email are switched on the same way, through their sections of appsettings.json. A sign-in page that offers no way in means no channel is enabled.
In Development the sample switches WhatsApp and Email on with placeholder values, only to show what a multi-channel sign-in page looks like. Neither can carry a sign-in through — Telegram is the channel that works.
On a real TV. A television cannot reach localhost: put the sample behind an HTTP tunnel. Nothing in the code changes — the issuer, the redirect URI, the authority and the channels’ public addresses are set to the public host through environment variables, all of them together, and Telegram switches to Webhook mode. The exact list is in the sample’s README; see also Behind a reverse proxy.
A Telegram bot delivers its updates to one webhook address, so with one bot token only one of the two showcase samples can take sign-ins at a time.

Videos

Sign-in on a TV

Sign-in by QR code from the sofa on a real TV, with no keyboard and no typing.

Step-up on a TV

Buying a title, confirmed in the messenger by the signed-in viewer.

See also