dvKioskRouteRedirect function
Where a running kiosk sends path, or null to let it through.
routes.allow was parsed, scanned by doctor for sensitive fields behind
allowed routes, and given a diagnostic code for a route being blocked --
and nothing blocked one. A kiosk declaring allow: [/welcome, /order/**]
served /admin to anyone who could ask for it, and the specification is
explicit about who can: deep links, notifications and OS intents are
honoured only within the allow list, and a link on one of the kiosk's own
pages is the shortest route of all.
The attract route is never redirected, even when the list forgets to include it. Home redirecting to home is a loop rather than a wrong page, and a router gives up on it with a redirect-limit error on the one screen the kiosk always has to be able to show.
Null when no kiosk holds and in staff mode, where the rest of the policy lifts too: an engineer standing at the machine with the exit method needs the pages the queue must not reach. Reported when it blocks one, rather than blocking in silence.
DVKioskDegradation.routeBlocked was declared with a code of its own and
assigned nowhere, so the one thing this function exists to do was the one
thing a kiosk could not say it had done. A deep link, a notification or a
stale link on an attract screen all arrive here, and a screen that
answered with the home page told whoever was watching nothing about why.
At debug, which is what the registry says DV-KIOSK-006 is: a kiosk
refusing a route it was told to refuse is ordinary, and every navigation
passes through this gate.
Implementation
String? dvKioskRouteRedirect(String path) {
final DVKioskPolicy? policy = _holding;
if (policy == null) return null;
final String route = path.split('?').first.split('#').first;
if (route == policy.home) return null;
if (policy.allowsRoute(route)) return null;
DVObservability.log(
'Kiosk blocked $route; sent to ${policy.home}.',
level: DVLogLevel.debug,
code: DVKioskDegradation.routeBlocked.code,
context: <String, Object?>{'route': route, 'home': policy.home},
);
return policy.home;
}