AppSurface Search
API Reference

Push

Type

AppSurfaceWebPushReadinessProvider

Source

Builds privacy-safe PWA push readiness evidence from validated package configuration.

Type

AppSurfaceWebPushServiceCollectionExtensions

Source

Registers the optional AppSurface Web Push safe rail.

Method

AddAppSurfaceWebPush

IServiceCollection AddAppSurfaceWebPush(this IServiceCollection services, Action<AppSurfaceWebPushOptions> configure)

Registers Web Push with host-owned VAPID keys and exact push-service origins.

Parameters

  • services
    The host service collection.
  • configure
    The host-owned key ring and exact-origin configuration.

Returns

The same service collection for chaining.

Remarks

This method maps no route and does not enable the shared PWA worker. The host must separately enable WebOptions.Pwa.Push.Enabled , register IAppSurfaceWebPushSubscriptionCustody , and call one explicit protected mapping method. Calling this method also registers one singleton IPwaPushReadinessProvider for Web's additive PWA diagnostics contract. The provider exposes only the active safe key identifier, a SHA-256 public-key fingerprint, and the synchronized route-mapped bit; it never exposes key material, route values, or subscription data. Options are validated during host startup; incomplete keys, non-canonical origins, and mismatched key pairs fail startup.

Method

AddAppSurfaceWebPushDevelopmentProofTransport

IServiceCollection AddAppSurfaceWebPushDevelopmentProofTransport(this IServiceCollection services, IHostEnvironment environment)

Replaces network transport with a deterministic HTTP 201 proof transport in Development only.

Parameters

  • services
    The host service collection after AddAppSurfaceWebPush(IServiceCollection, Action{AppSurfaceWebPushOptions}) .
  • environment
    The current host environment, which must be Development.

Returns

The same service collection for chaining.

Exceptions

  • ArgumentNullException
    A required argument is null.
  • InvalidOperationException
    The environment is not Development.

Remarks

This seam exists only for canonical examples and local integration proofs. It still runs the package sender, encryption, validation, and response classifier, but it performs no network request and proves no delivery. Never register it in staging or production.

Type

AppSurfaceWebPushClientAsset

Source

Serves the package-owned browser client from one fixed app-root-relative path.

Remarks

Map the Web Push rail on the application-root endpoint builder so route-group prefixes cannot move this asset. The embedded resource is required package content; failure to locate it is a packaging error.

Method

WriteAsync

Task WriteAsync(HttpContext context)

Writes the JavaScript response, or headers only for a HEAD request.

Parameters

  • context
    The active request context. Request cancellation stops body transmission.

Remarks

A matching v query value enables immutable caching. Missing or stale versions use no-cache . The response always applies JavaScript content type and nosniff headers.

Property

Version

string Version { get; } Source

Gets the first 16 lowercase hexadecimal characters of the embedded asset SHA-256 hash.

Remarks

The version is suitable for cache busting; it is not a package or API version.

Type

IAppSurfaceWebPushBearerTokenValidator

Source

Validates one bearer token for the antiforgery-free Web Push subscription rail.

Remarks

The package extracts the token from a syntactically valid HTTP Authorization: Bearer header and supplies only the token value. Implementations should validate issuer, audience, signature, lifetime, and any app-specific revocation requirements, then return an authenticated principal or null . They must not fall back to cookies, ambient request identities, or other credentials. Bearer tokens are sensitive and must not be logged. Register exactly one implementation before mapping bearer subscription endpoints.

Method

ValidateAsync

ValueTask<ClaimsPrincipal?> ValidateAsync(string bearerToken, CancellationToken cancellationToken = default)

Validates a bearer token and returns its authenticated principal when accepted.

Parameters

  • bearerToken
    The nonblank token value extracted from the Authorization header.
  • cancellationToken
    Cancels validation when the request is aborted.

Returns

An authenticated principal when accepted; otherwise null .

Exceptions

  • OperationCanceledException
    The request is canceled.
Type

AppSurfaceWebPushEndpointRouteBuilderExtensions

Source

Maps the explicit protected AppSurface Web Push subscription rail.

Method

