AppSurface Search
API Reference

Push

Type

AppSurfaceWebPushServiceCollectionExtensions

Source

Registers the optional AppSurface Web Push safe rail.

Method

AddAppSurfaceWebPush

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

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

Parameters

  • servicesThe host service collection.
  • configureThe 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) Source

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

Parameters

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

Returns

The same service collection for chaining.

Exceptions

  • ArgumentNullExceptionA required argument is null.
  • InvalidOperationExceptionThe 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

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) Source

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

Parameters

  • valueThe candidate identifier.

Returns

true when the identifier is safe for diagnostics and lookup.

Method

TryDecodeCanonicalBase64Url

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

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

Parameters

  • valueThe candidate base64url text. Padding and noncanonical encodings are rejected.
  • expectedLengthThe required decoded byte count.
  • decodedReceives 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) Source

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

Parameters

  • valueThe 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) Source

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

Parameters

  • publicKeyThe 65-byte uncompressed public point encoded as canonical base64url.
  • privateKeyThe 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) Source

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

Parameters

  • valueThe 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) Source

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

Parameters

  • valueThe candidate origin without credentials, path, query, fragment, wildcard, or custom port.
  • originReceives 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) Source

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

Parameters

  • valueThe absolute HTTPS default-port endpoint, limited to 4,096 characters.
  • allowedOriginsCanonical origins accepted by the host.
  • originReceives 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) Source

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

Parameters

  • valueThe candidate path.

Returns

true when raw and repeatedly decoded forms remain safe.

Method

IsValidDestinationPath

bool IsValidDestinationPath(string? value) Source

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

Parameters

  • valueThe 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) Source

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

Parameters

  • valueThe topic, or null when no topic is requested.

Returns

true for a missing or valid topic.

Method

Base64UrlEncode

string Base64UrlEncode(ReadOnlySpan<byte> value) Source

Encodes bytes as canonical unpadded base64url text.

Parameters

  • valueThe 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

AppSurfaceWebPushReadinessProvider

Source

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

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

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) Source

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

Parameters

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

Exceptions

  • ArgumentExceptionThe 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.
  • InvalidOperationExceptionThe 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) Source

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

Parameters

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

Exceptions

  • ArgumentExceptionThe 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.
  • InvalidOperationExceptionThe 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) Source

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

Parameters

  • pathThe previously validated literal base path.

Returns

true only for the first successful claim in the application.

Exceptions

  • InvalidOperationExceptionThe 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

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) Source

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

Parameters

  • bearerTokenThe nonblank token value extracted from the Authorization header.
  • cancellationTokenCancels validation when the request is aborted.

Returns

An authenticated principal when accepted; otherwise null.

Exceptions

  • OperationCanceledExceptionThe request is canceled.
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) Source

Idempotently registers or refreshes a subscription for the authenticated principal.

Parameters

  • contextThe authenticated write context.
  • subscriptionThe complete validated subscription snapshot.
  • cancellationTokenCancels 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) Source

Idempotently unregisters a subscription for the authenticated principal.

Parameters

  • contextThe authenticated write context.
  • subscriptionThe endpoint reference to remove.
  • cancellationTokenCancels 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) Source

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

Parameters

  • subscriptionThe complete snapshot that received a terminal push-service response.
  • reasonThe safe terminal reason.
  • cancellationTokenBounds cleanup independently from the caller's send token.

Returns

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

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.

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) Source

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

  • requestThe validated-at-send, single-recipient request.
  • cancellationTokenCancels the push-service attempt.

Returns

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

Exceptions

  • ArgumentExceptionA request field is invalid or the encoded payload exceeds its bound.
  • OperationCanceledExceptionThe 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

AppSurfaceWebPushUrgency

Source

Defines Web Push urgency.

Enum

AppSurfaceWebPushSendOutcome

Source

Classifies the safe result of one send attempt.

Enum

AppSurfaceWebPushCleanupState

Source

Classifies conditional terminal cleanup.

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) Source

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

Parameters

  • contextThe 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.