diff --git a/Cargo.lock b/Cargo.lock index b1be8960..da95abf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common 0.1.6", + "generic-array 0.14.9", +] + [[package]] name = "aead" version = "0.6.1" @@ -15,7 +25,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ "crypto-common 0.2.2", - "inout", + "inout 0.2.2", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures 0.2.17", ] [[package]] @@ -24,23 +45,37 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138" dependencies = [ - "cipher", + "cipher 0.5.2", "cpubits", "cpufeatures 0.3.0", "zeroize", ] +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead 0.5.2", + "aes 0.8.4", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash 0.5.1", + "subtle", +] + [[package]] name = "aes-gcm" version = "0.11.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da8c919c118108f144adecad74b425b804ad075580d605d9b33c2d6d1c62a2f8" dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", + "aead 0.6.1", + "aes 0.9.1", + "cipher 0.5.2", + "ctr 0.10.1", + "ghash 0.6.0", "subtle", "zeroize", ] @@ -453,6 +488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", + "axum-macros", "base64", "bytes", "form_urlencoded", @@ -501,6 +537,40 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-extra" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96" +dependencies = [ + "axum", + "axum-core", + "bytes", + "cookie", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "serde_core", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa268c23bfbbd2c4363b9cd302a4f504fb2a9dfe7e3451d66f35dd392e20aca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "base-x" version = "0.2.11" @@ -666,7 +736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62ce3946557b35e71d1bbe07ec385073ce9eda05043f95de134eb578fcf1a298" dependencies = [ "byteorder", - "cipher", + "cipher 0.5.2", ] [[package]] @@ -915,6 +985,7 @@ name = "bobbin-xrpc" version = "0.0.1" dependencies = [ "axum", + "base64", "bobbin-edge-index", "bobbin-knot-proxy", "bobbin-record-lru", @@ -926,9 +997,11 @@ dependencies = [ "chrono", "futures", "http", + "jacquard-axum", "jacquard-common", "jacquard-identity", "reqwest 0.13.1", + "scc", "serde", "serde_json", "thiserror 2.0.18", @@ -1061,7 +1134,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce2dc9ee5f88d11e0beb842c88b33c8a5cf0d1329c4b19494af42b07dbfe8896" dependencies = [ - "cipher", + "cipher 0.5.2", ] [[package]] @@ -1134,7 +1207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" dependencies = [ "cfg-if", - "cipher", + "cipher 0.5.2", "cpufeatures 0.3.0", "rand_core 0.10.1", "zeroize", @@ -1194,6 +1267,16 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common 0.1.6", + "inout 0.1.4", +] + [[package]] name = "cipher" version = "0.5.2" @@ -1202,7 +1285,7 @@ checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ "block-buffer 0.12.1", "crypto-common 0.2.2", - "inout", + "inout 0.2.2", "zeroize", ] @@ -1372,6 +1455,21 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "aes-gcm 0.10.3", + "base64", + "percent-encoding", + "rand 0.8.6", + "subtle", + "time", + "version_check", +] + [[package]] name = "cordyceps" version = "0.3.4" @@ -1556,6 +1654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array 0.14.9", + "rand_core 0.6.4", "typenum", ] @@ -1580,13 +1679,22 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + [[package]] name = "ctr" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21" dependencies = [ - "cipher", + "cipher 0.5.2", ] [[package]] @@ -1599,6 +1707,22 @@ dependencies = [ "subtle", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto 0.2.9", + "rustc_version", + "subtle", + "zeroize", +] + [[package]] name = "curve25519-dalek" version = "5.0.0-rc.0" @@ -1609,7 +1733,7 @@ dependencies = [ "cpufeatures 0.3.0", "curve25519-dalek-derive", "digest 0.11.3", - "fiat-crypto", + "fiat-crypto 0.3.0", "rustc_version", "subtle", "zeroize", @@ -1853,7 +1977,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "916a94e407b54f9034d71dd748234cd1e516ced6284009906ae246f177eafe5a" dependencies = [ - "cipher", + "cipher 0.5.2", ] [[package]] @@ -1963,6 +2087,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature 2.2.0", +] + [[package]] name = "ed25519" version = "3.0.0" @@ -1973,14 +2107,29 @@ dependencies = [ "signature 3.0.0", ] +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", + "rand_core 0.6.4", + "serde", + "sha2 0.10.9", + "subtle", + "zeroize", +] + [[package]] name = "ed25519-dalek" version = "3.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b011170fe4f04665565b4110afef66774fe9ffff278f3eb5b81cc73d26e27d60" dependencies = [ - "curve25519-dalek", - "ed25519", + "curve25519-dalek 5.0.0-rc.0", + "ed25519 3.0.0", "rand_core 0.10.1", "serde", "sha2 0.11.0", @@ -2007,6 +2156,7 @@ dependencies = [ "ff 0.13.1", "generic-array 0.14.9", "group 0.13.0", + "hkdf 0.12.4", "pem-rfc7468 0.7.0", "pkcs8 0.10.2", "rand_core 0.6.4", @@ -2027,7 +2177,7 @@ dependencies = [ "digest 0.11.3", "ff 0.14.0", "group 0.14.0", - "hkdf", + "hkdf 0.13.0", "hybrid-array", "once_cell", "pem-rfc7468 1.0.0", @@ -2185,6 +2335,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "fiat-crypto" version = "0.3.0" @@ -2288,6 +2444,16 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + [[package]] name = "futures" version = "0.3.32" @@ -2512,13 +2678,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval 0.6.2", +] + [[package]] name = "ghash" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" dependencies = [ - "polyval", + "polyval 0.7.1", ] [[package]] @@ -3439,6 +3615,34 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "gloo-storage" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" +dependencies = [ + "gloo-utils", + "js-sys", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "governor" version = "0.10.4" @@ -3705,6 +3909,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + [[package]] name = "hkdf" version = "0.13.0" @@ -3732,6 +3945,20 @@ dependencies = [ "digest 0.11.3", ] +[[package]] +name = "html5ever" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 2.0.118", +] + [[package]] name = "htmlescape" version = "0.3.1" @@ -4015,6 +4242,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array 0.14.9", +] + [[package]] name = "inout" version = "0.2.2" @@ -4116,6 +4352,76 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jacquard" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5055461df426c9d0ac379bcf8f59177ff4c29b4ea2b23bd98c773061b863bbe" +dependencies = [ + "bytes", + "getrandom 0.2.17", + "gloo-storage", + "http", + "jacquard-api", + "jacquard-common", + "jacquard-identity", + "jacquard-oauth", + "jose-jwk", + "miette", + "regex", + "regex-lite", + "reqwest 0.12.28", + "serde", + "serde_html_form", + "serde_json", + "smol_str", + "thiserror 2.0.18", + "tokio", + "trait-variant", + "webpage", +] + +[[package]] +name = "jacquard-api" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c803a3c097e3ef8aea63747b4fe3fc9e339cd18272dd0366b1d10dd90d5c3f" +dependencies = [ + "jacquard-common", + "jacquard-derive", + "jacquard-lexicon", + "miette", + "serde", + "thiserror 2.0.18", +] + +[[package]] +name = "jacquard-axum" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4fa141b5bc2c34a4070cdab72b93b605f3a452e7e6663920e7c6a87925cd5ee" +dependencies = [ + "axum", + "axum-extra", + "base64", + "bytes", + "chrono", + "jacquard", + "jacquard-common", + "jacquard-derive", + "jacquard-identity", + "miette", + "mini-moka-wasm", + "multibase", + "serde", + "serde_html_form", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tower-http 0.6.11", + "tracing", +] + [[package]] name = "jacquard-common" version = "0.12.1" @@ -4232,6 +4538,40 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "jacquard-oauth" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5da2643242cbe906e707712117eefcc37b351a5ff12909f944ef556e523bfd9" +dependencies = [ + "base64", + "bytes", + "chrono", + "dashmap", + "ed25519-dalek 2.2.0", + "elliptic-curve 0.13.8", + "http", + "jacquard-common", + "jacquard-identity", + "jose-jwa", + "jose-jwk", + "k256", + "miette", + "p256 0.13.2", + "p384 0.13.1", + "rand 0.8.6", + "reqwest 0.12.28", + "serde", + "serde_html_form", + "serde_json", + "sha2 0.10.9", + "smallvec", + "smol_str", + "thiserror 2.0.18", + "tokio", + "trait-variant", +] + [[package]] name = "jiff" version = "0.2.29" @@ -4328,6 +4668,42 @@ dependencies = [ "libc", ] +[[package]] +name = "jose-b64" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec69375368709666b21c76965ce67549f2d2db7605f1f8707d17c9656801b56" +dependencies = [ + "base64ct", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "jose-jwa" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ab78e053fe886a351d67cf0d194c000f9d0dcb92906eb34d853d7e758a4b3a7" +dependencies = [ + "serde", +] + +[[package]] +name = "jose-jwk" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280fa263807fe0782ecb6f2baadc28dffc04e00558a58e33bfdb801d11fd58e7" +dependencies = [ + "jose-b64", + "jose-jwa", + "p256 0.13.2", + "p384 0.13.1", + "rsa 0.9.10", + "serde", + "zeroize", +] + [[package]] name = "js-sys" version = "0.3.102" @@ -4800,9 +5176,9 @@ dependencies = [ name = "knot-secrets" version = "2.0.0" dependencies = [ - "aes-gcm", + "aes-gcm 0.11.0-rc.4", "base64", - "hkdf", + "hkdf 0.13.0", "k256", "knot-resource", "knot-runtime", @@ -5035,6 +5411,9 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] [[package]] name = "levenshtein_automata" @@ -5048,6 +5427,12 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + [[package]] name = "libsqlite3-sys" version = "0.36.0" @@ -5135,6 +5520,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef0d4ed8669f8f8826eb00dc878084aa8f253506c4fd5e8f58f5bce72ddb97e" +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + [[package]] name = "maitake-sync" version = "0.1.2" @@ -5148,6 +5539,32 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "markup5ever" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +dependencies = [ + "log", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "markup5ever_rcdom" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edaa21ab3701bfee5099ade5f7e1f84553fd19228cf332f13cd6e964bf59be18" +dependencies = [ + "html5ever", + "markup5ever", + "tendril", + "xml5ever", +] + [[package]] name = "match-lookup" version = "0.1.2" @@ -5418,6 +5835,12 @@ dependencies = [ "web-time", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.31.3" @@ -5478,6 +5901,22 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.6", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.2.2" @@ -5493,6 +5932,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -5500,6 +5949,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -5554,6 +6004,12 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl-probe" version = "0.2.1" @@ -5621,6 +6077,18 @@ dependencies = [ "sha2 0.11.0", ] +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder 0.13.6", + "sha2 0.10.9", +] + [[package]] name = "p384" version = "0.14.0-rc.10" @@ -5629,7 +6097,7 @@ checksum = "9bd5333afa5ae0347f39e6a0f2c9c155da431583fd71fe5555bd0521b4ccaf02" dependencies = [ "ecdsa 0.17.0-rc.18", "elliptic-curve 0.14.0-rc.33", - "fiat-crypto", + "fiat-crypto 0.3.0", "primefield", "primeorder 0.14.0-rc.10", "sha2 0.11.0", @@ -5798,6 +6266,16 @@ dependencies = [ "phf_shared", ] +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared", +] + [[package]] name = "phf_generator" version = "0.11.3" @@ -5867,6 +6345,17 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", +] + [[package]] name = "pkcs1" version = "0.8.0-rc.4" @@ -5883,7 +6372,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279a91971a1d8eb1260a30938eae3be9cb67b472dffecb222fbbbe2fd2dc1453" dependencies = [ - "aes", + "aes 0.9.1", "cbc", "der 0.8.0", "pbkdf2", @@ -5942,10 +6431,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a00baa632505d05512f48a963e16051c54fda9a95cc9acea1a4e3c90991c4a2e" dependencies = [ "cpufeatures 0.3.0", - "universal-hash", + "universal-hash 0.6.1", "zeroize", ] +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "opaque-debug", + "universal-hash 0.5.1", +] + [[package]] name = "polyval" version = "0.7.1" @@ -5954,7 +6455,7 @@ checksum = "7dfc63250416fea14f5749b90725916a6c903f599d51cb635aa7a52bfd03eede" dependencies = [ "cpubits", "cpufeatures 0.3.0", - "universal-hash", + "universal-hash 0.6.1", ] [[package]] @@ -6009,6 +6510,12 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + [[package]] name = "prettyplease" version = "0.2.37" @@ -6678,6 +7185,26 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid 0.9.6", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1 0.7.5", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "signature 2.2.0", + "spki 0.7.3", + "subtle", + "zeroize", +] + [[package]] name = "rsa" version = "0.10.0-rc.18" @@ -6688,7 +7215,7 @@ dependencies = [ "crypto-bigint 0.7.4", "crypto-primes", "digest 0.11.3", - "pkcs1", + "pkcs1 0.8.0-rc.4", "pkcs8 0.11.0", "rand_core 0.10.1", "sha2 0.11.0", @@ -6728,33 +7255,33 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbf893f64684e58da8a68d56a5e84d1cf0440226274c515770fe267707a7d0b0" dependencies = [ - "aes", + "aes 0.9.1", "aws-lc-rs", "bitflags 2.13.0", "block-padding", "byteorder", "bytes", "cbc", - "cipher", + "cipher 0.5.2", "crypto-bigint 0.7.4", - "ctr", - "curve25519-dalek", + "ctr 0.10.1", + "curve25519-dalek 5.0.0-rc.0", "data-encoding", "delegate", "der 0.8.0", "digest 0.11.3", "ecdsa 0.17.0-rc.18", - "ed25519-dalek", + "ed25519-dalek 3.0.0-rc.0", "elliptic-curve 0.14.0-rc.33", "enum_dispatch", "flate2", "futures", "generic-array 1.4.3", "getrandom 0.4.3", - "ghash", + "ghash 0.6.0", "hex-literal", "hmac 0.13.0", - "inout", + "inout 0.2.2", "internal-russh-num-bigint", "keccak", "log", @@ -6763,17 +7290,17 @@ dependencies = [ "module-lattice", "num-bigint", "p256 0.14.0-rc.10", - "p384", + "p384 0.14.0-rc.10", "p521", "pageant", "pbkdf2", - "pkcs1", + "pkcs1 0.8.0-rc.4", "pkcs5", "pkcs8 0.11.0", - "polyval", + "polyval 0.7.1", "rand 0.10.1", "rand_core 0.10.1", - "rsa", + "rsa 0.10.0-rc.18", "russh-cryptovec", "russh-util", "salsa20", @@ -6790,7 +7317,7 @@ dependencies = [ "thiserror 2.0.18", "tokio", "typenum", - "universal-hash", + "universal-hash 0.6.1", "zeroize", ] @@ -7014,7 +7541,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f874456e72520ff1375a06c588eaf074b0f01f9e9e1aada45bd9b7954a6e42c" dependencies = [ "cfg-if", - "cipher", + "cipher 0.5.2", ] [[package]] @@ -7595,13 +8122,13 @@ version = "0.3.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10db6f219196a8528f9ec904d9d45cdad692d65b0e57e72be4dedd1c5fddce36" dependencies = [ - "aead", - "aes", - "aes-gcm", + "aead 0.6.1", + "aes 0.9.1", + "aes-gcm 0.11.0-rc.4", "cbc", "chacha20", - "cipher", - "ctr", + "cipher 0.5.2", + "ctr 0.10.1", "ctutils", "des", "poly1305", @@ -7633,14 +8160,14 @@ dependencies = [ "argon2", "bcrypt-pbkdf", "ctutils", - "ed25519-dalek", + "ed25519-dalek 3.0.0-rc.0", "hex", "hmac 0.13.0", "p256 0.14.0-rc.10", - "p384", + "p384 0.14.0-rc.10", "p521", "rand_core 0.10.1", - "rsa", + "rsa 0.10.0-rc.18", "sec1 0.8.1", "sha1 0.11.0", "sha2 0.11.0", @@ -7662,6 +8189,31 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + [[package]] name = "strsim" version = "0.11.1" @@ -7915,6 +8467,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + [[package]] name = "terminal_size" version = "0.4.4" @@ -8272,6 +8835,7 @@ dependencies = [ "tower", "tower-layer", "tower-service", + "tracing", "url", ] @@ -8568,6 +9132,16 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common 0.1.6", + "subtle", +] + [[package]] name = "universal-hash" version = "0.6.1" @@ -8816,6 +9390,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpage" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70862efc041d46e6bbaa82bb9c34ae0596d090e86cbd14bd9e93b36ee6802eac" +dependencies = [ + "html5ever", + "markup5ever_rcdom", + "serde_json", + "url", +] + [[package]] name = "webpki-root-certs" version = "1.0.8" @@ -9324,6 +9910,17 @@ dependencies = [ "rustix", ] +[[package]] +name = "xml5ever" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bbb26405d8e919bc1547a5aa9abc95cbfa438f04844f5fdd9dc7596b748bf69" +dependencies = [ + "log", + "mac", + "markup5ever", +] + [[package]] name = "yasna" version = "0.5.2" @@ -9413,6 +10010,7 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" dependencies = [ + "serde", "zeroize_derive", ] diff --git a/Cargo.toml b/Cargo.toml index 95aeecda..af9ff56f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,6 +71,7 @@ knot-maintenance = { path = "knot2/crates/knot-maintenance" } knot-sim = { path = "knot2/crates/knot-sim" } knot-edge = { path = "knot2/crates/knot-edge" } +jacquard-axum = "0.12.1" jacquard-common = "0.12.1" jacquard-derive = "0.12.1" jacquard-lexicon = { version = "0.12.1", default-features = false } @@ -117,7 +118,7 @@ ahash = { version = "0.8", default-features = false, features = ["std"] } arc-swap = "1" reqwest = { version = "0.13", default-features = false, features = ["rustls", "webpki-roots", "http2", "json", "gzip", "stream"] } -axum = "0.8" +axum = { version = "0.8", features = ["macros"] } hyper = { version = "1", features = ["server", "http1", "http2"] } hyper-util = { version = "0.1", features = ["server", "server-auto", "tokio", "service"] } tower = { version = "0.5", features = ["util", "limit", "load-shed"] } diff --git a/bobbin/crates/bobbin/src/main.rs b/bobbin/crates/bobbin/src/main.rs index faf26c07..eb442129 100644 --- a/bobbin/crates/bobbin/src/main.rs +++ b/bobbin/crates/bobbin/src/main.rs @@ -223,6 +223,7 @@ async fn run(cfg: BobbinConfig) -> anyhow::Result<()> { clock.clone(), hasher, )?); + // tracing::info!(audience = %service_auth.audience().as_str(), "service auth enabled"); let search_heap = usize::try_from(search_heap_cap) .with_context(|| format!("search heap {search_heap_cap} exceeds usize"))?; let search = Arc::new(SearchIndex::new(search_heap, clock.clone())?); diff --git a/bobbin/crates/xrpc/Cargo.toml b/bobbin/crates/xrpc/Cargo.toml index cadeb571..215f2220 100644 --- a/bobbin/crates/xrpc/Cargo.toml +++ b/bobbin/crates/xrpc/Cargo.toml @@ -14,6 +14,7 @@ bobbin-runtime = { workspace = true } bobbin-search = { workspace = true } bobbin-slingshot-client = { workspace = true } bobbin-knot-proxy = { workspace = true } +jacquard-axum = { workspace = true } jacquard-common = { workspace = true } jacquard-identity = { workspace = true } @@ -21,6 +22,7 @@ axum = { workspace = true } chrono = { workspace = true } futures = { workspace = true } http = { workspace = true } +scc = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } @@ -31,6 +33,7 @@ url = { workspace = true } reqwest = { workspace = true } [dev-dependencies] +base64 = { workspace = true } bobbin-runtime = { workspace = true } http = { workspace = true } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/bobbin/crates/xrpc/src/feed.rs b/bobbin/crates/xrpc/src/feed.rs index 27049e97..8730eb69 100644 --- a/bobbin/crates/xrpc/src/feed.rs +++ b/bobbin/crates/xrpc/src/feed.rs @@ -12,9 +12,10 @@ use bobbin_types::sh_tangled::feed::get_timeline::{ use bobbin_types::sh_tangled::feed::star::{Star, StarRecord, StarSubject}; use bobbin_types::sh_tangled::graph::follow::{Follow, FollowRecord}; use bobbin_types::sh_tangled::repo::{self, Repo, RepoRecord, RepoViewBasic}; -use jacquard_common::DefaultStr; +use jacquard_axum::service_auth::ExtractOptionalServiceAuth; use jacquard_common::types::string::{AtUri, Datetime, Did, Handle, UriValue}; use jacquard_common::xrpc::XrpcResp; +use jacquard_common::{DefaultStr, IntoStatic as _}; use jacquard_identity::resolver::IdentityResolver; use crate::{ @@ -32,29 +33,30 @@ const HYDRATE_CONCURRENCY: usize = 8; #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub(crate) struct GetTimelineQuery { - viewer: Option>, #[serde(default)] following_only: bool, limit: Option, cursor: Option, } +#[axum::debug_handler] pub(crate) async fn get_timeline( State(state): State, + ExtractOptionalServiceAuth(auth): ExtractOptionalServiceAuth, XrpcQuery(q): XrpcQuery, ) -> Result { let limit = parse_limit(q.limit)?; let cursor = parse_cursor(q.cursor.as_deref())?; let permit = state.heavy_permit()?; - let viewer = q.viewer.as_ref(); + let viewer = auth.as_ref().map(|auth| auth.did().into_static()); // Prepare timeline skeleton let page = if q.following_only { // Following feed: the viewer's followed set, then a time-ordered k-way merge. - let viewer = viewer.ok_or_else(|| { - XrpcError::InvalidParams("followingOnly requires a viewer did".into()) + let viewer = viewer.as_ref().ok_or_else(|| { + XrpcError::AuthRequired("followingOnly requires an authenticated viewer".into()) })?; - let followed = followed_dids(&state, viewer).await; + let followed = followed_dids(&state, &viewer).await; following_skeleton(&state, &followed, cursor, limit) } else { global_skeleton(&state, cursor, limit) @@ -64,7 +66,7 @@ pub(crate) async fn get_timeline( let hydrated = stream::iter( page.items .iter() - .map(|it| hydrate_item(&state, viewer, it)) + .map(|it| hydrate_item(&state, viewer.as_ref(), it)) .collect::>(), ) .buffered(HYDRATE_CONCURRENCY) diff --git a/bobbin/crates/xrpc/src/lib.rs b/bobbin/crates/xrpc/src/lib.rs index db1e9643..71b778ae 100644 --- a/bobbin/crates/xrpc/src/lib.rs +++ b/bobbin/crates/xrpc/src/lib.rs @@ -81,6 +81,7 @@ use bobbin_types::sh_tangled::string::{ }; use futures::Stream; use futures::stream::{self, StreamExt, TryStreamExt}; +use jacquard_axum::service_auth::{self, ServiceAuthConfig}; use jacquard_common::types::did::Did; use jacquard_common::types::ident::AtIdentifier; use jacquard_common::types::nsid::Nsid; @@ -132,6 +133,7 @@ pub struct AppState { pub resolver: Arc, pub directory: Arc, pub limiter: Option>, + service_auth_config: service_auth::ServiceAuthConfig>, enrich_router: Arc>, } @@ -159,8 +161,12 @@ impl AppState { knots, search, resolver, - directory, + directory: directory.clone(), limiter: None, + service_auth_config: ServiceAuthConfig::new( + Did::new_static("did:web:bobbin.tngl.boltless.dev").unwrap(), + directory, + ), enrich_router: Arc::new(std::sync::OnceLock::new()), } } @@ -182,6 +188,29 @@ impl AppState { } } +impl service_auth::ServiceAuth for AppState { + type Resolver = Directory; + + fn service_did(&self) -> Did<&str> { + self.service_auth_config.service_did() + } + fn resolver(&self) -> &Self::Resolver { + self.service_auth_config.resolver() + } + fn require_lxm(&self) -> bool { + service_auth::ServiceAuth::require_lxm(&self.service_auth_config) + } + fn allowed_services(&self) -> &[jacquard_common::SmolStr] { + self.service_auth_config.allowed_services() + } + fn replay_protection_enabled(&self) -> bool { + self.service_auth_config.replay_protection_enabled() + } + fn replay_store(&self) -> &dyn jacquard_axum::service_auth::ReplayStore { + self.service_auth_config.replay_store() + } +} + pub fn router(state: AppState) -> Router { Router::new() .route("/xrpc/sh.tangled.repo.getRepo", get(get_repo)) @@ -740,6 +769,12 @@ where pub enum XrpcError { #[error("invalid request: {0}")] InvalidParams(String), + #[error("authentication required: {0}")] + AuthRequired(String), + // /// A service-auth token failed verification. Typed so the jwt-level checks speak jacquard's + // /// vocabulary; adopting `jacquard-axum` later replaces the producer, not this variant. + // #[error(transparent)] + // Auth(#[from] jacquard_common::service_auth::ServiceAuthError), #[error("record not found")] NotFound, #[error("upstream unavailable: {0}")] @@ -770,6 +805,7 @@ impl IntoResponse for XrpcError { fn into_response(self) -> Response { let (status, error) = match &self { Self::InvalidParams(_) => (StatusCode::BAD_REQUEST, "InvalidRequest"), + Self::AuthRequired(_) => (StatusCode::UNAUTHORIZED, "AuthenticationRequired"), Self::NotFound => (StatusCode::NOT_FOUND, "RecordNotFound"), Self::UpstreamUnavailable(_) => (StatusCode::BAD_GATEWAY, "UpstreamFailed"), Self::UpstreamGone(_) => (StatusCode::BAD_GATEWAY, "UpstreamGone"), @@ -1626,7 +1662,9 @@ fn drop_unhydratable( Ok(None) } }, - Err(err @ (XrpcError::Internal(_) | XrpcError::Overloaded)) => Err(err), + Err( + err @ (XrpcError::Internal(_) | XrpcError::Overloaded | XrpcError::AuthRequired(_)), + ) => Err(err), } }