MapAppSurfaceWebPushSubscriptions

void MapAppSurfaceWebPushSubscriptions(this IEndpointRouteBuilder endpoints, string path, string authorizationPolicy, string? rateLimiterPolicy = null)

Maps cookie-authenticated subscription endpoints with package-owned antiforgery validation.

Parameters

  • endpoints
    The application-root endpoint route builder. Route groups are rejected because they would move the package's fixed client asset.
  • path
    The literal app-root-relative base path for configuration, PUT, and DELETE. Route parameters, catch-alls, and traversal segments are not supported.
  • authorizationPolicy
    The nonblank host-owned named policy, including exactly one cookie authentication scheme, evaluated directly inside every handler.
  • rateLimiterPolicy
    An optional host-owned named rate-limiter policy applied to every protected endpoint.

Exceptions

  • ArgumentException
    The builder is a route group, or the path, authorization policy, or supplied rate-limiter policy is blank, unsafe, or inside AppSurface's reserved route space.
  • InvalidOperationException
    The same package base path was already mapped.

Remarks

Mapping is explicit and returns no convention builder, so callers cannot disable the package-owned security contract. Authorization is evaluated before VAPID configuration, antiforgery, parsing, or custody access.

Method

MapAppSurfaceWebPushBearerSubscriptions

void MapAppSurfaceWebPushBearerSubscriptions(this IEndpointRouteBuilder endpoints, string path, string authorizationPolicy, string? rateLimiterPolicy = null)

Maps token-only subscription endpoints using the app's registered bearer-token validator.

Parameters

  • endpoints
    The application-root endpoint route builder. Route groups are rejected because they would move the package's fixed client asset.
  • path
    The literal app-root-relative base path for configuration, PUT, and DELETE. Route parameters, catch-alls, and traversal segments are not supported.
  • authorizationPolicy
    The nonblank host-owned named policy evaluated directly inside every handler.
  • rateLimiterPolicy
    An optional host-owned named rate-limiter policy applied to every protected endpoint.

Exceptions

  • ArgumentException
    The builder is a route group, or the path, authorization policy, or supplied rate-limiter policy is blank, unsafe, or inside AppSurface's reserved route space.
  • InvalidOperationException
    The same package base path was already mapped.

Remarks

Register exactly one IAppSurfaceWebPushBearerTokenValidator . Requests must carry a nonblank HTTP Authorization: Bearer credential. The package passes only that token to the validator and ignores ambient identities and authentication schemes. A missing, rejecting, or failing validator fails closed.

Type

AppSurfaceWebPushRouteRegistry

Source

Coordinates route claims across repeated package mapping calls in one application.

Remarks

Claims are synchronized and compared case-insensitively to match ASP.NET Core route behavior.

Method

Claim

bool Claim(string path)

Claims one base path and reports whether this caller owns the one-time client asset mapping.

Parameters

  • path
    The previously validated literal base path.

Returns

true only for the first successful claim in the application.

Exceptions

  • InvalidOperationException
    The path was already claimed, including with different casing.
Property

IsMapped

bool IsMapped { get; } Source

Gets whether at least one package-owned Web Push route has been mapped.

Type

AppSurfaceWebPushSubscription

Source

Contains one sensitive browser push subscription snapshot.

Property

Endpoint

string Endpoint { get; } Source

Gets the sensitive push-service endpoint.

Property

P256Dh

string P256Dh { get; } Source

Gets the sensitive browser P-256 Diffie-Hellman public key.

Property

Auth

string Auth { get; } Source

Gets the sensitive browser authentication secret.

Property

VapidKeyId

string VapidKeyId { get; } Source

Gets the safe retained VAPID key identifier.

Type

AppSurfaceWebPushSubscriptionReference

Source

Identifies a sensitive browser subscription for an app-owned unregister operation.

Property

Endpoint

string Endpoint { get; } Source

Gets the sensitive push-service endpoint.

Type

AppSurfaceWebPushSubscriptionWriteContext

Source

Provides the authenticated principal to app-owned subscription custody.

Property

Principal

ClaimsPrincipal Principal { get; } Source

