NavigationUrlPolicy
in package
Server-side scheme allowlist for stored external links (user profile, company reference, blog intro panel, article, menu item).
Latte 3 runs href="{$x}" through checkUrl and blanks javascript: and data: schemes, but
that only mitigates at render time (it does not apply outside an attribute context, nor to
values sent out through Api JSON). The authoritative gate therefore belongs here, before
persistence. Modeled on ReturnUrlPolicy, a different domain (a navigation link to click,
not an HTTP redirect).
Rule (positive allowlist, not a scheme deny-list):
- an absolute URL
http://orhttps://(case-insensitive scheme) with a non-empty host and no credentials (user:pass@host), mailto:andtel:with non-empty content after the colon,- for fields where a relative value makes sense (internal menu, anchor in text) also a relative
path starting with exactly one
/(not//host, not/\host) and#anchor.
Anything else (javascript:, data:, vbscript:, file:, a schemeless evil.example where
no relative path is allowed, control characters including CR/LF, a backslash, inner spaces) is
rejected: the caller either does not store the value (form rule) or refuses the save (Api
beforeSave()).
Table of Contents
Constants
- ADMIN_MESSAGE : string = '//admin.general.navigationUrl'
- Global message key (admin); same trick as {@see \App\Core\Forms\StrictDateInput}.
- ADMIN_MESSAGE_RELATIVE : string = '//admin.general.navigationUrlRelative'
- Message key for fields that also allow a link to this site (`/path`, `#anchor`), admin.
- FRONT_MESSAGE : string = '//front.general.navigationUrl'
- Global message key (front); `front.general` speaks to the visitor.
Methods
- isAllowed() : bool
- rule() : BaseControl
- Server-side rule for a Nette form. An empty value passes (optional field); required-ness is the caller's `setRequired()`, as with {@see \App\Core\Forms\StrictDateInput}.
- rules() : void
- Batch variant of {@see rule()} for several fields at once (e.g. `link_<langId>` per language).
- isAllowedAbsolute() : bool
- isValidOrEmpty() : bool
Constants
ADMIN_MESSAGE
Global message key (admin); same trick as {@see \App\Core\Forms\StrictDateInput}.
public
string
ADMIN_MESSAGE
= '//admin.general.navigationUrl'
ADMIN_MESSAGE_RELATIVE
Message key for fields that also allow a link to this site (`/path`, `#anchor`), admin.
public
string
ADMIN_MESSAGE_RELATIVE
= '//admin.general.navigationUrlRelative'
FRONT_MESSAGE
Global message key (front); `front.general` speaks to the visitor.
public
string
FRONT_MESSAGE
= '//front.general.navigationUrl'
Methods
isAllowed()
public
static isAllowed(mixed $url, bool $allowRelative) : bool
Parameters
- $url : mixed
- $allowRelative : bool
Return values
boolrule()
Server-side rule for a Nette form. An empty value passes (optional field); required-ness is the caller's `setRequired()`, as with {@see \App\Core\Forms\StrictDateInput}.
public
static rule(BaseControl $control, bool $allowRelative[, string|null $message = null ]) : BaseControl
Parameters
- $control : BaseControl
- $allowRelative : bool
- $message : string|null = null
Return values
BaseControlrules()
Batch variant of {@see rule()} for several fields at once (e.g. `link_<langId>` per language).
public
static rules(Container $container, array<int, string> $names, bool $allowRelative[, string|null $message = null ]) : void
A missing control is skipped (fields are sometimes built conditionally).
Parameters
- $container : Container
- $names : array<int, string>
- $allowRelative : bool
- $message : string|null = null
isAllowedAbsolute()
private
static isAllowedAbsolute(string $url) : bool
Parameters
- $url : string
Return values
boolisValidOrEmpty()
private
static isValidOrEmpty(mixed $value, bool $allowRelative) : bool
Parameters
- $value : mixed
- $allowRelative : bool