Work through the open Dependabot PRs (#663)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-09-15 13:18:54 -07:00
committed by GitHub
co-authored by Claude Opus 5
parent 31d55440c1
commit 3d6c31440c
18 changed files with 1435 additions and 2787 deletions
+9
View File
@@ -7,6 +7,11 @@ updates:
interval: weekly
day: monday
open-pull-requests-limit: 5
ignore:
# 0.8 dropped stateExtensions and updateSchema from the package root and
# exposes no subpath to reach them, which GrpcEditor needs. Unpin once
# that editor moves to the jsonSchema helper.
- dependency-name: codemirror-json-schema
groups:
npm-production:
dependency-type: production
@@ -25,6 +30,10 @@ updates:
interval: weekly
day: monday
open-pull-requests-limit: 5
ignore:
# Held at 11.10.0 to pin what rolldown_resolver ("^11") resolves to; it
# does not build against 11.11. See crates-cli/yaak-cli/Cargo.toml.
- dependency-name: oxc_resolver
groups:
cargo:
patterns:
Generated
+799 -750
View File
File diff suppressed because it is too large Load Diff
+6 -8
View File
@@ -19,7 +19,7 @@
"@codemirror/merge": "^6.11.2",
"@codemirror/search": "^6.5.11",
"@dnd-kit/core": "^6.3.1",
"@gilbarbara/deep-equal": "^0.3.1",
"@gilbarbara/deep-equal": "^0.4.1",
"@lezer/highlight": "^1.1.3",
"@lezer/lr": "^1.3.3",
"@mjackson/multipart-parser": "^0.10.1",
@@ -47,12 +47,12 @@
"eventemitter3": "^5.0.1",
"focus-trap-react": "^11.0.4",
"fuzzbunny": "^1.0.1",
"graphql": "^16.13.1",
"hexy": "^0.3.5",
"graphql": "^17.0.2",
"hexy": "^0.4.0",
"history": "^5.3.0",
"jotai": "^2.18.0",
"jotai-family": "^1.0.1",
"js-md5": "^0.8.3",
"js-md5": "^0.9.2",
"jsonc-parser": "^3.3.1",
"lucide-react": "^0.525.0",
"mime": "^4.0.4",
@@ -93,11 +93,9 @@
"@yaakapp-internal/theme": "^1.0.0",
"@yaakapp-internal/ui": "^1.0.0",
"babel-plugin-react-compiler": "^1.0.0",
"internal-ip": "^8.0.0",
"rollup": "^4.60.3",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.2.9",
"vite-plugin-static-copy": "^3.3.0",
"vite-plugin-svgr": "^4.5.0",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.3.2",
"vite-plugin-static-copy": "^4.1.1",
"vite-plugin-wasm": "^3.5.0",
"vite-plus": "^0.3.0"
}
+57 -6
View File
@@ -1,11 +1,11 @@
// @ts-ignore
import { tanstackRouter } from "@tanstack/router-plugin/vite";
import react from "@vitejs/plugin-react";
import fs from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
import { defineConfig, normalizePath } from "vite-plus";
import { viteStaticCopy } from "vite-plugin-static-copy";
import svgr from "vite-plugin-svgr";
import wasm from "vite-plugin-wasm";
const require = createRequire(import.meta.url);
@@ -46,6 +46,41 @@ function sendServerUrl(): string {
return `http://${dialable}:${port}`;
}
/**
* Fails the build when a copied asset is not where the app fetches it from.
*
* `PdfViewer` and the page head address these by URL, but nothing ties those
* URLs to the copy targets below, and a target that mirrors its source path
* instead of landing at the root still builds cleanly — the miss only shows up
* as a 404 once the app runs.
*/
function verifyServedAssets(expected: string[]) {
let outDir = "";
return {
name: "verify-served-assets",
apply: "build" as const,
configResolved(config: { root: string; build: { outDir: string } }) {
outDir = path.resolve(config.root, config.build.outDir);
},
// After viteStaticCopy, which writes on `writeBundle`.
closeBundle() {
const missing = expected.filter((asset) => {
const full = path.join(outDir, asset);
if (!fs.existsSync(full)) return true;
const stat = fs.statSync(full);
return stat.isDirectory() && fs.readdirSync(full).length === 0;
});
if (missing.length > 0) {
throw new Error(
`Copied assets missing from ${outDir}: ${missing.join(", ")}. ` +
`Every viteStaticCopy target needs to strip its base path, or it lands ` +
`under a copy of the directories it came from instead.`,
);
}
},
};
}
// https://vitejs.dev/config/
export default defineConfig(async () => {
return {
@@ -79,18 +114,34 @@ export default defineConfig(async () => {
generatedRouteTree: "./routeTree.gen.ts",
autoCodeSplitting: true,
}),
svgr(),
react(),
viteStaticCopy({
// v4 matches only files and always mirrors the source tree into the
// output, so every target here needs stripBase to land where it is
// actually served from — without it these end up under a copy of the
// path they came from, and nothing fails until the request 404s.
targets: [
{ src: cMapsDir, dest: "" },
{ src: standardFontsDir, dest: "" },
{ src: `${cMapsDir}/*`, dest: "cmaps", rename: { stripBase: true } },
{
src: `${standardFontsDir}/*`,
dest: "standard_fonts",
rename: { stripBase: true },
},
// `/favicon.ico` is requested by browsers whether or not anything links to it,
// so it is served under that name to keep a 404 out of every console.
{ src: `${iconsDir}/icon.ico`, dest: "", rename: "favicon.ico" },
{ src: `${iconsDir}/128x128.png`, dest: "", rename: "icon-128.png" },
{
src: `${iconsDir}/icon.ico`,
dest: "",
rename: { name: "favicon.ico", stripBase: true },
},
{
src: `${iconsDir}/128x128.png`,
dest: "",
rename: { name: "icon-128.png", stripBase: true },
},
],
}),
verifyServedAssets(["cmaps", "standard_fonts", "favicon.ico", "icon-128.png"]),
],
build: {
target: "esnext",
+1 -1
View File
@@ -31,7 +31,7 @@
"@vitejs/plugin-react": "^6.0.1",
"babel-plugin-react-compiler": "^1.0.0",
"typescript": "^5.8.3",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.2.9",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.3.2",
"vite-plus": "^0.3.0"
}
}
+3
View File
@@ -24,6 +24,9 @@ log = { workspace = true }
rand = "0.8"
reqwest = { workspace = true, features = ["form"] }
rolldown = "0.1.0"
# Pinned exactly: rolldown_resolver takes `oxc_resolver = "^11"`, so cargo
# drifts it forward and breaks on 11.11 (TsconfigOptions became
# TsconfigDiscovery). This dep exists only to hold that resolution.
oxc_resolver = "=11.10.0"
schemars = { workspace = true }
serde = { workspace = true }
+1 -1
View File
@@ -7,7 +7,7 @@ publish = false
[dependencies]
base32 = "0.5.1" # For encoding human-readable key
base64 = "0.22.1" # For encoding in the database
chacha20poly1305 = "0.10.1"
chacha20poly1305 = "0.11.0"
keyring = { workspace = true, features = ["apple-native", "windows-native", "sync-secret-service"] }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
+34 -13
View File
@@ -1,14 +1,14 @@
use crate::error::Error::{DecryptionError, EncryptionError, InvalidEncryptedData};
use crate::error::Result;
use chacha20poly1305::aead::generic_array::typenum::Unsigned;
use chacha20poly1305::aead::{Aead, AeadCore, Key, KeyInit, OsRng};
use chacha20poly1305::XChaCha20Poly1305;
use chacha20poly1305::aead::array::typenum::Unsigned;
use chacha20poly1305::aead::{Aead, AeadCore, Generate, Key, KeyInit};
use chacha20poly1305::{XChaCha20Poly1305, XNonce};
const ENCRYPTION_TAG: &str = "yA4k3nC";
const ENCRYPTION_VERSION: u8 = 1;
pub(crate) fn encrypt_data(data: &[u8], key: &Key<XChaCha20Poly1305>) -> Result<Vec<u8>> {
let nonce = XChaCha20Poly1305::generate_nonce(&mut OsRng);
let nonce = XNonce::generate();
let cipher = XChaCha20Poly1305::new(&key);
let ciphered_data = cipher.encrypt(&nonce, data).map_err(|_| EncryptionError)?;
@@ -34,11 +34,12 @@ pub(crate) fn decrypt_data(cipher_data: &[u8], key: &Key<XChaCha20Poly1305>) ->
return Err(InvalidEncryptedData);
}
let nonce_bytes = <XChaCha20Poly1305 as AeadCore>::NonceSize::to_usize();
let nonce_bytes = <XChaCha20Poly1305 as AeadCore>::NonceSize::USIZE;
let (nonce, ciphered_data) = rest.split_at_checked(nonce_bytes).ok_or(InvalidEncryptedData)?;
let nonce: &XNonce = nonce.try_into().map_err(|_| InvalidEncryptedData)?;
let cipher = XChaCha20Poly1305::new(&key);
cipher.decrypt(nonce.into(), ciphered_data).map_err(|_e| DecryptionError)
cipher.decrypt(nonce, ciphered_data).map_err(|_e| DecryptionError)
}
#[cfg(test)]
@@ -46,12 +47,12 @@ mod test {
use crate::encryption::{decrypt_data, encrypt_data};
use crate::error::Error::InvalidEncryptedData;
use crate::error::Result;
use chacha20poly1305::aead::OsRng;
use chacha20poly1305::{KeyInit, XChaCha20Poly1305};
use chacha20poly1305::aead::{Generate, Key};
use chacha20poly1305::XChaCha20Poly1305;
#[test]
fn test_encrypt_decrypt() -> Result<()> {
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
let encrypted = encrypt_data("hello world".as_bytes(), &key)?;
let decrypted = decrypt_data(encrypted.as_slice(), &key)?;
assert_eq!(String::from_utf8(decrypted).unwrap(), "hello world");
@@ -60,7 +61,7 @@ mod test {
#[test]
fn test_decrypt_empty() -> Result<()> {
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
let encrypted = encrypt_data(&[], &key)?;
assert_eq!(encrypted.len(), 48);
let decrypted = decrypt_data(encrypted.as_slice(), &key)?;
@@ -70,7 +71,7 @@ mod test {
#[test]
fn test_decrypt_bad_version() -> Result<()> {
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
let mut encrypted = encrypt_data("hello world".as_bytes(), &key)?;
encrypted[7] = 0;
let decrypted = decrypt_data(encrypted.as_slice(), &key);
@@ -80,7 +81,7 @@ mod test {
#[test]
fn test_decrypt_bad_tag() -> Result<()> {
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
let mut encrypted = encrypt_data("hello world".as_bytes(), &key)?;
encrypted[0] = 2;
let decrypted = decrypt_data(encrypted.as_slice(), &key);
@@ -90,9 +91,29 @@ mod test {
#[test]
fn test_decrypt_unencrypted_data() -> Result<()> {
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
let decrypted = decrypt_data("123".as_bytes(), &key);
assert!(matches!(decrypted, Err(InvalidEncryptedData)));
Ok(())
}
}
#[cfg(test)]
mod compatibility {
use super::*;
/// Produced by chacha20poly1305 0.10.1. Decrypting it here proves a crate
/// upgrade hasn't changed the on-disk format, which users already have
/// rows of in their databases.
const V1_FROM_0_10: &str = "7941346b336e43017c7cb13467eecaa963b11734be636f9cc4152de348584fb27e95d1a70973e557cd335cf29e12d0d305d63ca0aa168f1b17003b1690a9d49140f0";
#[test]
fn decrypts_data_written_by_the_previous_release() {
let bytes: Vec<u8> = (0..V1_FROM_0_10.len())
.step_by(2)
.map(|i| u8::from_str_radix(&V1_FROM_0_10[i..i + 2], 16).unwrap())
.collect();
let key = Key::<XChaCha20Poly1305>::from([7u8; 32]);
assert_eq!(decrypt_data(&bytes, &key).unwrap(), b"yaak golden vector");
}
}
+5 -6
View File
@@ -2,7 +2,7 @@ use crate::encryption::{decrypt_data, encrypt_data};
use crate::error::Error::GenericError;
use crate::error::Result;
use base32::Alphabet;
use chacha20poly1305::aead::{Key, KeyInit, OsRng};
use chacha20poly1305::aead::{Generate, Key};
use chacha20poly1305::XChaCha20Poly1305;
use keyring::{Entry, Error};
use log::info;
@@ -24,11 +24,12 @@ impl MasterKey {
let without_prefix = encoded.strip_prefix(HUMAN_PREFIX).unwrap_or(&encoded);
let key_bytes = base32::decode(Alphabet::Crockford {}, &without_prefix)
.ok_or(GenericError("Failed to decode master key".to_string()))?;
Key::<XChaCha20Poly1305>::clone_from_slice(key_bytes.as_slice())
Key::<XChaCha20Poly1305>::try_from(key_bytes.as_slice())
.map_err(|_| GenericError("Master key is the wrong length".to_string()))?
}
Err(Error::NoEntry) => {
info!("Creating new master key");
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
let encoded = base32::encode(Alphabet::Crockford {}, key.as_slice());
let with_prefix = format!("{HUMAN_PREFIX}{encoded}");
entry.set_password(&with_prefix)?;
@@ -50,9 +51,7 @@ impl MasterKey {
#[cfg(test)]
pub(crate) fn test_key() -> Self {
let key: Key<XChaCha20Poly1305> = Key::<XChaCha20Poly1305>::clone_from_slice(
"00000000000000000000000000000000".as_bytes(),
);
let key = Key::<XChaCha20Poly1305>::from(*b"00000000000000000000000000000000");
Self { key }
}
}
+5 -3
View File
@@ -2,7 +2,7 @@ use crate::encryption::{decrypt_data, encrypt_data};
use crate::error::Error::InvalidHumanKey;
use crate::error::Result;
use base32::Alphabet;
use chacha20poly1305::aead::{Key, KeyInit, OsRng};
use chacha20poly1305::aead::{Generate, Key};
use chacha20poly1305::{KeySizeUser, XChaCha20Poly1305};
#[derive(Debug, Clone)]
@@ -39,7 +39,9 @@ impl WorkspaceKey {
}
pub(crate) fn from_raw_key(key: &[u8]) -> Self {
Self { key: Key::<XChaCha20Poly1305>::clone_from_slice(key) }
Self {
key: Key::<XChaCha20Poly1305>::try_from(key).expect("workspace key must be 32 bytes"),
}
}
pub(crate) fn raw_key(&self) -> &[u8] {
@@ -47,7 +49,7 @@ impl WorkspaceKey {
}
pub(crate) fn create() -> Result<Self> {
let key = XChaCha20Poly1305::generate_key(OsRng);
let key = Key::<XChaCha20Poly1305>::generate();
Ok(Self::from_raw_key(key.as_slice()))
}
+5 -5
View File
@@ -13,15 +13,15 @@ hyper-rustls = { version = "0.27.7", default-features = false, features = ["http
hyper-util = { version = "0.1.13", default-features = false, features = ["client-legacy"] }
log = { workspace = true }
md5 = "0.7.0"
prost = "0.13.4"
prost-reflect = { version = "0.14.4", default-features = false, features = ["serde", "derive"] }
prost-types = "0.13.4"
prost = "0.14.4"
prost-reflect = { version = "0.16.5", default-features = false, features = ["serde", "derive"] }
prost-types = "0.14.4"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs", "process"] }
tokio-stream = "0.1.14"
tonic = { version = "0.12.3", default-features = false, features = ["transport"] }
tonic-reflection = "0.12.3"
tonic = { version = "0.14.6", default-features = false, features = ["transport"] }
tonic-reflection = "0.14.6"
uuid = { version = "1.7.0", features = ["v4"] }
yaak-common = { workspace = true }
yaak-tls = { workspace = true }
+2 -2
View File
@@ -10,7 +10,7 @@ use log::debug;
use std::collections::BTreeMap;
use tokio_stream::StreamExt;
use tonic::Request;
use tonic::body::BoxBody;
use tonic::body::Body;
use tonic::transport::Uri;
use tonic_reflection::pb::v1::server_reflection_request::MessageRequest;
use tonic_reflection::pb::v1::server_reflection_response::MessageResponse;
@@ -22,7 +22,7 @@ use tonic_reflection::pb::v1::{ExtensionRequest, FileDescriptorResponse};
use tonic_reflection::pb::{v1, v1alpha};
use yaak_tls::ClientCertificateConfig;
pub struct AutoReflectionClient<T = Client<HttpsConnector<HttpConnector>, BoxBody>> {
pub struct AutoReflectionClient<T = Client<HttpsConnector<HttpConnector>, Body>> {
use_v1alpha: bool,
client_v1: v1::server_reflection_client::ServerReflectionClient<T>,
client_v1alpha: v1alpha::server_reflection_client::ServerReflectionClient<T>,
+4 -4
View File
@@ -27,7 +27,7 @@ use std::sync::Arc;
use tokio::sync::RwLock;
use tokio_stream::StreamExt;
use tokio_stream::wrappers::ReceiverStream;
use tonic::body::BoxBody;
use tonic::body::Body;
use tonic::metadata::{MetadataKey, MetadataValue};
use tonic::transport::Uri;
use tonic::{IntoRequest, IntoStreamingRequest, Request, Response, Status, Streaming};
@@ -36,7 +36,7 @@ use yaak_tls::ClientCertificateConfig;
#[derive(Clone)]
pub struct GrpcConnection {
pool: Arc<RwLock<DescriptorPool>>,
conn: Client<HttpsConnector<HttpConnector>, BoxBody>,
conn: Client<HttpsConnector<HttpConnector>, Body>,
pub uri: Uri,
use_reflection: bool,
max_message_size: usize,
@@ -338,10 +338,10 @@ impl GrpcConnection {
}
fn grpc_client(
conn: Client<HttpsConnector<HttpConnector>, BoxBody>,
conn: Client<HttpsConnector<HttpConnector>, Body>,
uri: Uri,
max_message_size: usize,
) -> tonic::client::Grpc<Client<HttpsConnector<HttpConnector>, BoxBody>> {
) -> tonic::client::Grpc<Client<HttpsConnector<HttpConnector>, Body>> {
tonic::client::Grpc::with_origin(conn, uri)
.max_decoding_message_size(max_message_size)
.max_encoding_message_size(max_message_size)
+2 -2
View File
@@ -4,7 +4,7 @@ use hyper_util::client::legacy::Client;
use hyper_util::client::legacy::connect::HttpConnector;
use hyper_util::rt::TokioExecutor;
use log::info;
use tonic::body::BoxBody;
use tonic::body::Body;
use yaak_tls::{ClientCertificateConfig, get_tls_config};
// I think ALPN breaks this because we're specifying http2_only
@@ -13,7 +13,7 @@ const WITH_ALPN: bool = false;
pub(crate) fn get_transport(
validate_certificates: bool,
client_cert: Option<ClientCertificateConfig>,
) -> Result<Client<HttpsConnector<HttpConnector>, BoxBody>> {
) -> Result<Client<HttpsConnector<HttpConnector>, Body>> {
let tls_config = get_tls_config(validate_certificates, WITH_ALPN, client_cert.clone())?;
let mut http = HttpConnector::new();
+498 -1982
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -135,7 +135,7 @@
"tailwindcss": "^4.3.2",
"tar": "^7.5.22",
"typescript": "^5.8.3",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.2.9",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.3.2",
"vite-plus": "^0.3.0",
"vitest": "^4.1.10",
"yauzl": "^3.4.0"
@@ -144,7 +144,7 @@
"@vitest/mocker": "^4.1.11",
"js-yaml": "^4.3.1",
"underscore": "^1.13.8",
"vite": "npm:@voidzero-dev/vite-plus-core@^0.2.9"
"vite": "npm:@voidzero-dev/vite-plus-core@^0.3.2"
},
"packageManager": "npm@11.11.1"
}
+1 -1
View File
@@ -14,7 +14,7 @@
"dev": "yaakcli dev"
},
"dependencies": {
"@hono/mcp": "^0.2.3",
"@hono/mcp": "^0.3.2",
"@hono/node-server": "^2.0.10",
"@modelcontextprotocol/sdk": "^1.26.0",
"hono": "^4.13.5",
@@ -11,7 +11,7 @@
"dev": "yaakcli dev"
},
"dependencies": {
"@1password/sdk": "^0.4.0-beta.2"
"@1password/sdk": "^0.5.0"
},
"devDependencies": {
"cpx2": "^9.0.0"