Gets the authenticated principal. The host derives its own user and tenant keys.

Type

IAppSurfaceWebPushSubscriptionCustody

Source

Stores subscriptions and conditionally marks complete snapshots terminal.

Method

RegisterAsync

ValueTask<AppSurfaceWebPushRegistrationDisposition> RegisterAsync(AppSurfaceWebPushSubscriptionWriteContext context, AppSurfaceWebPushSubscription subscription, CancellationToken cancellationToken)

Idempotently registers or refreshes a subscription for the authenticated principal.

Parameters

  • context
    The authenticated write context.
  • subscription
    The complete validated subscription snapshot.
  • cancellationToken
    Cancels app-owned custody work.

Returns

A disposition that distinguishes create, update, no-op, ownership conflict, and policy rejection.

Method

UnregisterAsync

ValueTask<AppSurfaceWebPushUnregistrationDisposition> UnregisterAsync(AppSurfaceWebPushSubscriptionWriteContext context, AppSurfaceWebPushSubscriptionReference subscription, CancellationToken cancellationToken)

Idempotently unregisters a subscription for the authenticated principal.

Parameters

  • context
    The authenticated write context.
  • subscription
    The endpoint reference to remove.
  • cancellationToken
    Cancels app-owned custody work.

Returns

A disposition that distinguishes removal, absence, ownership conflict, and policy rejection.

Method

MarkTerminalAsync

ValueTask<AppSurfaceWebPushTerminalDisposition> MarkTerminalAsync(AppSurfaceWebPushSubscription subscription, AppSurfaceWebPushTerminalReason reason, CancellationToken cancellationToken)

Compares and marks the complete subscription snapshot terminal. Implementations must not retire a replacement subscription that happens to reuse the same endpoint.

Parameters

  • subscription
    The complete snapshot that received a terminal push-service response.
  • reason
    The safe terminal reason.
  • cancellationToken
    Bounds cleanup independently from the caller's send token.

Returns

A compare-and-mark disposition; replacement records must produce AppSurfaceWebPushTerminalDisposition.AlreadyTerminal .

Type

AppSurfaceWebPushOptions

Source

Configures the active VAPID key ring and the exact push-service origins an AppSurface host permits.

Property

ActiveVapidKeyId

string? ActiveVapidKeyId { get; set; } Source

Gets or sets the safe identifier used for newly created browser subscriptions.

Remarks

Defaults to null . The value must match a retained VapidKeys entry and use the documented safe-ID alphabet. Startup validation fails closed until an active key is configured.

Property

VapidKeys

IDictionary<string, AppSurfaceWebPushVapidKeyOptions> VapidKeys { get; } Source

Gets the bounded VAPID key ring. Retain old keys while stored subscriptions still reference them.

Remarks

The collection starts empty and must contain 1 through 8 valid entries. Add the new key before changing ActiveVapidKeyId , then retain older entries until no stored subscription references them.

Property

AllowedPushServiceOrigins

ISet<string> AllowedPushServiceOrigins { get; } Source

Gets the exact normalized HTTPS origins allowed to receive push requests, for example https://updates.push.services.mozilla.com . Wildcards and custom ports are rejected.

Remarks

The collection starts empty and must contain 1 through 16 canonical default-port origins. Startup validation and delivery fail closed when the allowlist is empty or invalid.

Type

AppSurfaceWebPushVapidKeyOptions

Source

Configures one retained VAPID signing key pair.

Remarks

The private key is sensitive. Store it in user-secrets or a production secret provider.

Property

Subject

string? Subject { get; set; } Source

Gets or sets the RFC 8292 contact subject, as a mailto: or HTTPS URI.

Property

PublicKey

string? PublicKey { get; set; } Source

Gets or sets the canonical unpadded base64url P-256 public key.

Property

PrivateKey

string? PrivateKey { get; set; } Source

Gets or sets the canonical unpadded base64url P-256 private key.

Type

AppSurfaceWebPushValidation

Source

Provides package-internal canonical validation for configuration, routes, and browser subscription material.

Remarks

Validation methods return false for malformed external input and never echo secret key material.

Method

