feat(leptos): always expose use_nonce()

This commit is contained in:
Marcus Ofenhed
2026-07-10 17:52:29 +00:00
committed by GitHub
parent 595edbba6e
commit f81ffcd5fc
3 changed files with 28 additions and 29 deletions

View File

@@ -166,12 +166,10 @@ pub mod prelude {
// In the future, maybe we should remove this blanket export
// However, it is definitely useful relative to looking up every struct etc.
mod export_types {
#[cfg(feature = "nonce")]
pub use crate::nonce::*;
pub use crate::{
callback::*, children::*, component::*, control_flow::*, error::*,
form::*, hydration::*, into_view::*, mount::*, suspense::*,
text_prop::*,
form::*, hydration::*, into_view::*, mount::*, nonce::*,
suspense::*, text_prop::*,
};
pub use leptos_config::*;
pub use leptos_dom::helpers::*;
@@ -241,7 +239,6 @@ pub mod portal;
pub mod hydration;
/// Utilities for exporting nonces to be used for a Content Security Policy.
#[cfg(feature = "nonce")]
pub mod nonce;
/// Components to load asynchronous data.

View File

@@ -1,10 +1,4 @@
use crate::context::{provide_context, use_context};
use base64::{
alphabet,
engine::{self, general_purpose},
Engine,
};
use rand::{rng, RngCore};
use crate::context::use_context;
use std::{fmt::Display, ops::Deref, sync::Arc};
use tachys::html::attribute::AttributeValue;
@@ -127,6 +121,9 @@ impl AttributeValue for Nonce {
/// server response. This can be added to inline `<script>` and
/// `<style>` tags for compatibility with a Content Security Policy.
///
/// This function can be called without the `nonce` feature enabled,
/// in which case it will always return [`None::<Nonce>`].
///
/// ```rust,ignore
/// #[component]
/// pub fn App() -> impl IntoView {
@@ -156,21 +153,33 @@ impl AttributeValue for Nonce {
/// }
/// }
/// ```
#[inline(always)]
pub fn use_nonce() -> Option<Nonce> {
use_context::<Nonce>()
cfg!(feature = "nonce").then(use_context).flatten()
}
/// Generates a nonce and provides it via context.
#[cfg(feature = "nonce")]
pub fn provide_nonce() {
provide_context(Nonce::new())
crate::context::provide_context(Nonce::new())
}
const NONCE_ENGINE: engine::GeneralPurpose =
engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD);
#[cfg(feature = "nonce")]
impl Nonce {
/// Generates a new nonce from 16 bytes (128 bits) of random data.
pub fn new() -> Self {
use base64::{
alphabet,
engine::{self, general_purpose},
Engine as _,
};
use rand::{rng, RngCore as _};
const NONCE_ENGINE: engine::GeneralPurpose =
engine::GeneralPurpose::new(
&alphabet::URL_SAFE,
general_purpose::NO_PAD,
);
let mut rng = rng();
let mut bytes = [0; 16];
rng.fill_bytes(&mut bytes);
@@ -188,6 +197,7 @@ impl Nonce {
}
}
#[cfg(feature = "nonce")]
impl Default for Nonce {
fn default() -> Self {
Self::new()

View File

@@ -47,6 +47,7 @@ use leptos::{
attr::{any_attribute::AnyAttribute, NextAttribute},
component,
logging::debug_warn,
nonce::use_nonce,
oco::Oco,
reactive::owner::{provide_context, use_context},
tachys::{
@@ -595,18 +596,9 @@ pub(crate) trait OrDefaultNonce {
impl OrDefaultNonce for Option<Oco<'static, str>> {
fn or_default_nonce(self) -> Option<Oco<'static, str>> {
#[cfg(feature = "nonce")]
{
use leptos::nonce::use_nonce;
match self {
Some(nonce) => Some(nonce),
None => use_nonce().map(|n| Arc::clone(n.as_inner()).into()),
}
}
#[cfg(not(feature = "nonce"))]
{
self
match self {
Some(nonce) => Some(nonce),
None => use_nonce().map(|n| Arc::clone(n.as_inner()).into()),
}
}
}