IsSafeKeyId

bool IsSafeKeyId(string? value)

Determines whether a key identifier uses 1 through 64 safe ASCII characters and begins alphanumerically.

Parameters

  • value
    The candidate identifier.

Returns

true when the identifier is safe for diagnostics and lookup.

Method

TryDecodeCanonicalBase64Url

bool TryDecodeCanonicalBase64Url(string? value, int expectedLength, out byte[] decoded)

Decodes a canonical unpadded base64url value with an exact decoded length.

Parameters

  • value
    The candidate base64url text. Padding and noncanonical encodings are rejected.
  • expectedLength
    The required decoded byte count.
  • decoded
    Receives decoded bytes on success, or an empty array on failure.

Returns

true only when decoding, length, alphabet, and canonical round-trip checks pass.

Method

IsValidP256PublicKey

bool IsValidP256PublicKey(string? value)

Determines whether a value is a canonical uncompressed NIST P-256 public point.

Parameters

  • value
    The 65-byte uncompressed point encoded as canonical unpadded base64url.

Returns

true when the runtime accepts the point on NIST P-256.

Method

IsMatchingVapidPair

bool IsMatchingVapidPair(string? publicKey, string? privateKey)

Determines whether canonical P-256 public and private VAPID keys form one key pair.

Parameters

  • publicKey
    The 65-byte uncompressed public point encoded as canonical base64url.
  • privateKey
    The 32-byte private scalar encoded as canonical base64url.

Returns

true when the derived public coordinates match in fixed time.

Method

IsValidSubject

bool IsValidSubject(string? value)

Determines whether a VAPID subject is a canonical contact mailto: or HTTPS URI.

Parameters

  • value
    The candidate contact URI.

Returns

true when the value contains no whitespace, user-info, fragment, or unsupported scheme.

Method

TryNormalizeAllowedOrigin

bool TryNormalizeAllowedOrigin(string? value, out string origin)

Normalizes and validates one exact HTTPS default-port push-service origin.

Parameters

  • value
    The candidate origin without credentials, path, query, fragment, wildcard, or custom port.
  • origin
    Receives the canonical authority on success, or an empty string on failure.

Returns

true only when the input already equals its canonical origin.

Method

TryValidateEndpoint

bool TryValidateEndpoint(string? value, ISet<string> allowedOrigins, out string origin)

Validates a push subscription endpoint against the exact allowed-origin set.

Parameters

  • value
    The absolute HTTPS default-port endpoint, limited to 4,096 characters.
  • allowedOrigins
    Canonical origins accepted by the host.
  • origin
    Receives the endpoint authority when its URL shape is valid, even if it is not allowed.

Returns

true when the endpoint shape is valid and its authority is allowlisted.

Method

IsValidAssetPath

bool IsValidAssetPath(string? value)

Determines whether a local asset path is literal, app-root-relative, and free of query or traversal syntax.

Parameters

  • value
    The candidate path.

Returns

true when raw and repeatedly decoded forms remain safe.

Method

IsValidDestinationPath

bool IsValidDestinationPath(string? value)

Determines whether a local destination path is safe, allowing at most one query separator.

Parameters

  • value
    The candidate path and optional query.

Returns

true when raw and repeatedly decoded path forms remain app-root-relative and traversal-free.

Method

IsValidTopic

bool IsValidTopic(string? value)

Determines whether an optional Web Push topic uses 1 through 32 URL-safe characters.

Parameters

  • value
    The topic, or null when no topic is requested.

Returns

true for a missing or valid topic.

Method

Base64UrlEncode

string Base64UrlEncode(ReadOnlySpan<byte> value)

Encodes bytes as canonical unpadded base64url text.

Parameters

  • value
    The bytes to encode.

Returns

The canonical base64url representation without padding.

Type

AppSurfaceWebPushOptionsValidator

Source

Validates the bounded VAPID key ring and exact push-service origin allowlist at startup.

Type

AppSurfaceWebPushClientTagHelper

Source

Renders the CSP-compatible versioned AppSurface Web Push browser client script.

Property

ViewContext

Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; } Source

Gets or sets the current Razor view context.

Type

AppSurfaceWebPushNotification

Source

Contains a bounded payload matching AppSurface Web's PWA worker schema version 1.

Property

Title

string Title { get; } Source

Gets the required 1-256 character title.

Property

Body

string? Body { get; } Source

Gets the optional 1-2048 character body.

Property

IconPath

string? IconPath { get; } Source

Gets the optional app-root-relative icon path.

Property

BadgePath

string? BadgePath { get; } Source

Gets the optional app-root-relative badge path.

Property

Tag

string? Tag { get; } Source

Gets the optional 1-128 character notification tag.

Property

DestinationPath

string? DestinationPath { get; } Source

Gets the optional app-root-relative click destination, which may include one query string.

Type

AppSurfaceWebPushSendOptions

Source

Configures one push-service attempt.

Property

TimeToLiveSeconds

int TimeToLiveSeconds { get; } Source

Gets the required retention time in seconds.

Property

Urgency

AppSurfaceWebPushUrgency Urgency { get; } Source

Gets the push urgency.

Property

Topic

string? Topic { get; } Source

Gets the optional 1-32 character URL-safe collapse topic.

Type

AppSurfaceWebPushSendRequest

Source

Contains one immutable, sensitive single-recipient send request.

Property

Subscription

AppSurfaceWebPushSubscription Subscription { get; } Source

Gets the complete subscription snapshot.

Property

Notification

AppSurfaceWebPushNotification Notification { get; } Source

Gets the bounded worker payload.

Property

Options

AppSurfaceWebPushSendOptions Options { get; } Source

Gets the one-attempt transport options.

Type

IAppSurfaceWebPushSender

Source

Sends a single Web Push notification without retrying.

Method

SendAsync

ValueTask<AppSurfaceWebPushSendResult> SendAsync(AppSurfaceWebPushSendRequest request, CancellationToken cancellationToken = default)

Performs at most one push-service request. AppSurfaceWebPushSendOutcome.Accepted proves only an RFC 8030 201 Created response; it does not prove browser delivery or display. Caller cancellation propagates. Terminal cleanup uses an independent hard five-second bound and is reported in the safe result rather than extending the caller's request indefinitely.

Parameters

  • request
    The validated-at-send, single-recipient request.
  • cancellationToken
    Cancels the push-service attempt.

Returns

A safe classification containing no subscription, payload, token, body, or exception data.

Exceptions

  • ArgumentException
    A request field is invalid or the encoded payload exceeds its bound.
  • OperationCanceledException
    The caller cancels the push-service attempt.
Type

AppSurfaceWebPushSendResult

Source

Contains safe send classification without endpoint, key, payload, token, body, or exception data.

Property

Outcome

AppSurfaceWebPushSendOutcome Outcome { get; } Source

Gets the safe send outcome.

Property

CleanupState

AppSurfaceWebPushCleanupState CleanupState { get; } Source

Gets the terminal cleanup state.

Property

StatusCode

int? StatusCode { get; } Source

Gets the push-service HTTP status, when a response was observed.

Property

RetryAfter

TimeSpan? RetryAfter { get; } Source

Gets a safe nonnegative Retry-After delay when supplied by the push service.

Property

ReasonCode

string ReasonCode { get; } Source

Gets the stable safe reason code.

Property

VapidKeyId

string VapidKeyId { get; } Source

Gets the safe configured VAPID key identifier.

Enum

AppSurfaceWebPushRegistrationDisposition

Source

Describes an app-owned registration result.

Enum

AppSurfaceWebPushUnregistrationDisposition

Source

Describes an app-owned unregister result.

Enum

AppSurfaceWebPushTerminalDisposition

Source

Describes compare-and-mark terminal cleanup.

Enum

AppSurfaceWebPushTerminalReason

Source

Identifies the terminal push-service response.

Enum

AppSurfaceWebPushUrgency

Source

Defines Web Push urgency.

Enum

AppSurfaceWebPushSendOutcome

Source

Classifies the safe result of one send attempt.

Enum

AppSurfaceWebPushCleanupState

Source

Classifies conditional terminal cleanup.