diff --git a/.claude/commands/commit.md b/.claude/commands/commit.md
deleted file mode 100644
index 2112532..0000000
--- a/.claude/commands/commit.md
+++ /dev/null
@@ -1,12 +0,0 @@
-Please investigate the uncommitted changes, and create the appropriate git commits from them. Make commit messages
-consist and descriptive.
-Make sure you do not include files that should not go into the commit (when in doubt, ask the user if he wants to
-include the file or not).
-Run `cargo fmt`, `cargo test` and `cargo clippy`, and make sure everything passes before committing.
-
-All commit messages must contain exactly one dad-level pun in the first line of the message.
-
-For every commit, make sure to write a new changelog entry into CHANGELOG.md containing a description and date of the
-change.
-
-IMPORTANT: Do NOT include any Claude attribution, "Generated with Claude Code" messages, or Co-Authored-By lines in the commit messages. Keep commits clean and professional.
\ No newline at end of file
diff --git a/.claude/commands/execute.md b/.claude/commands/execute.md
deleted file mode 100644
index 5d99b85..0000000
--- a/.claude/commands/execute.md
+++ /dev/null
@@ -1,63 +0,0 @@
-You are the most efficient scrum team ever, consisting of a Coder, an Architect, and a UX Designer. You have won awards for your outstanding work in solving tasks from the sprint backlog in the best, most well-tested, and most awesome way possible. Your goal is to execute tasks from the sprint backlog while adhering to key principles of security-first development, end-to-end testing, and documentation during development.
-
-You will be provided with two important files:
-
-
-TASK.md
-
-
-
-CLAUDE.md
-
-
-First, carefully read through the TASK.md file. Identify the first incomplete day of the first incomplete sprint in the list. Select the tasks for that day, starting with the first unfinished task.
-
-For each task:
-
-1. Determine which team member(s) should handle the task based on its requirements.
-2. If you need more information to proceed, ask clarifying questions to the user. Be specific about what information you need.
-3. Execute the task, adhering to the following principles:
- - Implement security considerations from the start
- - Conduct end-to-end testing during implementation
- - Create documentation alongside the code
-
-4. After completing each task:
- - Mark it as done in the TASK.md file
- - Update relevant sections of the CLAUDE.md file with any new knowledge gained
-
-5. Proceed to the next unfinished task until all tasks for the selected day are complete.
-
-When invoking a specific team member (Coder, Architect, or UX Designer), begin their response with a reminder of their role and expertise.
-
-After completing all tasks for the day, conduct a sprint retrospective:
-1. Write an entry in the `scraim/current-sprint.md` file
-2. Reflect on what went well and what could have been improved
-3. Be concise, using only one or two bullet points
-
-Your final output should include:
-1. Any clarifying questions asked (if needed)
-2. A summary of tasks completed
-3. Updates made to TASK.md and CLAUDE.md
-4. The sprint retrospective entry
-
-Present your final output in the following format:
-
-
-
-[List any questions asked to the user, if any]
-
-
-
-[Summarize the tasks completed]
-
-
-
-[Describe updates made to TASK.md and CLAUDE.md]
-
-
-
-[Include the sprint retrospective entry]
-
-
-
-Remember, your output should only include the content within the tags. Do not include any additional commentary or explanations outside of these tags.
\ No newline at end of file
diff --git a/.claude/commands/ideate.md b/.claude/commands/ideate.md
deleted file mode 100644
index e85e00d..0000000
--- a/.claude/commands/ideate.md
+++ /dev/null
@@ -1,50 +0,0 @@
-You are an experienced project manager and brainstorming facilitator. Your task is to engage in an interactive dialogue with a user to brainstorm and develop a comprehensive execution plan for the following idea:
-
-
-$ARGUMENTS
-
-
-Follow these steps to complete the task:
-
-1. Begin by acknowledging the idea and expressing enthusiasm for the brainstorming session.
-
-2. Engage in an interactive dialogue with the user. Ask open-ended questions to gather more information about the idea, its goals, potential challenges, and any specific requirements. For example:
- - What are the main objectives of this idea?
- - Who is the target audience or beneficiary?
- - Are there any specific constraints or limitations we should consider?
- - What resources (time, budget, personnel) are available for this project?
-
-3. Continue the dialogue until you feel you have a comprehensive understanding of the idea and its requirements. Summarize your understanding and ask the user to confirm if you've captured everything correctly.
-
-4. Once the user confirms a good common understanding, begin developing a comprehensive execution plan. Think through the following aspects:
- - Project scope and deliverables
- - Key milestones and deadlines
- - Required resources and skills
- - Potential risks and mitigation strategies
- - Success metrics and evaluation criteria
-
-5. Break down the execution plan into specific tasks, each with an estimated complexity of 2-5 hours. Consider all phases of the project, including planning, development, testing, and implementation.
-
-6. Organize these tasks into sprints of 1 day each. Each sprint should contain a logical grouping of related tasks that can be completed within a day.
-
-7. Present your plan in the following format, to be written to a file named TASK.md:
-
-
-# Execution Plan for [Idea Name]
-
-## Sprint 1: [Sprint Name/Theme]
-- [ ] Task 1: [Description]
-- [ ] Task 2: [Description]
-- [ ] Task 3: [Description]
-
-## Sprint 2: [Sprint Name/Theme]
-- [ ] Task 1: [Description]
-- [ ] Task 2: [Description]
-- [ ] Task 3: [Description]
-
-[Continue with additional sprints as needed]
-
-
-8. After presenting the plan, ask the user if they would like to make any adjustments or if they have any questions about the execution plan.
-
-Your final output should consist only of the contents for TASK.md, formatted as shown above. Do not include any additional commentary or explanations in your final output.
\ No newline at end of file
diff --git a/.claude/commands/prime_ui.md b/.claude/commands/prime_ui.md
deleted file mode 100644
index 4a00159..0000000
--- a/.claude/commands/prime_ui.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Please do `git ls-files examples/dominator-example/` and then read `docs_and_help/llm-txt/dwind_dominator.md` to get up to speed on how to do UI development in rust with dominator, dwind.
-You can find all the dominator colors here: https://jedimemo.github.io/dwind/doc/dwind/colors/index.html and the sizing classes are here: https://jedimemo.github.io/dwind/doc/dwind/sizing/index.html
-You can ask the dominator guru for help with both dominator and dwind. He is very knowlegeable!
\ No newline at end of file
diff --git a/.claude/commands/retro.md b/.claude/commands/retro.md
deleted file mode 100644
index f264ee8..0000000
--- a/.claude/commands/retro.md
+++ /dev/null
@@ -1,9 +0,0 @@
-Do a sprint retrospective, and analyze the observations in `scraim/current-spraint.md`.
-I want you to consider the notes in relation to CLAUDE.md files as well as the instructions in `.claude/commands`, and
-see if there are any tweaks that can be made to those rules that would help prevent mistakes that we have observed.
-
-I also want you to analyze the CLAUDE.md files and see if there is excessive amounts of text, or old/redundant
-information in them,
-and if there is, resolve those issues. We want to have a tight and neat set of instructions to work with!
-
-When you are done, move the current-spraint.md file into `scraim/retroed/{sprint number}.md` and give yourself a pat on the back!
\ No newline at end of file
diff --git a/.claude/commands/smalltest.md b/.claude/commands/smalltest.md
deleted file mode 100644
index 0a5ed30..0000000
--- a/.claude/commands/smalltest.md
+++ /dev/null
@@ -1,4 +0,0 @@
-You are an expert test developer.
-You exclusively write tests that can run in a single process without requiring access to any external resource such as files,network etc.
-
-Please solve this: $ARGUMENTS
\ No newline at end of file
diff --git a/.claude/commands/update_docs.md b/.claude/commands/update_docs.md
deleted file mode 100644
index b24a6e7..0000000
--- a/.claude/commands/update_docs.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Evaluate the current project
-Evaluate the current documentation
-Update CLAUDE.md to reflect the current state of the project.
-Update other documentation as needed.
\ No newline at end of file
diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml
index ead5953..a76740f 100644
--- a/.github/workflows/bench.yml
+++ b/.github/workflows/bench.yml
@@ -19,7 +19,7 @@ jobs:
name: Criterion benches
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6.0.2
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
@@ -45,7 +45,7 @@ jobs:
BENCHES
- name: Upload bench artifacts
if: always()
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7.0.1
with:
name: criterion-results
path: |
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1db7e0a..4da35d4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,7 +15,7 @@ jobs:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6.0.2
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
@@ -25,35 +25,207 @@ jobs:
name: Clippy
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6.0.2
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- # Catch hard errors and lint regressions. We don't enforce -D warnings
- # workspace-wide yet (legacy code has standing warnings); the CI gate is
- # "compiles cleanly + no clippy ERRORS". Tighten later by promoting
- # selected lints to deny.
- - run: cargo clippy --workspace --all-targets --all-features
+ - run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
+
+ docs:
+ name: Documentation
+ runs-on: ubuntu-latest
+ env:
+ RUSTDOCFLAGS: -D warnings
+ steps:
+ - uses: actions/checkout@v6.0.2
+ - uses: dtolnay/rust-toolchain@stable
+ - uses: Swatinem/rust-cache@v2
+ - name: Build rustdoc
+ run: cargo doc --workspace --all-features --no-deps --locked
+
+ mdbook:
+ name: mdBook
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+
+ - uses: taiki-e/install-action@mdbook
+
+ - name: Build mdBook
+ run: mdbook build
+
+ - name: Configure GitHub Pages
+ if: github.event_name == 'push' && github.ref == 'refs/heads/master'
+ uses: actions/configure-pages@v5
+
+ - name: Upload GitHub Pages artifact
+ if: github.event_name == 'push' && github.ref == 'refs/heads/master'
+ uses: actions/upload-pages-artifact@v4
+ with:
+ path: target/mdbook
+
+ deploy-pages:
+ name: Deploy GitHub Pages
+ runs-on: ubuntu-latest
+ needs: mdbook
+ if: github.event_name == 'push' && github.ref == 'refs/heads/master'
+ permissions:
+ contents: read
+ pages: write
+ id-token: write
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ steps:
+ - name: Deploy artifact
+ id: deployment
+ uses: actions/deploy-pages@v4
+
+ docs-hygiene:
+ name: Documentation hygiene
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+
+ - name: Check package README targets
+ shell: bash
+ run: |
+ missing=0
+ while IFS= read -r manifest; do
+ dir=${manifest%/Cargo.toml}
+ package_name=$(sed -n 's/^name = "\([^"]*\)"/\1/p' "$manifest" | head -1)
+ [ -z "$package_name" ] && continue
+
+ readme=$(sed -n 's/^readme = "\([^"]*\)"/\1/p' "$manifest" | head -1)
+ if [ -z "$readme" ]; then
+ if [ ! -f "$dir/README.md" ]; then
+ printf '%s: package has no README.md and no readme target\n' "$manifest"
+ missing=1
+ fi
+ continue
+ fi
+
+ if [ ! -e "$dir/$readme" ]; then
+ printf '%s: readme target does not exist: %s\n' "$manifest" "$readme"
+ missing=1
+ fi
+ done < <(find . \( -path './.git' -o -path './target' -o -path './node_modules' -o -path '*/node_modules' \) -prune -o -name Cargo.toml -print | sort)
+
+ exit "$missing"
+
+ - name: Check local Markdown links
+ shell: bash
+ run: |
+ broken=0
+ while IFS=$'\t' read -r file raw; do
+ dir=${file%/*}
+ [ "$dir" = "$file" ] && dir=.
+
+ link=${raw%%[[:space:]]*}
+ link=${link#<}
+ link=${link%>}
+ link=${link%%#*}
+
+ case "$link" in
+ ''|'#'*|http://*|https://*|mailto:*|file:*|javascript:*)
+ continue
+ ;;
+ esac
+
+ target="$dir/$link"
+ if [ ! -e "$target" ]; then
+ printf '%s: broken local Markdown link: %s\n' "$file" "$raw"
+ broken=1
+ fi
+ done < <(
+ find . \( -path './.git' -o -path './target' -o -path './node_modules' -o -path '*/node_modules' \) -prune -o -name '*.md' -type f -print0 |
+ xargs -0 perl -ne 'while (/\[[^\]]+\]\(([^)]+)\)/g) { print "$ARGV\t$1\n" }'
+ )
+
+ exit "$broken"
+
+ supply-chain:
+ name: Supply chain policy
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+ - uses: dtolnay/rust-toolchain@stable
+ - uses: taiki-e/install-action@cargo-deny
+ - uses: Swatinem/rust-cache@v2
+ - run: cargo deny check
test:
name: Test (workspace)
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6.0.2
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Build tests
- run: cargo test --workspace --all-features --no-run --locked
+ run: cargo test --workspace --all-targets --all-features --no-run --locked
- name: Run tests
- run: cargo test --workspace --all-features -- --nocapture --test-threads=4
+ run: cargo test --workspace --all-targets --all-features --locked
+ - name: Run doctests
+ run: cargo test --doc --workspace --all-features --locked
+
+ feature-matrix:
+ name: Feature matrix
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: wasm32-unknown-unknown
+
+ - uses: Swatinem/rust-cache@v2
+
+ - name: Check macro crates without defaults
+ run: cargo check -p ras-rest-macro -p ras-jsonrpc-macro -p ras-jsonrpc-bidirectional-macro -p ras-file-macro --no-default-features --locked
+
+ - name: Check REST macro server-only
+ run: cargo check -p ras-rest-macro --no-default-features --features server --locked
+
+ - name: Check REST macro client-only
+ run: cargo check -p ras-rest-macro --no-default-features --features client --locked
+
+ - name: Check JSON-RPC macro server-only
+ run: cargo check -p ras-jsonrpc-macro --no-default-features --features server --locked
+
+ - name: Check JSON-RPC macro client-only
+ run: cargo check -p ras-jsonrpc-macro --no-default-features --features client --locked
+
+ - name: Check bidirectional macro server-only
+ run: cargo check -p ras-jsonrpc-bidirectional-macro --no-default-features --features server --locked
+
+ - name: Check bidirectional macro client-only
+ run: cargo check -p ras-jsonrpc-bidirectional-macro --no-default-features --features client --locked
+
+ - name: Check bidirectional native client
+ run: cargo check -p ras-jsonrpc-bidirectional-client --no-default-features --features native --locked
+
+ - name: Check bidirectional WASM client
+ run: cargo check -p ras-jsonrpc-bidirectional-client --no-default-features --features wasm --target wasm32-unknown-unknown --locked
+
+ - name: Check example API crates without defaults
+ run: cargo check -p basic-jsonrpc-api -p rest-api -p file-service-api -p bidirectional-chat-api -p oauth2-demo-api --no-default-features --locked
+
+ - name: Check example API crates server-only
+ run: cargo check -p basic-jsonrpc-api -p rest-api -p file-service-api -p bidirectional-chat-api -p oauth2-demo-api --no-default-features --features basic-jsonrpc-api/server,rest-api/server,file-service-api/server,bidirectional-chat-api/server,oauth2-demo-api/server --locked
+
+ - name: Check example API crates client-only
+ run: cargo check -p basic-jsonrpc-api -p rest-api -p file-service-api -p bidirectional-chat-api -p oauth2-demo-api --no-default-features --features basic-jsonrpc-api/client,rest-api/client,file-service-api/client,bidirectional-chat-api/client,oauth2-demo-api/client --locked
+
+ - name: Check inline file-service example server feature
+ run: cargo check -p file-service-example --no-default-features --features server --locked
playwright:
name: Playwright E2E
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6.0.2
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
@@ -62,9 +234,9 @@ jobs:
uses: Swatinem/rust-cache@v2
- name: Setup Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6.4.0
with:
- node-version: 22
+ node-version: 22.13
cache: npm
cache-dependency-path: tests/playwright/package-lock.json
@@ -82,7 +254,7 @@ jobs:
- name: Upload Playwright report
if: always()
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7.0.1
with:
name: playwright-report
path: tests/playwright/playwright-report
@@ -91,30 +263,84 @@ jobs:
- name: Upload Playwright test results
if: failure()
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7.0.1
with:
name: playwright-test-results
path: tests/playwright/test-results
if-no-files-found: ignore
retention-days: 7
+ generated-client-specs:
+ name: Generated client specs
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+
+ - uses: dtolnay/rust-toolchain@stable
+
+ - uses: Swatinem/rust-cache@v2
+
+ - name: Generate OpenAPI specs
+ run: cargo check -p file-service-backend -p rest-backend --locked
+
+ - name: Verify generated OpenAPI specs
+ run: |
+ test -s examples/file-service-wasm/file-service-backend/target/openapi/documentservice.json
+ test -s examples/rest-wasm-example/rest-backend/target/openapi/userservice.json
+
+ wasm-ui-example:
+ name: WASM UI example
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v6.0.2
+
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ targets: wasm32-unknown-unknown
+
+ - uses: Swatinem/rust-cache@v2
+
+ - name: Check browser API clients
+ run: >
+ cargo check
+ -p basic-jsonrpc-api
+ -p rest-api
+ -p file-service-api
+ --target wasm32-unknown-unknown
+ --no-default-features
+ --features basic-jsonrpc-api/client,rest-api/client,file-service-api/client
+ --locked
+
+ - name: Setup Node
+ uses: actions/setup-node@v6.4.0
+ with:
+ node-version: 22.13
+ cache: npm
+ cache-dependency-path: examples/wasm-ui-demo/package-lock.json
+
+ - name: Build WASM UI example
+ working-directory: examples/wasm-ui-demo
+ run: |
+ npm ci
+ npm run build
+
coverage:
name: Coverage report
runs-on: ubuntu-latest
needs: [test]
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6.0.2
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- uses: taiki-e/install-action@cargo-llvm-cov
- uses: Swatinem/rust-cache@v2
- name: Generate coverage (lcov)
- run: cargo llvm-cov --workspace --all-features --lcov --output-path lcov.info
+ run: cargo llvm-cov --workspace --all-targets --all-features --locked --lcov --output-path lcov.info
- name: Print summary
run: cargo llvm-cov report --summary-only
- name: Upload coverage artifact
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7.0.1
with:
name: coverage-lcov
path: lcov.info
diff --git a/.gitignore b/.gitignore
index 1793a3a..070cef3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,19 +13,25 @@ secrets/
**/secrets/
**/.env
-# Generated test output and OpenRPC documents
+# Generated API documents and local test output
**/custom/
-**/*.json
-!package*.json
+**/openrpc/
+**/openapi/
+**/pkg/
+tests/playwright/test-results/
# Local config and test files
examples/bidirectional-chat/server/config.toml
test_login.sh
+# Local agent, IDE, and scratch artifacts
+.agents/
+.codex/
+.claude/
+.references/
+agent-research/
+docs_and_help/
+sketchpad/
+
# Chat data
**/chat_data/
-
-# Build outputs
-**/openrpc/
-**/openapi/
-.references/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d33f59b..ea3827e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,103 @@ All notable changes to this project will be documented in this file.
## [Unreleased]
+### Changed - 2026-05-24
+- Specification types crate now uses the `ras-openrpc-types` package name and `ras_openrpc_types` import path.
+- Package metadata, clone instructions, and documentation links now point to the moved `rust-api-stack` repository.
+
+### Fixed - 2026-05-23
+- `ras-identity-local`: Duplicate local user creation now fails with `LocalUserError::UserAlreadyExists` instead of silently overwriting credentials.
+- Bumped `ras-identity-local` from `0.1.1` to `0.2.0` because `LocalUserProvider::add_user` now returns the crate-specific `LocalUserError`.
+- Bumped `ras-identity-oauth2` from `0.1.1` to `0.1.2` for the additive `UserInfoMapping` root re-export and updated OAuth2 docs.
+- Bumped `ras-identity-session` from `0.1.1` to `0.2.0` because replacing `jsonwebtoken` exposes the crate-local `JwtAlgorithm` and string-backed JWT errors in the public API.
+- `documentation/ras-identity.md`: Identity examples now use the current `UserPermissions`, `SessionService`, JWT claims, session revocation, and Axum 0.8 server APIs.
+- `ras-identity-local`: README testing/security notes now distinguish default tests from optional timing-sensitive checks.
+- `ras-identity-session`: JWT signing now uses local HMAC-SHA implementations for HS256/HS384/HS512 instead of pulling in the broader `jsonwebtoken` RustCrypto/RSA dependency path.
+- `ras-openrpc-types`: Restored the original `Extensions::insert`, `Extensions::with`, and `Extensions::from_map` signatures for compatibility; checked variants are now available as `try_insert`, `try_with`, and `try_from_map`.
+- `ras-jsonrpc-macro`: Version labels such as `"1.0.0"` and `"v1-beta"` now generate sanitized client method suffixes instead of invalid Rust identifiers.
+- Supply-chain policy now passes on current `cargo-deny`; vulnerable `rand`, `time`, `tracing-subscriber`, `protobuf`, and related OpenTelemetry/Prometheus dependencies were updated, and unmaintained `wee_alloc` was removed from the WASM UI example.
+- `examples/bidirectional-chat`: Auth lifecycle tests now verify login after registration, duplicate registration rejection, and permission-bearing JWT claims.
+- `examples/bidirectional-chat`: Removed fake auth endpoint checks from `server_tests.rs`; auth endpoint coverage now lives in the in-memory lifecycle suite that wires the real identity/session stack.
+- `examples/bidirectional-chat`: Configuration docs now match the implemented config-file and environment-variable loading behavior.
+- `examples/bidirectional-chat`: README commands now use the actual `bidirectional-chat-tui` package and current example credentials.
+- `examples/bidirectional-chat`: TUI README now states the correct Rust 1.88+ requirement for Rust 2024 edition crates.
+- `examples/file-service-wasm`: README now names the real `wasm-client` feature.
+- `ras-openrpc-types` and `ras-jsonrpc-types`: README dependency snippets now match the current crate versions.
+- REST and JSON-RPC macro documentation dependency snippets now match the workspace Axum, Tokio, and schemars versions.
+- `ras-rest-macro` and `ras-jsonrpc-macro`: HTTP integration tests now use in-memory `axum-test` mock transport instead of binding local TCP sockets.
+- `ras-jsonrpc-macro`: Generated-client compile/config coverage no longer attempts requests against an unused localhost port.
+- CI now treats clippy warnings as failures with `cargo clippy --workspace --all-targets --all-features -- -D warnings`.
+- Removed unused workspace dependency declarations left behind by older local tooling and UI experiments.
+- Narrowed JSON ignore rules so TypeScript example `tsconfig` files are visible for version control while generated OpenRPC/OpenAPI and runtime data stay ignored.
+- `examples/file-service-wasm` and `examples/rest-wasm-example`: TypeScript generated-client samples are now plain usage examples instead of standalone npm apps.
+- CI now verifies the generated OpenAPI specs used by the TypeScript usage samples without installing npm dependencies for those samples.
+- `examples/wasm-ui-demo`: Added a local README and fixed the browser client/proxy path to match the basic JSON-RPC service's `/rpc` route.
+- `examples/wasm-ui-demo`: Build scripts and ignore rules now match the actual Rollup `dist/` output.
+- CI now builds the `wasm-ui-demo` WebAssembly bundle with the `wasm32-unknown-unknown` target.
+- CI now enforces the tracked `deny.toml` supply-chain policy with `cargo-deny`.
+- `examples/file-service-example`: Added a local README with run instructions, curl examples, and token behavior.
+- Root and bidirectional JSON-RPC README examples now match the current generated client/server APIs and avoid overstating retry behavior.
+- `ras-jsonrpc-bidirectional-client`: The documented WASM feature check now compiles with `wasm32-unknown-unknown` and keeps native WebSocket dependencies out of the WASM dependency graph.
+- `ras-identity-oauth2`: OAuth2 integration tests now use in-memory `axum-test` mock transport instead of socket-bound mock HTTP servers.
+- `ras-jsonrpc-bidirectional-server` and `ras-jsonrpc-bidirectional-macro`: WebSocket handler, generated-service, and round-trip benchmark coverage now run through an in-memory socket adapter instead of binding local TCP ports.
+- `ras-jsonrpc-bidirectional-server`: Request handler failures now return JSON-RPC error responses and keep the WebSocket loop alive for later requests.
+- `ras-jsonrpc-bidirectional-client`: Native transport request construction and disconnected send/receive behavior now have socketless unit coverage.
+- `ras-identity-oauth2`: Added fake-transport client tests for state mismatch, provider callback errors, PKCE-disabled token exchange parameters, and missing userinfo endpoint handling.
+- `examples/bidirectional-chat`: Added runtime `messages_per_minute` enforcement for authenticated `send_message` calls, plus socketless WebSocket flow tests for room join, list, leave, profile update/readback, moderator kick, admin announcement broadcast, generated permission denial, request-error recovery, disconnect cleanup, typing cleanup, message rate limiting, and multi-user message broadcast through the generated handler, in-memory adapter, and in-memory connection manager; profile avatar persistence now uses the same snake_case strings as the API.
+- `examples/file-service-wasm`: Corrected the documented 100 MB upload limit and generated OpenAPI path in the TypeScript usage sample.
+- Root README quick start now keeps the first-run path Rust-only and points to frontend examples as optional follow-ups.
+- REST macro docs now describe the built-in API explorer and point to the actual `/docs/openapi.json` route.
+- TypeScript client docs now describe OpenAPI-generated fetch-client usage without implying a framework or npm app scaffold.
+- Changelog history no longer implies the current `.cargo/config.toml` configures Kellnr as the default registry.
+- `examples/bidirectional-chat`: Server test README now describes remaining WebSocket coverage as in-memory handler testing.
+- `examples/wasm-ui-demo`: Removed an unused placeholder resources directory.
+- `ras-jsonrpc-bidirectional-macro`: README feature docs now match the actual `server`/`client` feature set, and documented `server_to_client_calls` syntax is covered by parser and compile tests.
+- `ras-jsonrpc-bidirectional-macro`: Generated server-to-client RPC handlers now wrap callbacks in `Arc` instead of requiring an undocumented `Clone` bound.
+- `ras-jsonrpc-bidirectional-server`: Manager tests no longer reference the deleted socket-bound integration test file.
+- Root, REST macro, and observability docs no longer contain placeholder implementation comments or undefined sample variables in their primary setup snippets.
+- Package README test commands now consistently use `--locked`, and the OAuth2 demo's focused test example names a real current test.
+- OAuth2 README and demo landing-page copy now use current project naming and avoid implying unimplemented response caching or active-session token revocation.
+- Example run/check/build snippets now consistently use the checked-in lockfile.
+- Root, example overview, and local example quick-start commands now use workspace-root package invocations where practical instead of mixing `cd`-based forms.
+- `examples/bidirectional-chat`: Workspace-root server commands now set `CHAT_DATA_DIR` alongside `CHAT_CONFIG_FILE` so persisted chat state lands under the ignored example runtime directory.
+- Root, examples, Playwright, and CI metadata now state the Rust 1.88+ and Node.js 22.13+ prerequisites consistently.
+- Cargo package manifests now declare `rust-version = "1.88"` to match the locked workspace dependency graph.
+- File-service macro installation docs now list the native and WASM dependencies required by the generated server and clients.
+- REST and JSON-RPC macro installation snippets now wire consumer crate `server` and `client` features to the macro features and optional dependencies.
+- Bidirectional client docs now describe caller-managed reconnect behavior instead of claiming an automatic reconnect loop, and example snippets use concrete demo tokens and real package commands.
+- File-service macro docs and example READMEs now use current generated trait names, concrete upload/download snippets, and checked-in backend links instead of placeholder storage/auth code.
+- REST macro docs now use the current `AuthProvider`/`AuthFuture` shape, concrete demo auth providers, valid OpenAPI configuration examples, and complete generated trait method lists instead of placeholder code.
+- JSON-RPC macro and core docs now use concrete method definitions, generated builder declarations, and current `AuthProvider` permission-checking examples instead of placeholder helper APIs.
+- `ras-observability-core`: Added `RequestContext::websocket(method)` and updated observability/identity examples to use concrete env-backed configuration instead of placeholder credentials and pseudo-code.
+- Bidirectional JSON-RPC and OpenRPC type docs now use concrete validation/sender examples, and `ras-jsonrpc-bidirectional-types` re-exports `MessageSenderExt` from the crate root to match the documented API.
+- Identity, observability, bidirectional WebSocket, and JSON-RPC types docs now avoid broad "everything"/"complete"/"high-performance" claims unless the text is tied to a concrete implemented API.
+- REST macro TypeScript snippets now avoid ambiguous ellipsis-style config spreading in favor of explicit request option construction.
+- `examples/rest-wasm-example/rest-backend`: Added a backend-local README with run commands, demo tokens, generated OpenAPI locations, endpoint map, and focused test commands.
+- `examples/rest-wasm-example/rest-api`: Added a shared-contract README covering generated server/client features and related example files.
+- `examples/bidirectional-chat/server`: Added a server-local README with run commands, configuration behavior, REST auth endpoints, WebSocket auth options, and socketless test guidance.
+- Example API crates now have package-local READMEs that describe their generated contracts, feature flags, related runnable examples, and focused check commands.
+- Playwright fixture crates now have local READMEs that document their browser-test role, socket-bound ports, routes, test tokens, and focused check commands.
+- `examples/wasm-ui-demo`: Trimmed direct npm build dependencies by using Node's built-in directory removal and removing the extra terser Rollup plugin from the example build.
+- `examples/wasm-ui-demo` and `ras-rest-macro`: Removed stale direct Cargo dependency declarations that are no longer used by the example UI or REST macro tests.
+- REST macro installation docs now list the consumer-side `axum-extra` dependency required by generated query-parameter extractors.
+- Public guides now avoid broad "complete" claims for examples and use concrete labels such as runnable service, task API example, and file API example.
+- Example READMEs now use correct relative paths for backticked local file references that are not covered by Markdown link checking.
+- `basic-jsonrpc-api` and `rest-api`: Added direct contract tests for generated OpenRPC/OpenAPI documents and important wire shapes used by generated clients.
+- `oauth2-demo-api` and `bidirectional-chat-api`: Added direct contract tests for generated OpenRPC permissions, schema metadata, and bidirectional notification/avatar wire shapes.
+- Playwright fixture crates now have socketless contract tests for generated OpenRPC/OpenAPI methods, routes, docs, auth metadata, query parameters, and version metadata.
+- `ras-jsonrpc-core`: Added re-export contract tests for auth types, JSON-RPC protocol types, and version migration traits.
+- CI now checks Cargo package README targets and local Markdown links without adding repository scripts.
+- Root README now documents the documentation-hygiene checks that CI runs for package README targets and local Markdown links.
+- Security and observability docs now describe concrete mitigations and setup hooks instead of broad constant-time or zero-configuration claims.
+
+### Removed - 2026-05-23
+- Removed stale local development artifacts: the `ras-file-macro` debug proc-macro stub, the bidirectional chat `test-config` diagnostic binary, and a tracked runtime chat log.
+- Removed tracked local-agent and scratch artifacts from `.claude/`, `agent-research/`, `docs_and_help/`, and `sketchpad/`; these paths are now ignored for local use only.
+- Removed socket-bound HTTP mock dev-dependencies left behind by older OAuth2 and macro test suites.
+- Removed unused `tokio-test` dev-dependencies and the stale bidirectional chat server `reqwest` dev-dependency left behind after the socketless test cleanup.
+- Removed scaffold-style placeholder comments from `deny.toml` so the tracked supply-chain policy is project-specific.
+- Added the current `Unicode-3.0` SPDX license identifier to `deny.toml`.
+
### Added - 2026-05-10
- Added `ras-version-core` `0.1.0` with the shared `VersionMigration` trait for opt-in API compatibility migrations.
- `ras-jsonrpc-macro`: Added opt-in versioned JSON-RPC methods. Legacy wire methods can migrate legacy requests into canonical request types, call the canonical trait method, and migrate canonical responses back to legacy response types.
@@ -25,6 +122,9 @@ All notable changes to this project will be documented in this file.
### Documentation - 2026-05-10
- Updated JSON-RPC, REST, identity, observability, example, and Playwright documentation for trait-backed service setup, current auth syntax, current crate names, and versioned API migration examples.
+### Removed - 2026-05-22
+- Removed the `openrpc-to-bruno` tool crate from the workspace.
+
### Added - 2026-05-09
- Established repository versioning and changelog policy in `VERSIONING.md`.
- Added doc-comment support for generated API documentation:
@@ -78,19 +178,17 @@ All notable changes to this project will be documented in this file.
- Bidirectional chat terminal client foundation (Sprint 2 Day 1)
- Modular architecture with separate ui, client, auth, and config modules
- Complete ratatui-based terminal UI with message area, user list, and input field
- - Placeholder implementations for WebSocket client integration
+ - Initial WebSocket client integration scaffolding
- Configuration system supporting environment variables and TOML files
- JWT token management infrastructure for authentication
### Updated - 2025-01-14
-- Simplified CLAUDE.md build commands to use generic examples instead of listing all crates
+- Simplified local development guidance to use generic examples instead of listing all crates
- Added bidirectional chat client architecture details to documentation
- Terminal UI layout and components
- State management and WebSocket integration
- Authentication and configuration details
-- Updated TASK.md to mark completed Sprint 2 terminal client implementation tasks
-- Archived Sprint 3 retrospective to scraim/retroed/ folder
- - Documented successful completion of bidirectional chat server and client foundation
+- Documented successful completion of the bidirectional chat server and client foundation
### Added - 2025-01-13
- Comprehensive configuration system for bidirectional chat server
@@ -120,17 +218,13 @@ All notable changes to this project will be documented in this file.
- Operation metrics for state loading/saving
### Added - 2025-01-13
-- Added ideate command for interactive brainstorming and execution planning
- - New .claude/commands/ideate.md facilitates collaborative idea development
- - Updated plan.md to emphasize brainstorming before work breakdown
-
- Bidirectional chat example demonstrating real-time WebSocket communication
- Complete chat server with room management and message persistence
- CLI client with register/login/chat commands for interactive sessions
- JWT-based authentication with role-based permissions (user/admin)
- Persistent chat history using JSON file storage
- Type-safe bidirectional RPC using generated client/server code
- - Updated CLAUDE.md with bidirectional macro implementation notes
+ - Added bidirectional macro implementation notes
- User profile system with cat avatar customization
- Added profile management endpoints (get_profile, update_profile)
@@ -166,28 +260,12 @@ All notable changes to this project will be documented in this file.
- Optional client dependencies (reqwest) only loaded when client feature enabled
- Comprehensive test coverage for client generation and HTTP communication patterns
-### Fixed - 2025-01-09
-- Improved Bruno auth enum formatting for better code consistency
- - Fixed formatting of BrunoAuth enum to use consistent brace style
- - Enhanced readability with proper field alignment for Bearer and Basic auth types
- - Maintained proper code formatting standards throughout bruno.rs module
-
### Fixed - 2025-01-09
- Fixed OpenRPC schema generation to comply with JSON-RPC specification
- Schema definitions now properly use components/schemas instead of $defs
- Service-specific helper functions prevent naming conflicts in generated code
- All schema references updated to use standard #/components/schemas/ format
-### Added - 2025-01-09
-- New OpenRPC-to-Bruno conversion tool for generating Bruno API collections from OpenRPC specifications
- - Complete CLI tool `openrpc-to-bruno` for converting OpenRPC 1.3.2 documents to Bruno collections
- - Supports authentication extraction with Bearer token configuration
- - Generates environment variables and collection metadata automatically
- - Comprehensive test suite with integration tests for conversion accuracy
- - Handles method parameter conversion with proper JSON schema validation
- - Bruno collection format support with proper .bru file generation
- - Command-line interface with configurable output directories and collection naming
-
### Refactored - 2025-01-09
- Restructured Google OAuth example into multi-crate architecture for better separation of concerns
- Split into separate `api` and `server` crates with clean API boundary separation
@@ -199,32 +277,24 @@ All notable changes to this project will be documented in this file.
### Enhanced - 2025-01-09
- Updated workspace configuration and dependencies to support new tooling and improved development experience
- - Added clap workspace dependency for consistent CLI tooling across the project
- Updated schemars to 1.0.0-alpha.20 for improved JSON Schema Draft 7 compatibility
- - Enhanced workspace member organization with tools and multi-crate example structure
+ - Enhanced workspace member organization for multi-crate example structure
- Fixed import ordering in integration tests following Rust style guidelines
- Improved Cargo.lock with new dependencies for CLI tools and testing infrastructure
### Fixed - 2025-01-09
- Fixed OpenRPC specification parsing to support extension fields and JSON Schema compatibility
- - Removed deny_unknown_fields restrictions from Method and Schema structs in openrpc-types crate
+ - Removed deny_unknown_fields restrictions from Method and Schema structs in ras-openrpc-types crate
- Added $schema field support to Schema struct for proper JSON Schema Draft 7 compatibility
- Enables proper parsing of OpenRPC documents with x-authentication and x-permissions extensions
- - Bruno API collection generator now properly supports OpenRPC files with custom authentication metadata
### Enhanced - 2025-01-09
- Enhanced OpenRPC document generation functionality to actually generate files
- - Modified google-oauth-example to call OpenRPC generation functions during service creation
+ - Modified the OAuth2 demo to call OpenRPC generation functions during service creation
- Added JsonSchema derives to all request/response types for proper schema generation
- Created test infrastructure to verify end-to-end OpenRPC generation works correctly
- OpenRPC documents now properly written to target/openrpc/ directory when enabled
-### Fixed - 2025-01-09
-- Fixed Bruno API collection JSON formatting to be properly indented and valid
- - Corrected JSON body indentation in .bru files to use proper 2-space indentation within body:json blocks
- - Generated Bruno collections are now properly formatted and compatible with Bruno API client
- - Resolves validation errors when importing generated collections into Bruno
-
### Documentation - 2025-01-09
- Added comprehensive OpenRPC generation documentation to ras-jsonrpc-macro README
- Documented OpenRPC generation feature with complete usage examples and configuration options
@@ -268,28 +338,28 @@ All notable changes to this project will be documented in this file.
- Comprehensive HTTP integration test suites for both JSON-RPC and REST macro crates
- Complete JSON-RPC integration tests covering all authentication patterns (UNAUTHORIZED, WITH_PERMISSIONS with various levels)
- Full REST API integration tests with CRUD operations, path parameters, and HTTP method validation
- - Real HTTP server testing using random port binding with tokio TcpListener for concurrent test execution
+ - HTTP integration coverage for generated routers and clients
- Authentication and authorization testing across all permission levels with JWT token validation
- Security testing including timing attack resistance and proper error handling scenarios
- Concurrent request testing validating thread safety and performance under load
- OpenRPC and OpenAPI document generation testing ensuring specification compliance
- Test infrastructure supporting both positive and negative scenarios with comprehensive error validation
- - Fixed unused import warnings in rust-identity-local during test infrastructure development
+ - Fixed unused import warnings in `ras-identity-local` during test infrastructure development
### Enhanced - 2025-01-08
- Added comprehensive testing dependencies for HTTP integration testing across macro crates
- - Added wiremock, reqwest, tower, hyper, rand, and futures to workspace dependencies for robust HTTP testing infrastructure
- - Enhanced rust-jsonrpc-macro and rust-rest-macro with testing dependencies for real server integration tests
- - Established foundation for comprehensive integration testing with random port binding and concurrent request handling
+ - Added HTTP client, router, concurrency, and async helper dependencies for robust HTTP testing infrastructure
+ - Enhanced `ras-jsonrpc-macro` and `ras-rest-macro` with testing dependencies for real server integration tests
+ - Established foundation for comprehensive integration testing and concurrent request handling
- Dependencies support both JSON-RPC and REST API testing patterns with authentication validation
### Refactored - 2025-01-08
- Architectural refactoring to eliminate coupling between RPC and REST macro crates
- - Created new `rust-auth-core` crate as shared foundation for authentication types and traits
- - Moved `AuthProvider`, `AuthenticatedUser`, `AuthError`, and related types from `rust-jsonrpc-core` to `rust-auth-core`
- - Updated `rust-rest-macro` to depend on `rust-auth-core` instead of `rust-jsonrpc-core`, eliminating unwanted cross-dependencies
- - Updated `rust-identity-session` and other affected crates to use shared authentication types
- - Maintained full backward compatibility through re-exports in `rust-jsonrpc-core`
+ - Created new `ras-auth-core` crate as shared foundation for authentication types and traits
+ - Moved `AuthProvider`, `AuthenticatedUser`, `AuthError`, and related types from `ras-jsonrpc-core` to `ras-auth-core`
+ - Updated `ras-rest-macro` to depend on `ras-auth-core` instead of `ras-jsonrpc-core`, eliminating unwanted cross-dependencies
+ - Updated `ras-identity-session` and other affected crates to use shared authentication types
+ - Maintained full backward compatibility through re-exports in `ras-jsonrpc-core`
- Enhanced codebase maintainability with clear separation of concerns between authentication logic and protocol-specific implementations
- Improved workspace architecture enabling future protocol extensions (gRPC, etc.) without introducing coupling
- Updated documentation and build commands to reflect new crate structure
@@ -304,7 +374,7 @@ All notable changes to this project will be documented in this file.
### Fixed - 2025-01-08
- Fixed REST API documentation schema display for optional fields showing as empty objects
- - Enhanced OpenAPI schema generation to convert `"type": ["string", "null"]` format to `"type": "string", "nullable": true"` for better Swagger UI compatibility
+ - Enhanced OpenAPI schema generation to convert `"type": ["string", "null"]` format to `"type": "string", "nullable": true"` for better explorer compatibility
- Improved JavaScript schema processing in documentation UI to handle array type definitions (e.g., `["string", "null"]`)
- Added recursive schema normalization for all nested objects and definitions
- Optional fields like `email` and `display_name` now display as proper string input fields with meaningful examples
@@ -313,15 +383,15 @@ All notable changes to this project will be documented in this file.
### Enhanced - 2025-01-08
- Sprint retrospective update covering Static API Documentation Hosting & Explorer UI implementation
- Documented strategic orchestration approach with successful role delegation (Architect → Backend Coder → UX Designer)
- - Noted seamless integration with existing rust-rest-macro patterns without breaking changes
- - Recognized custom API explorer UI success replacing generic Swagger UI with tailored features
+ - Noted seamless integration with existing `ras-rest-macro` patterns without breaking changes
+ - Recognized custom API explorer UI success with tailored features
- Highlighted zero-overhead implementation design for optional features
- Identified opportunity for smaller proof-of-concept approach in future complex implementations
### Added - 2025-01-08
- Static API documentation hosting with embedded explorer UI for REST services
- - Complete static file hosting support integrated into rust-rest-macro crate
- - Interactive API documentation with custom-built explorer UI replacing generic Swagger UI
+ - Complete static file hosting support integrated into the `ras-rest-macro` crate
+ - Interactive API documentation with custom-built explorer UI
- Embedded static assets using rust-embed for zero-dependency deployment
- JWT authentication integration directly in the explorer interface
- Responsive documentation UI with multiple theme support (default theme included)
@@ -332,16 +402,16 @@ All notable changes to this project will be documented in this file.
### Enhanced - 2025-01-08
- Sprint retrospective process with enhanced development guidelines based on observed patterns
- - Added Critical Development Rules section to CLAUDE.md based on sprint observation analysis
+ - Added critical development rules based on sprint observation analysis
- Five new rules: Test Early/Often, Specification First, Incremental Implementation, Macro Testing, End-to-End Validation
- Enhanced Common Pitfalls with string type mismatches and move semantics guidance
- - Updated crate listings to include rust-rest-macro and build commands
- - Archived sprint-2 retrospective notes covering OpenRPC generation, registry setup, and REST macro implementation
+ - Updated crate listings to include `ras-rest-macro` and build commands
+ - Captured retrospective notes covering OpenRPC generation, registry setup, and REST macro implementation
- Systematic approach to learning from development patterns and preventing recurring issues
### Enhanced - 2025-01-08
- REST service example now demonstrates complete local authentication integration with comprehensive security features
- - Full JWT-based authentication using rust-identity-local and rust-identity-session crates
+ - Full JWT-based authentication using `ras-identity-local` and `ras-identity-session` crates
- Complete auth endpoints: user registration, login, logout, and user info retrieval
- Role-based permission system with admin and user access levels (admin users inherit user permissions)
- Two-phase authentication flow: LocalUserProvider for credential validation → SessionService for JWT issuance
@@ -352,24 +422,23 @@ All notable changes to this project will be documented in this file.
### Added - 2025-01-08
- REST macro crate implementation with comprehensive REST API generation capabilities
- - Complete rust-rest-macro procedural macro crate for type-safe REST endpoints with authentication integration
+ - Complete `ras-rest-macro` procedural macro crate for type-safe REST endpoints with authentication integration
- Supports all HTTP methods (GET, POST, PUT, DELETE, PATCH) with path parameters and request bodies
- OpenAPI 3.0 document generation using schemars with configurable output paths
- Permission-based access control with JWT authentication through AuthProvider integration
- Generated service traits, builders, and axum router integration following JSON-RPC macro patterns
- - Example application (rest-service-example) demonstrating comprehensive REST service implementation
+ - Example application demonstrating comprehensive REST service implementation
- Full workspace integration with proper dependency management and testing infrastructure
### Added - 2025-01-08
-- Kellnr registry configuration for local crate publishing
- - Configured kellnr as default registry in `.cargo/config.toml`
- - Registry URL set to `http://localhost:8000/api/v1/crates/`
- - Created comprehensive release command at `.claude/commands/kellnr-release.md`
+- Kellnr registry notes for local crate publishing
+ - Recorded the local registry URL `http://localhost:8000/api/v1/crates/`
+ - Created comprehensive release checklist
- Includes A-Z release process with dependency order management
- All internal dependencies already properly configured with path + version
### Added - 2025-01-08
-- Complete OpenRPC 1.3.2 specification types crate (openrpc-types) with full type safety and validation
+- Complete OpenRPC 1.3.2 specification types crate (ras-openrpc-types) with full type safety and validation
- Comprehensive implementation of all OpenRPC specification types with serde serialization support
- Ergonomic builder patterns using bon crate for fluent API construction
- Extensive validation system for OpenRPC documents, method names, error codes, and component references
@@ -385,20 +454,9 @@ All notable changes to this project will be documented in this file.
- Generates complete JSON Schema definitions using schemars crate for all request/response types
- Includes authentication metadata with OpenRPC extensions (`x-authentication`, `x-permissions`)
- Added comprehensive test coverage and examples demonstrating all features
- - Updated CLAUDE.md documentation with usage examples and requirements
+ - Updated JSON-RPC macro documentation with usage examples and requirements
- Requires types to implement `schemars::JsonSchema` trait when OpenRPC generation is enabled
-### Added - 2025-01-07
-- Sprint retrospective implementation with project guidelines optimization
- - Streamlined CLAUDE.md documentation from verbose descriptions to concise guidelines
- - Added testing guidelines based on sprint observations (security-first, end-to-end testing)
- - Enhanced orchestrate command with key execution principles to prevent observed mistakes
- - Archived sprint-1 retrospective notes to scraim/retroed/ for historical tracking
-
-- Added raitro command for automated sprint retrospectives
- - Command analyzes sprint observations and optimizes project guidelines
- - Provides framework for continuous improvement of development processes
-
### Fixed - 2025-01-07
- Fixed JSON-RPC macro routing issue causing 404 errors when accessing service endpoints
- Macro now properly uses the base_url parameter instead of hardcoding "/" routes
@@ -428,7 +486,7 @@ All notable changes to this project will be documented in this file.
- Custom user info field mapping for flexible OAuth2 provider integration
- Comprehensive error handling with OAuth2-specific error types and detailed context
- Full test suite covering PKCE generation, authorization URLs, state management, and security scenarios
- - Production-ready implementation with proper HTTP timeouts and robust error recovery
+ - HTTP timeouts and error handling for the provider client
- Enhanced JwtAuthProvider with Clone trait for improved service compatibility and architecture flexibility
### Added - 2025-01-07
@@ -437,7 +495,7 @@ All notable changes to this project will be documented in this file.
- Complete Rust backend integration using Axum server with JSON-RPC API endpoints
- Sophisticated permission system with role-based access control based on email domains and user attributes
- Six different API endpoints showcasing permission-based access (user info, documents, admin, system status, beta features)
- - Production-ready OAuth2 flow with PKCE, state validation, JWT session management, and comprehensive error handling
+ - OAuth2 flow with PKCE, state validation, JWT session management, and error handling
- Interactive API documentation with built-in testing capabilities and JWT token management
- Comprehensive test suite covering permission logic and service compilation validation
- Complete setup documentation with Google Cloud Console integration instructions
@@ -449,11 +507,11 @@ All notable changes to this project will be documented in this file.
- Includes protection for production, staging, and local environment configurations
### Documentation - 2025-01-07
-- Updated CLAUDE.md with comprehensive Google OAuth2 example documentation and usage instructions
+- Updated Google OAuth2 example documentation and usage instructions
- Added quick start guide with Google Cloud Console setup steps and environment configuration
- Documented sophisticated permission system with role-based access control examples
- Comprehensive API endpoint documentation with permission requirements and functionality descriptions
- - Added oauth2 provider status update from stub to full production-ready implementation
+ - Added oauth2 provider status update from stub to implemented provider
- Enhanced development commands with example application execution instructions
- Added Common Pitfalls section documenting Axum router nesting syntax issues
- Updated sprint reflection documentation with Google OAuth2 full-stack implementation learnings and coordination insights
@@ -461,7 +519,7 @@ All notable changes to this project will be documented in this file.
- Documented lessons learned about testing end-to-end flows and examining generated code
### Security - 2025-01-07
-- Enhanced authentication security in rust-identity-local with comprehensive attack vector protection
+- Enhanced authentication security in `ras-identity-local` with comprehensive attack vector protection
- Fixed username enumeration vulnerability - consistent errors for non-existent users and wrong passwords
- Implemented timing attack resistance using constant-time authentication with real Argon2 dummy hash
- Added robust input validation for malformed payloads, empty credentials, and special characters
@@ -472,10 +530,10 @@ All notable changes to this project will be documented in this file.
### Added - 2025-01-07
- Identity management system with pluggable authentication providers
- - rust-identity-core: Core traits for IdentityProvider and UserPermissions with default implementations
- - rust-identity-local: Local username/password authentication with Argon2 password hashing
- - rust-identity-oauth2: OAuth2 provider framework (stub implementation for future completion)
- - rust-identity-session: JWT-based session management with configurable secrets and permission lookup
+ - `ras-identity-core`: Core traits for IdentityProvider and UserPermissions with default implementations
+ - `ras-identity-local`: Local username/password authentication with Argon2 password hashing
+ - `ras-identity-oauth2`: Initial OAuth2 provider framework for external-provider authentication
+ - `ras-identity-session`: JWT-based session management with configurable secrets and permission lookup
- Two-stage authentication flow: identity verification followed by JWT session creation
- Permission system with UserPermissions trait enabling flexible RBAC patterns
- JwtAuthProvider implementing AuthProvider trait for seamless JSON-RPC integration
@@ -488,23 +546,20 @@ All notable changes to this project will be documented in this file.
### Added - 2025-01-07
- Complete JSON-RPC library ecosystem with three core crates
- - rust-jsonrpc-types: Pure JSON-RPC 2.0 protocol types and utilities
- - rust-jsonrpc-core: Authentication and authorization framework with AuthProvider trait
- - rust-jsonrpc-macro: Procedural macro for generating type-safe RPC interfaces with axum integration
+ - `ras-jsonrpc-types`: Pure JSON-RPC 2.0 protocol types and utilities
+ - `ras-jsonrpc-core`: Authentication and authorization framework with AuthProvider trait
+ - `ras-jsonrpc-macro`: Procedural macro for generating type-safe RPC interfaces with axum integration
- Comprehensive test suite and integration tests for macro functionality
- Workspace-level dependency management with shared crate versions
- Example applications demonstrating JSON-RPC service implementation
- basic-jsonrpc-service: Complete working example with authentication and multiple endpoints
- Usage examples showing macro-generated service builders
- Enhanced project documentation and development guidelines
- - Updated CLAUDE.md with comprehensive crate organization patterns
+ - Updated crate organization patterns
- Added development workflow instructions and dependency management guidelines
- - Improved orchestration commands for better AI-assisted development
- Sprint reflection system for tracking development progress and learnings
### Added - 2025-01-06
- Initial project setup with Cargo workspace structure
-- Created rust-jsonrpc-macro procedural macro crate foundation
+- Created `ras-jsonrpc-macro` procedural macro crate foundation
- Added .gitignore for Rust and IDE artifacts
-- Configured MCP integration with Context7 for enhanced documentation
-- Added CLAUDE.md for AI-assisted development guidance
diff --git a/Cargo.lock b/Cargo.lock
index 6047251..a9c822d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,28 +2,13 @@
# It is not intended for manual editing.
version = 4
-[[package]]
-name = "addr2line"
-version = "0.24.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
-dependencies = [
- "gimli",
-]
-
-[[package]]
-name = "adler2"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
-
[[package]]
name = "ahash"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"once_cell",
"version_check",
"zerocopy",
@@ -31,9 +16,9 @@ dependencies = [
[[package]]
name = "aho-corasick"
-version = "1.1.3"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
@@ -44,12 +29,6 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
-[[package]]
-name = "android-tzdata"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
-
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -65,61 +44,17 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
-[[package]]
-name = "anstream"
-version = "0.6.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
-dependencies = [
- "anstyle",
- "anstyle-parse",
- "anstyle-query",
- "anstyle-wincon",
- "colorchoice",
- "is_terminal_polyfill",
- "utf8parse",
-]
-
[[package]]
name = "anstyle"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
-
-[[package]]
-name = "anstyle-parse"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
-dependencies = [
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle-query"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
-dependencies = [
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "anstyle-wincon"
-version = "3.0.9"
+version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
-dependencies = [
- "anstyle",
- "once_cell_polyfill",
- "windows-sys 0.59.0",
-]
+checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anyhow"
-version = "1.0.98"
+version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "argon2"
@@ -139,43 +74,11 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
-[[package]]
-name = "assert-json-diff"
-version = "2.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
-dependencies = [
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "async-stream"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
-dependencies = [
- "async-stream-impl",
- "futures-core",
- "pin-project-lite",
-]
-
-[[package]]
-name = "async-stream-impl"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "async-trait"
-version = "0.1.88"
+version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
+checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
@@ -188,23 +91,17 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
-[[package]]
-name = "auto-future"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373"
-
[[package]]
name = "autocfg"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "axum"
-version = "0.8.4"
+version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
+checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
dependencies = [
"axum-core",
"base64 0.22.1",
@@ -223,15 +120,14 @@ dependencies = [
"multer",
"percent-encoding",
"pin-project-lite",
- "rustversion",
- "serde",
+ "serde_core",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sha1",
"sync_wrapper",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.29.0",
"tower",
"tower-layer",
"tower-service",
@@ -240,9 +136,9 @@ dependencies = [
[[package]]
name = "axum-core"
-version = "0.5.2"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6"
+checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [
"bytes",
"futures-core",
@@ -251,7 +147,6 @@ dependencies = [
"http-body-util",
"mime",
"pin-project-lite",
- "rustversion",
"sync_wrapper",
"tower-layer",
"tower-service",
@@ -260,9 +155,9 @@ dependencies = [
[[package]]
name = "axum-extra"
-version = "0.10.1"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45bf463831f5131b7d3c756525b305d40f1185b688565648a92e1392ca35713d"
+checksum = "9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96"
dependencies = [
"axum",
"axum-core",
@@ -275,22 +170,21 @@ dependencies = [
"mime",
"pin-project-lite",
"rustversion",
- "serde",
+ "serde_core",
"serde_html_form",
"serde_path_to_error",
- "tower",
"tower-layer",
"tower-service",
+ "tracing",
]
[[package]]
name = "axum-test"
-version = "18.0.0-rc3"
+version = "18.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b81709cdada734964eba19892410332b2cbf79d21cda5b5996c45e9c451eeaf7"
+checksum = "0ce2a8627e8d8851f894696b39f2b67807d6375c177361d376173ace306a21e2"
dependencies = [
"anyhow",
- "auto-future",
"axum",
"bytes",
"bytesize",
@@ -313,27 +207,6 @@ dependencies = [
"url",
]
-[[package]]
-name = "backtrace"
-version = "0.3.75"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
-dependencies = [
- "addr2line",
- "cfg-if 1.0.0",
- "libc",
- "miniz_oxide",
- "object",
- "rustc-demangle",
- "windows-targets",
-]
-
-[[package]]
-name = "base16ct"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
-
[[package]]
name = "base64"
version = "0.21.7"
@@ -348,9 +221,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
-version = "1.8.0"
+version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
+checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
[[package]]
name = "basic-jsonrpc-api"
@@ -360,6 +233,7 @@ dependencies = [
"ras-jsonrpc-core",
"ras-jsonrpc-macro",
"ras-jsonrpc-types",
+ "ras-permission-manifest",
"reqwest",
"schemars",
"serde",
@@ -398,6 +272,7 @@ dependencies = [
"ras-jsonrpc-bidirectional-server",
"ras-jsonrpc-bidirectional-types",
"ras-jsonrpc-types",
+ "ras-permission-manifest",
"ras-rest-core",
"ras-rest-macro",
"reqwest",
@@ -415,23 +290,21 @@ dependencies = [
"anyhow",
"async-trait",
"axum",
+ "axum-test",
"bidirectional-chat-api",
"chrono",
"config",
"dashmap",
"dotenvy",
- "jsonwebtoken",
"ras-auth-core",
"ras-identity-core",
"ras-identity-local",
"ras-identity-session",
- "ras-jsonrpc-bidirectional-macro",
"ras-jsonrpc-bidirectional-server",
"ras-jsonrpc-bidirectional-types",
"ras-jsonrpc-types",
"ras-rest-core",
"ras-rest-macro",
- "reqwest",
"schemars",
"serde",
"serde_json",
@@ -456,7 +329,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
"tracing",
"tracing-subscriber",
@@ -464,11 +337,11 @@ dependencies = [
[[package]]
name = "bitflags"
-version = "2.9.1"
+version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
dependencies = [
- "serde",
+ "serde_core",
]
[[package]]
@@ -491,9 +364,9 @@ dependencies = [
[[package]]
name = "bon"
-version = "3.6.3"
+version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ced38439e7a86a4761f7f7d5ded5ff009135939ecb464a24452eaa4c1696af7d"
+checksum = "f47dbe92550676ee653353c310dfb9cf6ba17ee70396e1f7cf0a2020ad49b2fe"
dependencies = [
"bon-macros",
"rustversion",
@@ -501,9 +374,9 @@ dependencies = [
[[package]]
name = "bon-macros"
-version = "3.6.3"
+version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ce61d2d3844c6b8d31b2353d9f66cf5e632b3e9549583fe3cac2f4f6136725e"
+checksum = "519bd3116aeeb42d5372c29d982d16d0170d3d4a5ed85fc7dd91642ffff3c67c"
dependencies = [
"darling",
"ident_case",
@@ -516,21 +389,21 @@ dependencies = [
[[package]]
name = "bumpalo"
-version = "3.18.1"
+version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee"
+checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "bytes"
-version = "1.10.1"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
name = "bytesize"
-version = "2.0.1"
+version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3c8f83209414aacf0eeae3cf730b18d6981697fba62f200fcfb92b9f082acba"
+checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3"
[[package]]
name = "case"
@@ -552,33 +425,28 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "castaway"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5"
+checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
dependencies = [
"rustversion",
]
[[package]]
name = "cc"
-version = "1.2.26"
+version = "1.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
+checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98"
dependencies = [
+ "find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cfg_aliases"
@@ -588,11 +456,10 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
-version = "0.4.41"
+version = "0.4.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
+checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
dependencies = [
- "android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
@@ -630,49 +497,28 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.39"
+version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
+checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
- "clap_derive",
]
[[package]]
name = "clap_builder"
-version = "4.5.39"
+version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
+checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
- "anstream",
"anstyle",
"clap_lex",
- "strsim",
-]
-
-[[package]]
-name = "clap_derive"
-version = "4.5.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "syn",
]
[[package]]
name = "clap_lex"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
-
-[[package]]
-name = "colorchoice"
-version = "1.0.4"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
+checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "compact_str"
@@ -681,7 +527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32"
dependencies = [
"castaway",
- "cfg-if 1.0.0",
+ "cfg-if",
"itoa",
"rustversion",
"ryu",
@@ -713,16 +559,10 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"wasm-bindgen",
]
-[[package]]
-name = "const-oid"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
-
[[package]]
name = "const-random"
version = "0.1.18"
@@ -738,18 +578,19 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "const_format"
-version = "0.2.34"
+version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd"
+checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e"
dependencies = [
"const_format_proc_macros",
+ "konst",
]
[[package]]
@@ -887,27 +728,15 @@ dependencies = [
[[package]]
name = "crunchy"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
-
-[[package]]
-name = "crypto-bigint"
-version = "0.5.5"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
-dependencies = [
- "generic-array",
- "rand_core 0.6.4",
- "subtle",
- "zeroize",
-]
+checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "crypto-common"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
@@ -936,38 +765,11 @@ dependencies = [
"syn",
]
-[[package]]
-name = "curve25519-dalek"
-version = "4.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
-dependencies = [
- "cfg-if 1.0.0",
- "cpufeatures",
- "curve25519-dalek-derive",
- "digest",
- "fiat-crypto",
- "rustc_version",
- "subtle",
- "zeroize",
-]
-
-[[package]]
-name = "curve25519-dalek-derive"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "darling"
-version = "0.20.11"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
+checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
dependencies = [
"darling_core",
"darling_macro",
@@ -975,11 +777,10 @@ dependencies = [
[[package]]
name = "darling_core"
-version = "0.20.11"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
+checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
dependencies = [
- "fnv",
"ident_case",
"proc-macro2",
"quote",
@@ -989,9 +790,9 @@ dependencies = [
[[package]]
name = "darling_macro"
-version = "0.20.11"
+version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
+checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
dependencies = [
"darling_core",
"quote",
@@ -1000,11 +801,11 @@ dependencies = [
[[package]]
name = "dashmap"
-version = "6.1.0"
+version = "6.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
+checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"crossbeam-utils",
"hashbrown 0.14.5",
"lock_api",
@@ -1014,44 +815,15 @@ dependencies = [
[[package]]
name = "data-encoding"
-version = "2.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
-
-[[package]]
-name = "deadpool"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb84100978c1c7b37f09ed3ce3e5f843af02c2a2c431bae5b19230dad2c1b490"
-dependencies = [
- "async-trait",
- "deadpool-runtime",
- "num_cpus",
- "tokio",
-]
-
-[[package]]
-name = "deadpool-runtime"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b"
-
-[[package]]
-name = "der"
-version = "0.7.10"
+version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
-dependencies = [
- "const-oid",
- "pem-rfc7468",
- "zeroize",
-]
+checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
[[package]]
name = "deranged"
-version = "0.4.0"
+version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
+checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
dependencies = [
"powerfmt",
]
@@ -1069,7 +841,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
- "const-oid",
"crypto-common",
"subtle",
]
@@ -1110,7 +881,7 @@ dependencies = [
"futures-channel",
"futures-signals",
"futures-util",
- "gloo-events 0.1.2",
+ "gloo-events",
"js-sys",
"once_cell",
"pin-project",
@@ -1141,9 +912,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "dtoa"
-version = "1.0.10"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04"
+checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590"
[[package]]
name = "dtoa-short"
@@ -1175,9 +946,9 @@ dependencies = [
[[package]]
name = "dwind-base"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b48947db4f7bdc9c27db63eae83b065d3b20ad32752771d0ade0fc7919164720"
+checksum = "8b44539af807f152bd40afa239653ec83e26fb40416329af894d3e8950f2d4ef"
dependencies = [
"dominator",
"futures-signals",
@@ -1209,74 +980,15 @@ dependencies = [
[[package]]
name = "dyn-clone"
-version = "1.0.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
-
-[[package]]
-name = "ecdsa"
-version = "0.16.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
-dependencies = [
- "der",
- "digest",
- "elliptic-curve",
- "rfc6979",
- "signature",
- "spki",
-]
-
-[[package]]
-name = "ed25519"
-version = "2.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
-dependencies = [
- "pkcs8",
- "signature",
-]
-
-[[package]]
-name = "ed25519-dalek"
-version = "2.2.0"
+version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
-dependencies = [
- "curve25519-dalek",
- "ed25519",
- "serde",
- "sha2",
- "subtle",
- "zeroize",
-]
+checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]]
name = "either"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
-
-[[package]]
-name = "elliptic-curve"
-version = "0.13.8"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
-dependencies = [
- "base16ct",
- "crypto-bigint",
- "digest",
- "ff",
- "generic-array",
- "group",
- "hkdf",
- "pem-rfc7468",
- "pkcs8",
- "rand_core 0.6.4",
- "sec1",
- "subtle",
- "zeroize",
-]
+checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]]
name = "email_address"
@@ -1293,7 +1005,7 @@ version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
]
[[package]]
@@ -1304,45 +1016,48 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "erased-serde"
-version = "0.4.6"
+version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
+checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec"
dependencies = [
"serde",
+ "serde_core",
"typeid",
]
[[package]]
name = "errno"
-version = "0.3.12"
+version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
name = "expect-json"
-version = "1.0.0"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ccf8a36121b5fb67d1882fbbd2292fa59c0e97a442006d052296f7a6e0c781d9"
+checksum = "869f97f4abe8e78fc812a94ad6b721d72c4fb5532877c79610f2c238d7ccf6c4"
dependencies = [
"chrono",
"email_address",
"expect-json-macros",
+ "num",
+ "regex",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"typetag",
"uuid",
]
[[package]]
name = "expect-json-macros"
-version = "1.0.0"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0ef275cc4d31f49ae44d19a53c5087cf24245b7329c471653d793653f77b63d"
+checksum = "6e6fdf550180a6c29a28cb9aac262dc0064c25735641d2317f670075e9a469d9"
dependencies = [
"proc-macro2",
"quote",
@@ -1351,25 +1066,9 @@ dependencies = [
[[package]]
name = "fastrand"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
-
-[[package]]
-name = "ff"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
-dependencies = [
- "rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "fiat-crypto"
-version = "0.2.9"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
+checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "file-service-api"
@@ -1377,20 +1076,19 @@ version = "0.1.0"
dependencies = [
"async-trait",
"axum",
- "axum-extra",
- "http",
"js-sys",
"ras-auth-core",
+ "ras-file-core",
"ras-file-macro",
+ "ras-permission-manifest",
"reqwest",
"schemars",
"serde",
"serde-wasm-bindgen",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
"tokio-util",
- "tower",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@@ -1403,18 +1101,14 @@ dependencies = [
"anyhow",
"async-trait",
"axum",
- "chrono",
"dotenvy",
"file-service-api",
- "jsonwebtoken",
"mime_guess",
"ras-auth-core",
- "serde",
- "serde_json",
- "thiserror 2.0.12",
+ "ras-file-core",
+ "ras-permission-manifest",
+ "tempfile",
"tokio",
- "tokio-util",
- "tower",
"tower-http",
"tracing",
"tracing-subscriber",
@@ -1427,12 +1121,15 @@ version = "0.1.0"
dependencies = [
"async-trait",
"axum",
+ "axum-test",
"ras-auth-core",
+ "ras-file-core",
"ras-file-macro",
+ "ras-permission-manifest",
"reqwest",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
"tokio-util",
"tower-http",
@@ -1441,6 +1138,12 @@ dependencies = [
"uuid",
]
+[[package]]
+name = "find-msvc-tools"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+
[[package]]
name = "fnv"
version = "1.0.7"
@@ -1455,18 +1158,18 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "form_urlencoded"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
@@ -1479,9 +1182,9 @@ dependencies = [
[[package]]
name = "futures-channel"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
@@ -1489,15 +1192,15 @@ dependencies = [
[[package]]
name = "futures-core"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
@@ -1506,15 +1209,15 @@ dependencies = [
[[package]]
name = "futures-io"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-macro"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
@@ -1539,21 +1242,21 @@ dependencies = [
[[package]]
name = "futures-sink"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
-version = "0.3.31"
+version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
@@ -1563,7 +1266,6 @@ dependencies = [
"futures-task",
"memchr",
"pin-project-lite",
- "pin-utils",
"slab",
]
@@ -1575,7 +1277,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
- "zeroize",
]
[[package]]
@@ -1592,46 +1293,47 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.16"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
+checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"js-sys",
"libc",
- "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasi",
"wasm-bindgen",
]
[[package]]
name = "getrandom"
-version = "0.3.3"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"js-sys",
"libc",
- "r-efi",
- "wasi 0.14.2+wasi-0.2.4",
+ "r-efi 5.3.0",
+ "wasip2",
"wasm-bindgen",
]
[[package]]
-name = "gimli"
-version = "0.31.1"
+name = "getrandom"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi 6.0.0",
+ "wasip2",
+ "wasip3",
+]
[[package]]
-name = "glob"
-version = "0.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
-
-[[package]]
-name = "gloo-events"
-version = "0.1.2"
+name = "gloo-events"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc"
dependencies = [
@@ -1639,78 +1341,11 @@ dependencies = [
"web-sys",
]
-[[package]]
-name = "gloo-events"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41"
-dependencies = [
- "wasm-bindgen",
- "web-sys",
-]
-
-[[package]]
-name = "gloo-net"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580"
-dependencies = [
- "futures-channel",
- "futures-core",
- "futures-sink",
- "gloo-utils",
- "http",
- "js-sys",
- "pin-project",
- "serde",
- "serde_json",
- "thiserror 1.0.69",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
-]
-
-[[package]]
-name = "gloo-timers"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994"
-dependencies = [
- "futures-channel",
- "futures-core",
- "js-sys",
- "wasm-bindgen",
-]
-
-[[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 = "group"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
-dependencies = [
- "ff",
- "rand_core 0.6.4",
- "subtle",
-]
-
[[package]]
name = "h2"
-version = "0.4.10"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5"
+checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
dependencies = [
"atomic-waker",
"bytes",
@@ -1731,7 +1366,7 @@ version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"crunchy",
"zerocopy",
]
@@ -1748,15 +1383,21 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.15.4"
+version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
+checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
+[[package]]
+name = "hashbrown"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
+
[[package]]
name = "hashlink"
version = "0.8.4"
@@ -1778,15 +1419,6 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08"
-[[package]]
-name = "hkdf"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
-dependencies = [
- "hmac",
-]
-
[[package]]
name = "hmac"
version = "0.12.1"
@@ -1798,12 +1430,11 @@ dependencies = [
[[package]]
name = "http"
-version = "1.3.1"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
+checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
- "fnv",
"itoa",
]
@@ -1850,13 +1481,14 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
-version = "1.6.0"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
+checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
dependencies = [
+ "atomic-waker",
"bytes",
"futures-channel",
- "futures-util",
+ "futures-core",
"h2",
"http",
"http-body",
@@ -1871,15 +1503,14 @@ dependencies = [
[[package]]
name = "hyper-rustls"
-version = "0.27.7"
+version = "0.27.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
+checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
- "rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
@@ -1888,14 +1519,13 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.14"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
+checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-channel",
- "futures-core",
"futures-util",
"http",
"http-body",
@@ -1912,9 +1542,9 @@ dependencies = [
[[package]]
name = "iana-time-zone"
-version = "0.1.63"
+version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
+checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
@@ -1936,12 +1566,13 @@ dependencies = [
[[package]]
name = "icu_collections"
-version = "2.0.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
+checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
dependencies = [
"displaydoc",
"potential_utf",
+ "utf8_iter",
"yoke",
"zerofrom",
"zerovec",
@@ -1949,9 +1580,9 @@ dependencies = [
[[package]]
name = "icu_locale_core"
-version = "2.0.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
+checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
dependencies = [
"displaydoc",
"litemap",
@@ -1962,11 +1593,10 @@ dependencies = [
[[package]]
name = "icu_normalizer"
-version = "2.0.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
+checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
dependencies = [
- "displaydoc",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
@@ -1977,42 +1607,38 @@ dependencies = [
[[package]]
name = "icu_normalizer_data"
-version = "2.0.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
+checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
[[package]]
name = "icu_properties"
-version = "2.0.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
+checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
dependencies = [
- "displaydoc",
"icu_collections",
"icu_locale_core",
"icu_properties_data",
"icu_provider",
- "potential_utf",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_properties_data"
-version = "2.0.1"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
+checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
[[package]]
name = "icu_provider"
-version = "2.0.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
+checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
dependencies = [
"displaydoc",
"icu_locale_core",
- "stable_deref_trait",
- "tinystr",
"writeable",
"yoke",
"zerofrom",
@@ -2020,6 +1646,12 @@ dependencies = [
"zerovec",
]
+[[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -2028,9 +1660,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
-version = "1.0.3"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
+checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
dependencies = [
"idna_adapter",
"smallvec",
@@ -2039,9 +1671,9 @@ dependencies = [
[[package]]
name = "idna_adapter"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
dependencies = [
"icu_normalizer",
"icu_properties",
@@ -2049,25 +1681,30 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.9.0"
+version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
+checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
- "hashbrown 0.15.4",
+ "hashbrown 0.17.1",
+ "serde",
+ "serde_core",
]
[[package]]
name = "indoc"
-version = "2.0.6"
+version = "2.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
+checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
+dependencies = [
+ "rustversion",
+]
[[package]]
name = "instability"
-version = "0.3.7"
+version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d"
+checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971"
dependencies = [
"darling",
"indoc",
@@ -2078,24 +1715,24 @@ dependencies = [
[[package]]
name = "inventory"
-version = "0.3.20"
+version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83"
+checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b"
dependencies = [
"rustversion",
]
[[package]]
name = "ipnet"
-version = "2.11.0"
+version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
+checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
[[package]]
name = "iri-string"
-version = "0.7.8"
+version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
+checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20"
dependencies = [
"memchr",
"serde",
@@ -2109,15 +1746,9 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
dependencies = [
"hermit-abi",
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
-[[package]]
-name = "is_terminal_polyfill"
-version = "1.70.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
-
[[package]]
name = "itertools"
version = "0.10.5"
@@ -2138,16 +1769,18 @@ dependencies = [
[[package]]
name = "itoa"
-version = "1.0.15"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
-version = "0.3.77"
+version = "0.3.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
+checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
dependencies = [
+ "cfg-if",
+ "futures-util",
"once_cell",
"wasm-bindgen",
]
@@ -2164,48 +1797,37 @@ dependencies = [
]
[[package]]
-name = "jsonwebtoken"
-version = "10.3.0"
+name = "konst"
+version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1"
+checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb"
dependencies = [
- "base64 0.22.1",
- "ed25519-dalek",
- "getrandom 0.2.16",
- "hmac",
- "js-sys",
- "p256",
- "p384",
- "pem",
- "rand 0.8.5",
- "rsa",
- "serde",
- "serde_json",
- "sha2",
- "signature",
- "simple_asn1",
+ "konst_macro_rules",
]
+[[package]]
+name = "konst_macro_rules"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37"
+
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
-dependencies = [
- "spin",
-]
[[package]]
-name = "libc"
-version = "0.2.172"
+name = "leb128fmt"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
-name = "libm"
-version = "0.2.16"
+name = "libc"
+version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "linux-raw-sys"
@@ -2215,31 +1837,30 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
-version = "0.9.4"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]]
name = "litemap"
-version = "0.8.0"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
+checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
[[package]]
name = "lock_api"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
- "autocfg",
"scopeguard",
]
[[package]]
name = "log"
-version = "0.4.27"
+version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
+checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "lru"
@@ -2247,7 +1868,7 @@ version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
dependencies = [
- "hashbrown 0.15.4",
+ "hashbrown 0.15.5",
]
[[package]]
@@ -2258,11 +1879,11 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]]
name = "matchers"
-version = "0.1.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9"
dependencies = [
- "regex-automata 0.1.10",
+ "regex-automata",
]
[[package]]
@@ -2273,15 +1894,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "memchr"
-version = "2.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
-
-[[package]]
-name = "memory_units"
-version = "0.4.0"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "mime"
@@ -2299,41 +1914,22 @@ dependencies = [
"unicase",
]
-[[package]]
-name = "minicov"
-version = "0.3.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b"
-dependencies = [
- "cc",
- "walkdir",
-]
-
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
-[[package]]
-name = "miniz_oxide"
-version = "0.8.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
-dependencies = [
- "adler2",
-]
-
[[package]]
name = "mio"
-version = "1.0.4"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
+checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
dependencies = [
"libc",
"log",
- "wasi 0.11.0+wasi-snapshot-preview1",
- "windows-sys 0.59.0",
+ "wasi",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -2377,12 +1973,25 @@ dependencies = [
[[package]]
name = "nu-ansi-term"
-version = "0.46.0"
+version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
- "overload",
- "winapi",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "num"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23"
+dependencies = [
+ "num-bigint",
+ "num-complex",
+ "num-integer",
+ "num-iter",
+ "num-rational",
+ "num-traits",
]
[[package]]
@@ -2396,26 +2005,19 @@ dependencies = [
]
[[package]]
-name = "num-bigint-dig"
-version = "0.8.6"
+name = "num-complex"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7"
+checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
- "lazy_static",
- "libm",
- "num-integer",
- "num-iter",
"num-traits",
- "rand 0.8.5",
- "smallvec",
- "zeroize",
]
[[package]]
name = "num-conv"
-version = "0.1.0"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
[[package]]
name = "num-integer"
@@ -2438,23 +2040,23 @@ dependencies = [
]
[[package]]
-name = "num-traits"
-version = "0.2.19"
+name = "num-rational"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
- "autocfg",
- "libm",
+ "num-bigint",
+ "num-integer",
+ "num-traits",
]
[[package]]
-name = "num_cpus"
-version = "1.17.0"
+name = "num-traits"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
- "hermit-abi",
- "libc",
+ "autocfg",
]
[[package]]
@@ -2465,6 +2067,7 @@ dependencies = [
"ras-jsonrpc-core",
"ras-jsonrpc-macro",
"ras-jsonrpc-types",
+ "ras-permission-manifest",
"reqwest",
"schemars",
"serde",
@@ -2480,7 +2083,6 @@ dependencies = [
"axum",
"chrono",
"dotenvy",
- "jsonwebtoken",
"mime_guess",
"oauth2-demo-api",
"ras-identity-core",
@@ -2489,6 +2091,7 @@ dependencies = [
"ras-jsonrpc-core",
"ras-jsonrpc-macro",
"ras-jsonrpc-types",
+ "ras-permission-manifest",
"schemars",
"serde",
"serde_json",
@@ -2500,26 +2103,11 @@ dependencies = [
"uuid",
]
-[[package]]
-name = "object"
-version = "0.36.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
-dependencies = [
- "memchr",
-]
-
[[package]]
name = "once_cell"
-version = "1.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
-
-[[package]]
-name = "once_cell_polyfill"
-version = "1.70.1"
+version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
+checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "oorandom"
@@ -2527,80 +2115,49 @@ version = "11.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
-[[package]]
-name = "openrpc-to-bruno"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "clap",
- "openrpc-types",
- "serde",
- "serde_json",
- "tempfile",
- "thiserror 2.0.12",
- "tokio",
- "tokio-test",
-]
-
-[[package]]
-name = "openrpc-types"
-version = "0.1.1"
-dependencies = [
- "bon",
- "schemars",
- "serde",
- "serde_json",
- "thiserror 2.0.12",
- "tokio-test",
-]
-
[[package]]
name = "opentelemetry"
-version = "0.28.0"
+version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "236e667b670a5cdf90c258f5a55794ec5ac5027e960c224bff8367a59e1e6426"
+checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682"
dependencies = [
"futures-core",
"futures-sink",
"js-sys",
"pin-project-lite",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tracing",
]
[[package]]
name = "opentelemetry-prometheus"
-version = "0.28.0"
+version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "765a76ba13ec77043903322f85dc5434d7d01a37e75536d0f871ed7b9b5bbf0d"
+checksum = "2c0359983e7f79cf33c9abd89e5d7ddf67c46c419d0148598022d70e70c01aba"
dependencies = [
"once_cell",
"opentelemetry",
"opentelemetry_sdk",
"prometheus",
- "protobuf",
"tracing",
]
[[package]]
name = "opentelemetry_sdk"
-version = "0.28.0"
+version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84dfad6042089c7fc1f6118b7040dc2eb4ab520abbf410b79dc481032af39570"
+checksum = "368afaed344110f40b179bb8fbe54bc52d98f9bd2b281799ef32487c2650c956"
dependencies = [
- "async-trait",
"futures-channel",
"futures-executor",
"futures-util",
- "glob",
"opentelemetry",
"percent-encoding",
- "rand 0.8.5",
- "serde_json",
- "thiserror 2.0.12",
+ "portable-atomic",
+ "rand 0.9.4",
+ "thiserror 2.0.18",
"tokio",
"tokio-stream",
- "tracing",
]
[[package]]
@@ -2613,41 +2170,11 @@ dependencies = [
"hashbrown 0.14.5",
]
-[[package]]
-name = "overload"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
-
-[[package]]
-name = "p256"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
-dependencies = [
- "ecdsa",
- "elliptic-curve",
- "primeorder",
- "sha2",
-]
-
-[[package]]
-name = "p384"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6"
-dependencies = [
- "ecdsa",
- "elliptic-curve",
- "primeorder",
- "sha2",
-]
-
[[package]]
name = "parking_lot"
-version = "0.12.4"
+version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
+checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -2655,15 +2182,15 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.11"
+version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
+checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"libc",
"redox_syscall",
"smallvec",
- "windows-targets",
+ "windows-link",
]
[[package]]
@@ -2689,30 +2216,11 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
-[[package]]
-name = "pem"
-version = "3.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
-dependencies = [
- "base64 0.22.1",
- "serde",
-]
-
-[[package]]
-name = "pem-rfc7468"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
-dependencies = [
- "base64ct",
-]
-
[[package]]
name = "percent-encoding"
-version = "2.3.1"
+version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pest"
@@ -2721,7 +2229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6"
dependencies = [
"memchr",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"ucd-trie",
]
@@ -2776,7 +2284,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [
"phf_shared",
- "rand 0.8.5",
+ "rand 0.8.6",
]
[[package]]
@@ -2803,18 +2311,18 @@ dependencies = [
[[package]]
name = "pin-project"
-version = "1.1.10"
+version = "1.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a"
+checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.1.10"
+version = "1.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
+checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
dependencies = [
"proc-macro2",
"quote",
@@ -2823,36 +2331,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
-
-[[package]]
-name = "pin-utils"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
-
-[[package]]
-name = "pkcs1"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
-dependencies = [
- "der",
- "pkcs8",
- "spki",
-]
-
-[[package]]
-name = "pkcs8"
-version = "0.10.2"
+version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
-dependencies = [
- "der",
- "spki",
-]
+checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "playwright-jsonrpc-fixture"
@@ -2860,10 +2341,12 @@ version = "0.0.0"
dependencies = [
"anyhow",
"axum",
+ "axum-test",
"ras-auth-core",
"ras-jsonrpc-core",
"ras-jsonrpc-macro",
"ras-jsonrpc-types",
+ "ras-permission-manifest",
"reqwest",
"schemars",
"serde",
@@ -2879,7 +2362,9 @@ dependencies = [
"async-trait",
"axum",
"axum-extra",
+ "axum-test",
"ras-auth-core",
+ "ras-permission-manifest",
"ras-rest-core",
"ras-rest-macro",
"reqwest",
@@ -2918,11 +2403,17 @@ dependencies = [
"plotters-backend",
]
+[[package]]
+name = "portable-atomic"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
+
[[package]]
name = "potential_utf"
-version = "0.1.2"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
+checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
dependencies = [
"zerovec",
]
@@ -2954,52 +2445,57 @@ dependencies = [
[[package]]
name = "prettyplease"
-version = "0.2.33"
+version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d"
+checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
-[[package]]
-name = "primeorder"
-version = "0.13.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
-dependencies = [
- "elliptic-curve",
-]
-
[[package]]
name = "proc-macro2"
-version = "1.0.95"
+version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "prometheus"
-version = "0.13.4"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1"
+checksum = "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"fnv",
"lazy_static",
"memchr",
"parking_lot",
"protobuf",
- "thiserror 1.0.69",
+ "thiserror 2.0.18",
]
[[package]]
name = "protobuf"
-version = "2.28.0"
+version = "3.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4"
+dependencies = [
+ "once_cell",
+ "protobuf-support",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "protobuf-support"
+version = "3.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
+checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6"
+dependencies = [
+ "thiserror 1.0.69",
+]
[[package]]
name = "quinn"
@@ -3015,7 +2511,7 @@ dependencies = [
"rustc-hash",
"rustls",
"socket2",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
"tracing",
"web-time",
@@ -3028,15 +2524,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
dependencies = [
"bytes",
- "getrandom 0.3.3",
+ "getrandom 0.3.4",
"lru-slab",
- "rand 0.9.1",
+ "rand 0.9.4",
"ring",
"rustc-hash",
"rustls",
"rustls-pki-types",
"slab",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tinyvec",
"tracing",
"web-time",
@@ -3053,29 +2549,35 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
name = "quote"
-version = "1.0.40"
+version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
-version = "5.2.0"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
+[[package]]
+name = "r-efi"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
dependencies = [
"libc",
"rand_chacha 0.3.1",
@@ -3084,12 +2586,12 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.9.1"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
+checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
dependencies = [
"rand_chacha 0.9.0",
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
@@ -3109,7 +2611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
- "rand_core 0.9.3",
+ "rand_core 0.9.5",
]
[[package]]
@@ -3118,25 +2620,39 @@ version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
- "getrandom 0.2.16",
+ "getrandom 0.2.17",
]
[[package]]
name = "rand_core"
-version = "0.9.3"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
+checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
- "getrandom 0.3.3",
+ "getrandom 0.3.4",
]
[[package]]
name = "ras-auth-core"
version = "0.1.0"
dependencies = [
+ "cookie",
+ "http",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
+]
+
+[[package]]
+name = "ras-file-core"
+version = "0.1.0"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-util",
+ "http",
+ "ras-auth-core",
+ "thiserror 2.0.18",
]
[[package]]
@@ -3150,14 +2666,15 @@ dependencies = [
"proc-macro2",
"quote",
"ras-auth-core",
- "ras-test-helpers",
+ "ras-file-core",
+ "ras-permission-manifest",
"reqwest",
"schemars",
"serde",
"serde_json",
"syn",
"tempfile",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
"tokio-util",
]
@@ -3169,13 +2686,13 @@ dependencies = [
"async-trait",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
]
[[package]]
name = "ras-identity-local"
-version = "0.1.1"
+version = "0.2.0"
dependencies = [
"argon2",
"async-trait",
@@ -3184,47 +2701,47 @@ dependencies = [
"serde",
"serde_json",
"tokio",
- "tokio-test",
]
[[package]]
name = "ras-identity-oauth2"
-version = "0.1.1"
+version = "0.1.2"
dependencies = [
"async-trait",
"axum",
+ "axum-test",
"base64 0.22.1",
"chrono",
- "rand 0.8.5",
+ "rand 0.8.6",
"ras-identity-core",
"ras-identity-session",
"reqwest",
"serde",
"serde_json",
"sha2",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
- "tokio-test",
"tracing",
"tracing-subscriber",
"url",
"uuid",
- "wiremock",
]
[[package]]
name = "ras-identity-session"
-version = "0.1.1"
+version = "0.2.0"
dependencies = [
"async-trait",
+ "base64 0.22.1",
"chrono",
- "jsonwebtoken",
+ "hmac",
"ras-auth-core",
"ras-identity-core",
"ras-identity-local",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "sha2",
+ "thiserror 2.0.18",
"tokio",
"uuid",
]
@@ -3241,24 +2758,21 @@ dependencies = [
"futures",
"http",
"js-sys",
- "rand 0.8.5",
+ "rand 0.8.6",
"ras-auth-core",
"ras-jsonrpc-bidirectional-types",
"ras-jsonrpc-types",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
- "tokio-test",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.26.2",
"tracing",
"tracing-subscriber",
"url",
- "uuid",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
- "wiremock",
]
[[package]]
@@ -3274,19 +2788,19 @@ dependencies = [
"http",
"proc-macro2",
"quote",
- "rand 0.8.5",
+ "rand 0.8.6",
"ras-auth-core",
"ras-jsonrpc-bidirectional-client",
"ras-jsonrpc-bidirectional-server",
"ras-jsonrpc-bidirectional-types",
"ras-jsonrpc-types",
- "ras-test-helpers",
+ "ras-permission-manifest",
"serde",
"serde_json",
"syn",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.26.2",
"url",
"uuid",
]
@@ -3306,9 +2820,8 @@ dependencies = [
"ras-jsonrpc-types",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
- "tokio-test",
"tracing",
]
@@ -3323,10 +2836,9 @@ dependencies = [
"ras-jsonrpc-types",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
- "tokio-test",
- "tokio-tungstenite",
+ "tokio-tungstenite 0.26.2",
"tracing",
"uuid",
]
@@ -3340,7 +2852,7 @@ dependencies = [
"ras-version-core",
"serde",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
]
[[package]]
@@ -3355,12 +2867,12 @@ dependencies = [
"futures",
"proc-macro2",
"quote",
- "rand 0.8.5",
+ "rand 0.8.6",
"ras-auth-core",
"ras-identity-session",
"ras-jsonrpc-core",
"ras-jsonrpc-types",
- "ras-test-helpers",
+ "ras-permission-manifest",
"reqwest",
"schemars",
"serde",
@@ -3410,6 +2922,24 @@ dependencies = [
"tracing-subscriber",
]
+[[package]]
+name = "ras-openrpc-types"
+version = "0.1.1"
+dependencies = [
+ "bon",
+ "schemars",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "ras-permission-manifest"
+version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "ras-rest-core"
version = "0.1.1"
@@ -3417,7 +2947,7 @@ dependencies = [
"ras-auth-core",
"ras-version-core",
"serde",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
]
[[package]]
@@ -3431,15 +2961,14 @@ dependencies = [
"chrono",
"criterion",
"futures",
- "hyper",
"proc-macro2",
"quote",
- "rand 0.8.5",
+ "rand 0.8.6",
"ras-auth-core",
"ras-identity-session",
"ras-jsonrpc-core",
+ "ras-permission-manifest",
"ras-rest-core",
- "ras-test-helpers",
"reqwest",
"schemars",
"serde",
@@ -3448,17 +2977,6 @@ dependencies = [
"tokio",
"tower",
"tracing",
- "wiremock",
-]
-
-[[package]]
-name = "ras-test-helpers"
-version = "0.0.0"
-dependencies = [
- "axum",
- "axum-test",
- "ras-auth-core",
- "tokio",
]
[[package]]
@@ -3508,27 +3026,27 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.5.12"
+version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags",
]
[[package]]
name = "ref-cast"
-version = "1.0.24"
+version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
+checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
dependencies = [
"ref-cast-impl",
]
[[package]]
name = "ref-cast-impl"
-version = "1.0.24"
+version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
+checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
@@ -3537,53 +3055,38 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.11.1"
+version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
dependencies = [
"aho-corasick",
"memchr",
- "regex-automata 0.4.9",
- "regex-syntax 0.8.5",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
-dependencies = [
- "regex-syntax 0.6.29",
+ "regex-automata",
+ "regex-syntax",
]
[[package]]
name = "regex-automata"
-version = "0.4.9"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
dependencies = [
"aho-corasick",
"memchr",
- "regex-syntax 0.8.5",
+ "regex-syntax",
]
[[package]]
name = "regex-syntax"
-version = "0.6.29"
+version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "reqwest"
-version = "0.12.19"
+version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119"
+checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [
"base64 0.22.1",
"bytes",
@@ -3597,12 +3100,10 @@ dependencies = [
"hyper",
"hyper-rustls",
"hyper-util",
- "ipnet",
"js-sys",
"log",
"mime",
"mime_guess",
- "once_cell",
"percent-encoding",
"pin-project-lite",
"quinn",
@@ -3628,11 +3129,11 @@ dependencies = [
[[package]]
name = "reserve-port"
-version = "2.3.0"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356"
+checksum = "94070964579245eb2f76e62a7668fe87bd9969ed6c41256f3bf614e3323dd3cc"
dependencies = [
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
]
[[package]]
@@ -3642,23 +3143,17 @@ dependencies = [
"async-trait",
"axum",
"axum-extra",
- "http",
- "js-sys",
"ras-auth-core",
+ "ras-permission-manifest",
"ras-rest-core",
"ras-rest-macro",
"reqwest",
"schemars",
"serde",
- "serde-wasm-bindgen",
"serde_json",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"tokio",
- "tower",
"tracing",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "web-sys",
]
[[package]]
@@ -3671,6 +3166,7 @@ dependencies = [
"axum-extra",
"http",
"ras-auth-core",
+ "ras-permission-manifest",
"ras-rest-core",
"rest-api",
"serde",
@@ -3683,16 +3179,6 @@ dependencies = [
"uuid",
]
-[[package]]
-name = "rfc6979"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
-dependencies = [
- "hmac",
- "subtle",
-]
-
[[package]]
name = "ring"
version = "0.17.14"
@@ -3700,8 +3186,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
- "cfg-if 1.0.0",
- "getrandom 0.2.16",
+ "cfg-if",
+ "getrandom 0.2.17",
"libc",
"untrusted",
"windows-sys 0.52.0",
@@ -3719,33 +3205,13 @@ dependencies = [
"serde_derive",
]
-[[package]]
-name = "rsa"
-version = "0.9.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
-dependencies = [
- "const-oid",
- "digest",
- "num-bigint-dig",
- "num-integer",
- "num-traits",
- "pkcs1",
- "pkcs8",
- "rand_core 0.6.4",
- "signature",
- "spki",
- "subtle",
- "zeroize",
-]
-
[[package]]
name = "rust-ini"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"ordered-multimap",
]
@@ -3760,31 +3226,16 @@ dependencies = [
"futures-util",
"http",
"mime",
- "rand 0.9.1",
- "thiserror 2.0.12",
+ "rand 0.9.4",
+ "thiserror 2.0.18",
]
-[[package]]
-name = "rustc-demangle"
-version = "0.1.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
-
[[package]]
name = "rustc-hash"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
[[package]]
name = "rustix"
version = "0.38.44"
@@ -3800,22 +3251,22 @@ dependencies = [
[[package]]
name = "rustix"
-version = "1.0.7"
+version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
+checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [
"bitflags",
"errno",
"libc",
- "linux-raw-sys 0.9.4",
- "windows-sys 0.59.0",
+ "linux-raw-sys 0.12.1",
+ "windows-sys 0.61.2",
]
[[package]]
name = "rustls"
-version = "0.23.27"
+version = "0.23.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
+checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21"
dependencies = [
"once_cell",
"ring",
@@ -3827,9 +3278,9 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.12.0"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
+checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
dependencies = [
"web-time",
"zeroize",
@@ -3837,9 +3288,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
-version = "0.103.3"
+version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
+checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
dependencies = [
"ring",
"rustls-pki-types",
@@ -3848,15 +3299,15 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.21"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
-version = "1.0.20"
+version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
+checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "same-file"
@@ -3869,9 +3320,9 @@ dependencies = [
[[package]]
name = "schemars"
-version = "1.0.0-alpha.20"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8682cd6af1ec0d28c9bcdb7fb47e514e837a15fbb336a8609214e551fb11e078"
+checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
dependencies = [
"dyn-clone",
"ref-cast",
@@ -3882,9 +3333,9 @@ dependencies = [
[[package]]
name = "schemars_derive"
-version = "1.0.0-alpha.20"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ed487625503023cae17e0e8654edd6b4e48dbd72c3e2fb3e6c11abcaf35d380"
+checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f"
dependencies = [
"proc-macro2",
"quote",
@@ -3898,20 +3349,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-[[package]]
-name = "sec1"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
-dependencies = [
- "base16ct",
- "der",
- "generic-array",
- "pkcs8",
- "subtle",
- "zeroize",
-]
-
[[package]]
name = "semver"
version = "1.0.28"
@@ -3972,37 +3409,39 @@ dependencies = [
[[package]]
name = "serde_html_form"
-version = "0.2.7"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4"
+checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f"
dependencies = [
"form_urlencoded",
"indexmap",
"itoa",
"ryu",
- "serde",
+ "serde_core",
]
[[package]]
name = "serde_json"
-version = "1.0.140"
+version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
- "ryu",
"serde",
+ "serde_core",
+ "zmij",
]
[[package]]
name = "serde_path_to_error"
-version = "0.1.17"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
+checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
dependencies = [
"itoa",
"serde",
+ "serde_core",
]
[[package]]
@@ -4032,7 +3471,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"cpufeatures",
"digest",
]
@@ -4043,7 +3482,7 @@ version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"cpufeatures",
"digest",
]
@@ -4075,9 +3514,9 @@ dependencies = [
[[package]]
name = "signal-hook-mio"
-version = "0.2.4"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
+checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
dependencies = [
"libc",
"mio",
@@ -4086,49 +3525,25 @@ dependencies = [
[[package]]
name = "signal-hook-registry"
-version = "1.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "signature"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
-dependencies = [
- "digest",
- "rand_core 0.6.4",
-]
-
-[[package]]
-name = "simple_asn1"
-version = "0.6.3"
+version = "1.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb"
+checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
dependencies = [
- "num-bigint",
- "num-traits",
- "thiserror 2.0.12",
- "time",
+ "errno",
+ "libc",
]
[[package]]
name = "siphasher"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
[[package]]
name = "slab"
-version = "0.4.9"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
-dependencies = [
- "autocfg",
-]
+checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "smallvec"
@@ -4138,12 +3553,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
-version = "0.5.10"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
+checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -4152,21 +3567,11 @@ version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-[[package]]
-name = "spki"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
-dependencies = [
- "base64ct",
- "der",
-]
-
[[package]]
name = "stable_deref_trait"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]]
name = "static_assertions"
@@ -4210,9 +3615,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
-version = "2.0.101"
+version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
@@ -4241,15 +3646,15 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "3.20.0"
+version = "3.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
+checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
- "getrandom 0.3.3",
+ "getrandom 0.4.2",
"once_cell",
- "rustix 1.0.7",
- "windows-sys 0.59.0",
+ "rustix 1.1.4",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -4263,11 +3668,11 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "2.0.12"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
- "thiserror-impl 2.0.12",
+ "thiserror-impl 2.0.18",
]
[[package]]
@@ -4283,9 +3688,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
-version = "2.0.12"
+version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
@@ -4294,40 +3699,39 @@ dependencies = [
[[package]]
name = "thread_local"
-version = "1.1.8"
+version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
dependencies = [
- "cfg-if 1.0.0",
- "once_cell",
+ "cfg-if",
]
[[package]]
name = "time"
-version = "0.3.41"
+version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
- "serde",
+ "serde_core",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
-version = "0.1.4"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
[[package]]
name = "time-macros"
-version = "0.2.22"
+version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
dependencies = [
"num-conv",
"time-core",
@@ -4344,9 +3748,9 @@ dependencies = [
[[package]]
name = "tinystr"
-version = "0.8.1"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
+checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
dependencies = [
"displaydoc",
"zerovec",
@@ -4379,11 +3783,10 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.45.1"
+version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
+checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
- "backtrace",
"bytes",
"libc",
"mio",
@@ -4392,14 +3795,14 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
- "windows-sys 0.52.0",
+ "windows-sys 0.61.2",
]
[[package]]
name = "tokio-macros"
-version = "2.5.0"
+version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
+checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
@@ -4408,9 +3811,9 @@ dependencies = [
[[package]]
name = "tokio-rustls"
-version = "0.26.2"
+version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
+checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [
"rustls",
"tokio",
@@ -4418,9 +3821,9 @@ dependencies = [
[[package]]
name = "tokio-stream"
-version = "0.1.17"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047"
+checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70"
dependencies = [
"futures-core",
"pin-project-lite",
@@ -4428,35 +3831,34 @@ dependencies = [
]
[[package]]
-name = "tokio-test"
-version = "0.4.4"
+name = "tokio-tungstenite"
+version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7"
+checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
dependencies = [
- "async-stream",
- "bytes",
- "futures-core",
+ "futures-util",
+ "log",
"tokio",
- "tokio-stream",
+ "tungstenite 0.26.2",
]
[[package]]
name = "tokio-tungstenite"
-version = "0.26.2"
+version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084"
+checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c"
dependencies = [
"futures-util",
"log",
"tokio",
- "tungstenite",
+ "tungstenite 0.29.0",
]
[[package]]
name = "tokio-util"
-version = "0.7.15"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
+checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
@@ -4508,9 +3910,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
[[package]]
name = "tower"
-version = "0.5.2"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
+checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
@@ -4524,9 +3926,9 @@ dependencies = [
[[package]]
name = "tower-http"
-version = "0.6.6"
+version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
+checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"bitflags",
"bytes",
@@ -4564,9 +3966,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
-version = "0.1.41"
+version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
+checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
"log",
"pin-project-lite",
@@ -4576,9 +3978,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
-version = "0.1.29"
+version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
+checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
dependencies = [
"proc-macro2",
"quote",
@@ -4587,9 +3989,9 @@ dependencies = [
[[package]]
name = "tracing-core"
-version = "0.1.34"
+version = "0.1.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
+checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
dependencies = [
"once_cell",
"valuable",
@@ -4608,14 +4010,14 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
-version = "0.3.19"
+version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
+checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
- "regex",
+ "regex-automata",
"sharded-slab",
"smallvec",
"thread_local",
@@ -4641,12 +4043,28 @@ dependencies = [
"http",
"httparse",
"log",
- "rand 0.9.1",
+ "rand 0.9.4",
"sha1",
- "thiserror 2.0.12",
+ "thiserror 2.0.18",
"utf-8",
]
+[[package]]
+name = "tungstenite"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8"
+dependencies = [
+ "bytes",
+ "data-encoding",
+ "http",
+ "httparse",
+ "log",
+ "rand 0.9.4",
+ "sha1",
+ "thiserror 2.0.18",
+]
+
[[package]]
name = "typeid"
version = "1.0.3"
@@ -4655,15 +4073,15 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "typenum"
-version = "1.18.0"
+version = "1.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
+checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
[[package]]
name = "typetag"
-version = "0.2.20"
+version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f"
+checksum = "c5a897b12c6c1151ad0b138b8db50252dc301f93bc3b027db05eec82aeed298c"
dependencies = [
"erased-serde",
"inventory",
@@ -4674,9 +4092,9 @@ dependencies = [
[[package]]
name = "typetag-impl"
-version = "0.2.20"
+version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952"
+checksum = "cf808357c6ed7e13ba0f3277ec8d8f21b2d501274895104263985330c726c1c5"
dependencies = [
"proc-macro2",
"quote",
@@ -4691,21 +4109,21 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unicase"
-version = "2.8.1"
+version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
+checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]]
name = "unicode-ident"
-version = "1.0.18"
+version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-segmentation"
-version = "1.12.0"
+version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
+checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]]
name = "unicode-truncate"
@@ -4744,13 +4162,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
-version = "2.5.4"
+version = "2.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
+checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
+ "serde",
]
[[package]]
@@ -4765,21 +4184,15 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
-[[package]]
-name = "utf8parse"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
-
[[package]]
name = "uuid"
-version = "1.17.0"
+version = "1.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
+checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
dependencies = [
- "getrandom 0.3.3",
+ "getrandom 0.4.2",
"js-sys",
- "serde",
+ "serde_core",
"wasm-bindgen",
]
@@ -4816,63 +4229,56 @@ dependencies = [
[[package]]
name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
-name = "wasi"
-version = "0.14.2+wasi-0.2.4"
+name = "wasip2"
+version = "1.0.3+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
+checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
dependencies = [
- "wit-bindgen-rt",
+ "wit-bindgen 0.57.1",
]
[[package]]
-name = "wasm-bindgen"
-version = "0.2.100"
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
- "cfg-if 1.0.0",
- "once_cell",
- "rustversion",
- "wasm-bindgen-macro",
+ "wit-bindgen 0.51.0",
]
[[package]]
-name = "wasm-bindgen-backend"
-version = "0.2.100"
+name = "wasm-bindgen"
+version = "0.2.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
+checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
dependencies = [
- "bumpalo",
- "log",
- "proc-macro2",
- "quote",
- "syn",
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.50"
+version = "0.4.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
+checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8"
dependencies = [
- "cfg-if 1.0.0",
"js-sys",
- "once_cell",
"wasm-bindgen",
- "web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.100"
+version = "0.2.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
+checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -4880,48 +4286,46 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.100"
+version = "0.2.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
+checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
dependencies = [
+ "bumpalo",
"proc-macro2",
"quote",
"syn",
- "wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.100"
+version = "0.2.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
+checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
dependencies = [
"unicode-ident",
]
[[package]]
-name = "wasm-bindgen-test"
-version = "0.3.50"
+name = "wasm-encoder"
+version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3"
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
dependencies = [
- "js-sys",
- "minicov",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wasm-bindgen-test-macro",
+ "leb128fmt",
+ "wasmparser",
]
[[package]]
-name = "wasm-bindgen-test-macro"
-version = "0.3.50"
+name = "wasm-metadata"
+version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b"
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
]
[[package]]
@@ -4947,26 +4351,29 @@ dependencies = [
"dwind",
"dwind-macros",
"futures-signals",
- "gloo-events 0.2.0",
- "gloo-net",
- "gloo-timers",
- "gloo-utils",
"once_cell",
- "reqwest",
- "serde",
- "serde_json",
"wasm-bindgen",
"wasm-bindgen-futures",
- "wasm-bindgen-test",
"web-sys",
- "wee_alloc",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
]
[[package]]
name = "web-sys"
-version = "0.3.77"
+version = "0.3.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
+checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -4984,25 +4391,13 @@ dependencies = [
[[package]]
name = "webpki-roots"
-version = "1.0.7"
+version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d"
+checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
dependencies = [
"rustls-pki-types",
]
-[[package]]
-name = "wee_alloc"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e"
-dependencies = [
- "cfg-if 0.1.10",
- "libc",
- "memory_units",
- "winapi",
-]
-
[[package]]
name = "winapi"
version = "0.3.9"
@@ -5021,11 +4416,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.9"
+version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -5036,9 +4431,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
-version = "0.61.2"
+version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
+checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
@@ -5049,9 +4444,9 @@ dependencies = [
[[package]]
name = "windows-implement"
-version = "0.60.0"
+version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
+checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
@@ -5060,9 +4455,9 @@ dependencies = [
[[package]]
name = "windows-interface"
-version = "0.59.1"
+version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
+checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
@@ -5071,24 +4466,24 @@ dependencies = [
[[package]]
name = "windows-link"
-version = "0.1.1"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
-version = "0.3.4"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
-version = "0.4.2"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
+checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
@@ -5099,7 +4494,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -5108,7 +4503,25 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.5",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
]
[[package]]
@@ -5117,14 +4530,31 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_gnullvm",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
+dependencies = [
+ "windows-link",
+ "windows_aarch64_gnullvm 0.53.1",
+ "windows_aarch64_msvc 0.53.1",
+ "windows_i686_gnu 0.53.1",
+ "windows_i686_gnullvm 0.53.1",
+ "windows_i686_msvc 0.53.1",
+ "windows_x86_64_gnu 0.53.1",
+ "windows_x86_64_gnullvm 0.53.1",
+ "windows_x86_64_msvc 0.53.1",
]
[[package]]
@@ -5133,95 +4563,204 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
+
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
+
[[package]]
name = "winnow"
-version = "0.7.11"
+version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
+checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
dependencies = [
"memchr",
]
[[package]]
-name = "wiremock"
-version = "0.6.3"
+name = "wit-bindgen"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "101681b74cd87b5899e87bcf5a64e83334dd313fcd3053ea72e6dba18928e301"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
- "assert-json-diff",
- "async-trait",
- "base64 0.22.1",
- "deadpool",
- "futures",
- "http",
- "http-body-util",
- "hyper",
- "hyper-util",
+ "wit-bindgen-rust-macro",
+]
+
+[[package]]
+name = "wit-bindgen"
+version = "0.57.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
+
+[[package]]
+name = "wit-bindgen-core"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
+
+[[package]]
+name = "wit-bindgen-rust"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
+
+[[package]]
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
+
+[[package]]
+name = "wit-component"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
+dependencies = [
+ "anyhow",
+ "bitflags",
+ "indexmap",
"log",
- "once_cell",
- "regex",
"serde",
+ "serde_derive",
"serde_json",
- "tokio",
- "url",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
]
[[package]]
-name = "wit-bindgen-rt"
-version = "0.39.0"
+name = "wit-parser"
+version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
dependencies = [
- "bitflags",
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid",
+ "wasmparser",
]
[[package]]
name = "writeable"
-version = "0.6.1"
+version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
+checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
[[package]]
name = "yaml-rust2"
@@ -5242,11 +4781,10 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yoke"
-version = "0.8.0"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
+checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
dependencies = [
- "serde",
"stable_deref_trait",
"yoke-derive",
"zerofrom",
@@ -5254,9 +4792,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
-version = "0.8.0"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
+checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
@@ -5286,18 +4824,18 @@ dependencies = [
[[package]]
name = "zerofrom"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
dependencies = [
"proc-macro2",
"quote",
@@ -5307,15 +4845,15 @@ dependencies = [
[[package]]
name = "zeroize"
-version = "1.8.1"
+version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
+checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
[[package]]
name = "zerotrie"
-version = "0.2.2"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
+checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
dependencies = [
"displaydoc",
"yoke",
@@ -5324,9 +4862,9 @@ dependencies = [
[[package]]
name = "zerovec"
-version = "0.11.2"
+version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
+checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
dependencies = [
"yoke",
"zerofrom",
@@ -5335,11 +4873,17 @@ dependencies = [
[[package]]
name = "zerovec-derive"
-version = "0.11.1"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
+checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
+
+[[package]]
+name = "zmij"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
diff --git a/Cargo.toml b/Cargo.toml
index 8f0ba42..945c112 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,8 +9,6 @@ members = [
"crates/rpc/ras-jsonrpc-macro",
"crates/rpc/ras-jsonrpc-types",
"crates/specs/*",
- "crates/test-utils/*",
- "crates/tools/*",
"examples/basic-jsonrpc/*",
"examples/bidirectional-chat/api",
"examples/bidirectional-chat/server",
@@ -31,55 +29,45 @@ anyhow = "1.0"
async-trait = "0.1"
axum-extra = { version = "0.10", features = ["query"] }
base64 = "0.22"
+bytes = "1.0"
bon = "3.2"
-console = "0.15"
console_error_panic_hook = "0.1"
criterion = "0.5"
+cookie = "0.18"
crossterm = "0.28"
dashmap = "6.1"
-dialoguer = "0.11"
dominator = "0.5"
dotenvy = "0.15"
dwind = "0.3.2"
dwind-macros = "0.2.2"
-dwui = "0.4.0"
futures = "0.3"
-futures-signals = "0.3"
-futures-signals-component-macro = "0.4.0"
+futures-core = "0.3"
futures-util = "0.3"
-gloo-events = "0.2"
-gloo-net = "0.6"
-gloo-utils = "0.2"
+futures-signals = "0.3"
http = "1.0"
+hmac = "0.12"
js-sys = "0.3"
-jsonwebtoken = { version = "10.3", features = ["rust_crypto"] }
mime_guess = "2.0"
once_cell = "1.20"
-opentelemetry = "0.28"
-opentelemetry-prometheus = "0.28"
+opentelemetry = "0.32"
+opentelemetry-prometheus = "0.32"
proc-macro2 = "1.0"
-prometheus = "0.13"
+prometheus = "0.14"
quote = "1.0"
rand = "0.8"
ratatui = "0.29"
-rust-embed = "8.0"
schemars = "1.0.0-alpha.20"
serde_json = "1.0"
sha2 = "0.10"
tempfile = "3.13"
thiserror = "2.0"
-tokio-test = "0.4"
tokio-tungstenite = "0.26"
-toml = "0.8"
tower-http = "0.6"
tracing = "0.1"
url = "2.5"
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
-wasm-bindgen-test = "0.3"
web-sys = "0.3"
-wee_alloc = "0.4"
-wiremock = "0.6"
[workspace.dependencies.argon2]
version = "0.5"
@@ -90,30 +78,18 @@ version = "0.8"
features = ["multipart"]
[workspace.dependencies.axum-test]
-version = "18.0.0-rc3"
+version = "18.7.0"
[workspace.dependencies.chrono]
version = "0.4"
features = ["serde"]
-[workspace.dependencies.clap]
-version = "4.5.39"
-features = ["derive"]
-
[workspace.dependencies.config]
version = "0.14"
features = ["toml"]
-[workspace.dependencies.gloo-timers]
-version = "0.3"
-features = ["futures"]
-
-[workspace.dependencies.hyper]
-version = "1.0"
-features = ["full"]
-
[workspace.dependencies.opentelemetry_sdk]
-version = "0.28"
+version = "0.32"
features = ["rt-tokio", "metrics"]
[workspace.dependencies.rand_core]
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..ccdfdfa
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,161 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the
+copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other
+entities that control, are controlled by, or are under common control with
+that entity. For the purposes of this definition, "control" means (i) the
+power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation source, and
+configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object
+code, generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form,
+made available under the License, as indicated by a copyright notice that is
+included in or attached to the work (an example is provided in the Appendix
+below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative
+Works shall not include works that remain separable from, or merely link (or
+bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original
+version of the Work and any modifications or additions to that Work or
+Derivative Works thereof, that is intentionally submitted to Licensor for
+inclusion in the Work by the copyright owner or by an individual or Legal
+Entity authorized to submit on behalf of the copyright owner. For the purposes
+of this definition, "submitted" means any form of electronic, verbal, or
+written communication sent to the Licensor or its representatives, including
+but not limited to communication on electronic mailing lists, source code
+control systems, and issue tracking systems that are managed by, or on behalf
+of, the Licensor for the purpose of discussing and improving the Work, but
+excluding communication that is conspicuously marked or otherwise designated
+in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this
+License, each Contributor hereby grants to You a perpetual, worldwide,
+non-exclusive, no-charge, royalty-free, irrevocable copyright license to
+reproduce, prepare Derivative Works of, publicly display, publicly perform,
+sublicense, and distribute the Work and such Derivative Works in Source or
+Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this
+License, each Contributor hereby grants to You a perpetual, worldwide,
+non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
+section) patent license to make, have made, use, offer to sell, sell, import,
+and otherwise transfer the Work, where such license applies only to those
+patent claims licensable by such Contributor that are necessarily infringed by
+their Contribution(s) alone or by combination of their Contribution(s) with
+the Work to which such Contribution(s) was submitted. If You institute patent
+litigation against any entity (including a cross-claim or counterclaim in a
+lawsuit) alleging that the Work or a Contribution incorporated within the Work
+constitutes direct or contributory patent infringement, then any patent
+licenses granted to You under this License for that Work shall terminate as of
+the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or
+Derivative Works thereof in any medium, with or without modifications, and in
+Source or Object form, provided that You meet the following conditions:
+
+(a) You must give any other recipients of the Work or Derivative Works a copy
+of this License; and
+
+(b) You must cause any modified files to carry prominent notices stating that
+You changed the files; and
+
+(c) You must retain, in the Source form of any Derivative Works that You
+distribute, all copyright, patent, trademark, and attribution notices from the
+Source form of the Work, excluding those notices that do not pertain to any
+part of the Derivative Works; and
+
+(d) If the Work includes a "NOTICE" text file as part of its distribution,
+then any Derivative Works that You distribute must include a readable copy of
+the attribution notices contained within such NOTICE file, excluding those
+notices that do not pertain to any part of the Derivative Works, in at least
+one of the following places: within a NOTICE text file distributed as part of
+the Derivative Works; within the Source form or documentation, if provided
+along with the Derivative Works; or within a display generated by the
+Derivative Works, if and wherever such third-party notices normally appear.
+The contents of the NOTICE file are for informational purposes only and do not
+modify the License. You may add Your own attribution notices within Derivative
+Works that You distribute, alongside or as an addendum to the NOTICE text from
+the Work, provided that such additional attribution notices cannot be construed
+as modifying the License.
+
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a
+whole, provided Your use, reproduction, and distribution of the Work otherwise
+complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any
+Contribution intentionally submitted for inclusion in the Work by You to the
+Licensor shall be under the terms and conditions of this License, without any
+additional terms or conditions. Notwithstanding the above, nothing herein
+shall supersede or modify the terms of any separate license agreement you may
+have executed with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names,
+trademarks, service marks, or product names of the Licensor, except as
+required for reasonable and customary use in describing the origin of the Work
+and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in
+writing, Licensor provides the Work (and each Contributor provides its
+Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied, including, without limitation, any warranties
+or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any risks
+associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in
+tort (including negligence), contract, or otherwise, unless required by
+applicable law (such as deliberate and grossly negligent acts) or agreed to in
+writing, shall any Contributor be liable to You for damages, including any
+direct, indirect, special, incidental, or consequential damages of any
+character arising as a result of this License or out of the use or inability
+to use the Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all other
+commercial damages or losses), even if such Contributor has been advised of
+the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or
+Derivative Works thereof, You may choose to offer, and charge a fee for,
+acceptance of support, warranty, indemnity, or other liability obligations
+and/or rights consistent with this License. However, in accepting such
+obligations, You may act only on Your own behalf and on Your sole
+responsibility, not on behalf of any other Contributor, and only if You agree
+to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..083bc3e
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) Rust Agent Stack Contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
index 7b8c06a..b1baefc 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,49 @@
# Rust Agent Stack (RAS)
-A comprehensive Rust framework for building type-safe, authenticated agent systems with JSON-RPC, REST APIs, and file services.
+A Rust framework for building type-safe, authenticated agent systems with JSON-RPC, REST APIs, and file services.
## Overview
-The Rust Agent Stack provides a complete toolkit for building distributed agent systems with:
-- 🔐 **Pluggable Authentication** - JWT, OAuth2, local auth with security best practices
-- 🚀 **Type-Safe APIs** - Procedural macros for JSON-RPC, REST, and file services
-- 🌐 **WebSocket Support** - Bidirectional real-time communication
-- 📁 **File Services** - Type-safe file upload/download with streaming support
-- 🎯 **Full-Stack TypeScript** - Automatic TypeScript client generation via WASM
-- 🎨 **Reactive WASM UIs** - Build modern web apps with Dominator framework
-- 📊 **Observability** - Built-in OpenTelemetry and Prometheus metrics
-- 📝 **API Documentation** - Automatic OpenRPC and OpenAPI generation
-- ✅ **Compile-Time Safety** - All endpoints must be implemented
+The Rust Agent Stack provides reusable building blocks for distributed agent systems:
+- **Pluggable Authentication** - JWT sessions, OAuth2, local username/password auth, secure cookie transport, and reusable authorization traits
+- **Type-Safe APIs** - Procedural macros for JSON-RPC, REST, and file services
+- **WebSocket Support** - Bidirectional real-time communication
+- **File Services** - Type-safe file upload/download with streaming support
+- **Generated Clients** - Rust and browser-friendly clients generated from shared service contracts
+- **Reactive WASM UIs** - Browser apps built with Dominator and generated API clients
+- **Observability** - OpenTelemetry and Prometheus metrics hooks
+- **API Documentation** - Automatic OpenRPC and OpenAPI generation
+- **Compile-Time Safety** - Generated traits require every endpoint to be implemented
## Quick Start
+Prerequisites:
+- Rust 1.88 or newer for Rust 2024 edition crates
+- Node.js 22.13 or newer only for the WASM UI example and Playwright browser tests
+
```bash
# Clone the repository
-git clone https://github.com/yourusername/rust-agent-stack.git
-cd rust-agent-stack
+git clone https://github.com/JedimEmO/rust-api-stack.git
+cd rust-api-stack
-# Build the entire workspace
-cargo build
+# Build the entire workspace with the checked-in lockfile
+cargo build --locked
# Run an example service
-cargo run -p basic-jsonrpc-service
-
-# In another terminal, run the WASM UI example
-cd examples/dominator-example
-./build.sh
-# Open http://localhost:8080
+cargo run -p basic-jsonrpc-service --locked
```
+The service listens on `http://localhost:3000` with:
+
+- JSON-RPC endpoint: `POST /rpc`
+- Explorer UI: `http://localhost:3000/rpc/explorer`
+- OpenRPC document: `http://localhost:3000/rpc/explorer/openrpc.json`
+- Prometheus metrics: `http://localhost:3000/metrics`
+
+Frontend examples are optional. The generated-client TypeScript samples are
+plain usage files under `examples/*/typescript-example`, while the only
+npm-based app is [`examples/wasm-ui-demo`](examples/wasm-ui-demo/).
+
## Architecture
RAS is organized as a Cargo workspace with the following structure:
@@ -43,7 +53,8 @@ crates/
├── core/ # Core libraries
│ ├── ras-auth-core # Authentication traits and types
│ ├── ras-identity-core # Core identity provider traits
-│ └── ras-observability-core # Unified observability traits
+│ ├── ras-observability-core # Unified observability traits
+│ └── ras-version-core # API version migration traits
├── rpc/ # JSON-RPC libraries
│ ├── ras-jsonrpc-types # JSON-RPC 2.0 protocol types
│ ├── ras-jsonrpc-core # JSON-RPC runtime support
@@ -64,16 +75,13 @@ crates/
├── observability/ # Monitoring and metrics
│ └── ras-observability-otel # OpenTelemetry implementation
├── specs/ # Specification types
-│ └── openrpc-types # OpenRPC 1.3.2 spec types
-└── tools/ # Development tools
- └── openrpc-to-bruno # Convert OpenRPC to Bruno
+│ └── ras-openrpc-types # OpenRPC 1.3.2 spec types
examples/ # Example applications
├── basic-jsonrpc/ # JSON-RPC service demo
├── bidirectional-chat/ # Real-time chat system
├── file-service-example/ # File upload/download demo
├── file-service-wasm/ # File service with TypeScript
├── oauth2-demo/ # OAuth2 authentication flow
-├── rest-api-demo/ # REST API example
├── rest-wasm-example/ # REST with TypeScript client
└── wasm-ui-demo/ # Dominator WASM UI
```
@@ -97,29 +105,21 @@ jsonrpc_service!({
]
});
-// Implement the generated trait
-struct TaskServiceImpl { /* ... */ }
-
-impl TaskServiceTrait for TaskServiceImpl {
- async fn sign_in(
- &self,
- request: SignInRequest,
- ) -> Result> {
- // Your implementation
- }
- // ... other methods
-}
+// Implement the generated `TaskServiceTrait` on your service type. The
+// runnable task implementation lives in `examples/basic-jsonrpc/service`.
+struct TaskServiceImpl;
// Use with the builder
-let router = TaskServiceBuilder::new(TaskServiceImpl { /* ... */ })
+let router = TaskServiceBuilder::new(TaskServiceImpl)
.base_url("/rpc")
- .auth_provider(JwtAuthProvider::new())
+ .auth_provider(MyAuthProvider)
.build()?;
```
### Type-Safe REST APIs
-Build RESTful services with automatic OpenAPI documentation and TypeScript client generation:
+Build RESTful services with automatic OpenAPI documentation that can feed
+TypeScript client generation:
```rust
use ras_rest_macro::rest_service;
@@ -128,7 +128,7 @@ rest_service!({
service_name: UserService,
base_path: "/api/v1",
openapi: true,
- serve_docs: true, // Serve Swagger UI at /api/v1/docs
+ serve_docs: true, // Serve the built-in API explorer at /api/v1/docs
endpoints: [
GET UNAUTHORIZED users() -> UsersResponse,
POST WITH_PERMISSIONS(["admin"]) users(CreateUserRequest) -> UserResponse,
@@ -137,19 +137,12 @@ rest_service!({
]
});
-// Implement the generated trait
-struct UserServiceImpl { /* ... */ }
-
-#[async_trait::async_trait]
-impl UserServiceTrait for UserServiceImpl {
- async fn get_users(&self) -> RestResult {
- // Your implementation
- }
- // ... other methods
-}
+// Implement the generated `UserServiceTrait` on your service type. The
+// REST guide includes an in-memory implementation.
+struct UserServiceImpl;
// Build the Axum router
-let app = UserServiceBuilder::new(UserServiceImpl { /* ... */ })
+let app = UserServiceBuilder::new(UserServiceImpl)
.auth_provider(jwt_auth_provider)
.build();
```
@@ -171,6 +164,9 @@ jsonrpc_bidirectional_service!({
server_to_client: [
message_received(MessageReceivedNotification),
user_joined(UserJoinedNotification),
+ ],
+
+ server_to_client_calls: [
]
});
```
@@ -185,36 +181,50 @@ use ras_file_macro::file_service;
file_service!({
service_name: DocumentService,
base_path: "/api/documents",
- body_limit: 52428800, // 50MB
endpoints: [
- UPLOAD WITH_PERMISSIONS(["user"]) upload() -> FileMetadata,
- DOWNLOAD UNAUTHORIZED download/{file_id: String}(),
+ UPLOAD WITH_PERMISSIONS(["user"]) upload multipart {
+ max_total_bytes: 52428800,
+ parts: [
+ file file {
+ required: true,
+ max_bytes: 52428800,
+ filename: optional,
+ },
+ ],
+ } -> FileMetadata,
+ DOWNLOAD UNAUTHORIZED download/{file_id: String} {
+ content_types: ["application/octet-stream"],
+ ranges: true,
+ },
]
});
```
-### TypeScript Client Generation
+### Generated Client Support
-All service macros support automatic TypeScript client generation:
+Service macros generate Rust clients and API documents from the same definitions used by the server. The REST and file-service browser examples are plain TypeScript usage samples that assume a fetch client generated locally from OpenAPI, while the JSON-RPC WASM UI uses generated Rust/WASM client code from the shared API crate.
```typescript
-// Auto-generated TypeScript client
-import { WasmUserServiceClient } from './pkg/user_api';
+import * as api from './generated';
-const client = new WasmUserServiceClient('http://localhost:3000');
-client.set_bearer_token('your-jwt-token');
+const users = await api.getUsers({
+ baseUrl: 'http://localhost:3000/api/v1',
+});
-const users = await client.get_users();
-const user = await client.create_user({ name: 'Alice', email: 'alice@example.com' });
+const created = await api.postUsers({
+ baseUrl: 'http://localhost:3000/api/v1',
+ headers: { Authorization: 'Bearer admintoken' },
+ body: { name: 'Alice', email: 'alice@example.com' },
+});
```
### Reactive WASM UIs
-Build modern web applications with Dominator:
+Build browser UIs with Dominator:
```rust
use dominator::{html, Dom};
-use futures_signals::signal::Mutable;
+use futures_signals::signal_vec::MutableVec;
fn create_task_list(tasks: MutableVec) -> Dom {
html!("div", {
@@ -231,7 +241,7 @@ fn create_task_list(tasks: MutableVec) -> Dom {
Simple task management API demonstrating authentication and OpenTelemetry metrics.
### [OAuth2 Demo](examples/oauth2-demo/)
-Full-stack OAuth2 implementation with PKCE flow and role-based permissions.
+OAuth2 demo with PKCE flow, JWT sessions, and role-based permissions.
### [Bidirectional Chat](examples/bidirectional-chat/)
Real-time chat system with WebSocket communication, TUI client, and persistence.
@@ -240,39 +250,48 @@ Real-time chat system with WebSocket communication, TUI client, and persistence.
File upload/download service with streaming support and authentication.
### [File Service WASM](examples/file-service-wasm/)
-Full-stack file service with TypeScript client and React frontend.
-
-### [REST API Demo](examples/rest-api-demo/)
-RESTful API with OpenAPI documentation, Swagger UI, and Prometheus metrics.
+File service with OpenAPI output and a minimal TypeScript usage sample for a generated fetch client.
### [REST WASM Example](examples/rest-wasm-example/)
-REST API with auto-generated TypeScript client and web UI.
+REST API with OpenAPI output and a minimal TypeScript usage sample for a generated fetch client.
### [WASM UI Demo](examples/wasm-ui-demo/)
-Reactive web UI with Dominator framework, glass morphism design.
+Reactive web UI with Dominator and the generated JSON-RPC client.
## Documentation
-Detailed documentation is available in the `documentation/` directory:
-- [REST Macro Guide](documentation/ras-rest-macro.md) - Complete REST API documentation
-- [File Service Guide](documentation/ras-file-macro.md) - File upload/download services
-- [Identity Providers](documentation/ras-identity.md) - Authentication system guide
-- [Observability](documentation/ras-observability.md) - Metrics and monitoring
+The canonical documentation is the mdBook source under
+[documentation/src](documentation/src/SUMMARY.md). Start with:
+
+- [Build A Typed Workspace App](documentation/src/tutorial/index.md)
+- [Why Typed Service Definitions](documentation/src/why-typed-service-definitions.md)
+- [Auth In The API Contract](documentation/src/auth-in-api-contract.md)
+- [`jsonrpc_service!`](documentation/src/macros/jsonrpc-service.md)
+- [`rest_service!`](documentation/src/macros/rest-service.md)
+- [`file_service!`](documentation/src/macros/file-service.md)
+- [`jsonrpc_bidirectional_service!`](documentation/src/macros/bidirectional-jsonrpc-service.md)
+
+Package-level README files remain available for crate-specific details:
+
+- [JSON-RPC Core](crates/rpc/ras-jsonrpc-core/README.md) - runtime auth and JSON-RPC support types
+- [Bidirectional JSON-RPC Server](crates/rpc/bidirectional/ras-jsonrpc-bidirectional-server/README.md) - server-side WebSocket runtime
+- [Bidirectional JSON-RPC Client](crates/rpc/bidirectional/ras-jsonrpc-bidirectional-client/README.md) - native and WASM WebSocket clients
## Built-in Features
### Authentication & Security
-- **Timing Attack Resistance** - Constant-time operations for authentication
-- **Username Enumeration Prevention** - Uniform error responses
-- **Rate Limiting** - Concurrent request limiting (5 attempts)
-- **Secure Password Storage** - Argon2 hashing with proper salts
-- **JWT Best Practices** - Configurable algorithms and secrets
+- **Timing Attack Mitigation** - Missing local users verify against an Argon2 sentinel hash
+- **Username Enumeration Mitigation** - Uniform invalid-credentials errors
+- **Rate Limiting** - Local authentication limits concurrent verification attempts
+- **Password Storage** - Per-user salted Argon2id hashes
+- **JWT Configuration** - Configurable algorithms, secrets, TTLs, and active-session enforcement
- **PKCE OAuth2** - Proof Key for Code Exchange by default
- **Session Management** - JWT-based sessions with revocation support
+- **Secure Cookie Transport** - Optional `HttpOnly`, `Secure`, `SameSite` cookies alongside bearer headers for browser sessions
### Observability
-Add production-ready metrics with minimal configuration:
+Add Prometheus-compatible metrics with minimal configuration:
```rust
use ras_observability_otel::standard_setup;
@@ -280,11 +299,12 @@ use ras_observability_otel::standard_setup;
// Set up OpenTelemetry with Prometheus
let otel = standard_setup("my-service")?;
-// Use with service builders
-let service = MyServiceBuilder::new(MyServiceImpl::new())
- .with_usage_tracker(otel.usage_tracker())
- .with_method_duration_tracker(otel.duration_tracker())
- .build()?;
+let _usage_tracker = otel.usage_tracker();
+let _duration_tracker = otel.method_duration_tracker();
+let _metrics_router = otel.metrics_router();
+
+// Wire the trackers into generated service builders through their
+// `with_usage_tracker` and `with_method_duration_tracker` hooks.
// Metrics available at /metrics endpoint
```
@@ -292,69 +312,138 @@ let service = MyServiceBuilder::new(MyServiceImpl::new())
Features:
- Unified metrics for JSON-RPC, REST, and file services
- Request counting, duration tracking, user activity
-- Zero-config Prometheus integration
+- Prometheus exporter and Axum `/metrics` router helpers
- Extensible trait-based design
-### TypeScript/WASM Support
+### TypeScript And WASM Support
-All service macros support automatic TypeScript client generation:
-- Type-safe API calls with full IntelliSense
-- Automatic error handling and retries
-- Bearer token management
-- Works in browsers and Node.js
-- Zero runtime overhead with WASM
+Browser examples use generated contracts without hand-written DTOs:
+- REST and file-service TypeScript usage samples assume a fetch client generated from OpenAPI specs.
+- JSON-RPC WASM UI uses generated Rust/WASM client code from the shared API crate.
+- Bearer tokens are passed as ordinary per-request headers.
+- Browser-facing services can opt into secure `HttpOnly` session cookies on the same generated builders, with double-submit CSRF protection for cookie-authenticated unsafe requests.
## Development
-See [CLAUDE.md](CLAUDE.md) for detailed development guidelines and architecture decisions.
+Use the workspace commands below as the baseline development checks. They mirror
+the GitHub Actions workflow so local validation catches the same classes of
+breakage before a pull request.
+
+### Rust Checks
+
+```bash
+# Formatting and linting
+cargo fmt --all -- --check
+cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
+
+# Tests and doctests
+cargo test --workspace --all-targets --all-features --no-run --locked
+cargo test --workspace --all-targets --all-features --locked
+cargo test --doc --workspace --all-features --locked
+
+# Documentation
+RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked
+```
+
+### Documentation Hygiene
+
+CI also checks that each Cargo package has a local README target and that local
+Markdown links resolve. The checks are implemented directly in
+[`.github/workflows/ci.yml`](.github/workflows/ci.yml) so the repository does
+not need separate verification scripts.
-### Building
+The mdBook can be built locally with:
```bash
-# Development build
-cargo build
+mdbook build
+```
+
+### Supply Chain Policy
+
+The tracked [`deny.toml`](deny.toml) is enforced in CI with `cargo-deny`.
+Run the same check locally when dependency versions, features, or licenses
+change:
+
+```bash
+cargo deny check
+```
+
+Install `cargo-deny` first if it is not already available:
+
+```bash
+cargo install cargo-deny
+```
+
+### Frontend Examples
+
+```bash
+# Generate OpenAPI specs used by the TypeScript usage samples
+cargo check -p file-service-backend -p rest-backend --locked
+```
+
+The generated-client usage samples are plain TypeScript files:
-# Release build with optimizations
-cargo build --release
+- `examples/file-service-wasm/typescript-example/src/example.ts`
+- `examples/rest-wasm-example/typescript-example/src/example.ts`
-# Run all tests
-cargo test
+The only npm-based frontend example is the Dominator WASM UI:
-# Run specific crate tests
-cargo test -p ras-auth-core
+```bash
+# Dominator WASM UI
+npm --prefix examples/wasm-ui-demo ci
+npm --prefix examples/wasm-ui-demo run build
```
-### Documentation
+### Browser Explorer Tests
+
+From the workspace root:
```bash
-# Generate and open documentation
-cargo doc --open
+npm --prefix tests/playwright ci
+npm --prefix tests/playwright run install:browsers
+npm --prefix tests/playwright test
+```
+
+These tests start dedicated REST and JSON-RPC fixture servers and exercise the
+generated API explorers in Chromium.
+
+### Coverage
-# Generate OpenRPC documentation (when enabled)
-cargo build # OpenRPC files generated in target/openrpc/
+From the workspace root:
+
+```bash
+cargo llvm-cov --workspace --all-targets --all-features --locked --lcov --output-path lcov.info
+cargo llvm-cov report --summary-only
+```
+
+Install `cargo-llvm-cov` first if it is not already available:
+
+```bash
+cargo install cargo-llvm-cov
```
## Contributing
-Contributions are welcome! Please read our contributing guidelines and code of conduct.
+Contributions are welcome. Keep changes focused, include tests for behavioral changes, and run the relevant workspace checks before opening a pull request.
### Development Setup
-1. Install Rust (latest stable)
-2. Install wasm-pack for WASM examples: `cargo install wasm-pack`
+1. Install Rust 1.88 or newer
+2. Install Node.js 22.13 or newer for the WASM UI example and Playwright browser tests
3. Clone the repository
-4. Run `cargo build` to verify setup
+4. Run `cargo build --locked` to verify setup
## License
-This project is licensed under the MIT License - see the LICENSE file for details.
+This project is licensed under either MIT or Apache-2.0. See
+[`LICENSE-MIT`](LICENSE-MIT) and [`LICENSE-APACHE`](LICENSE-APACHE).
## Acknowledgments
-Built with these excellent Rust crates:
+Built with these Rust crates:
- [Axum](https://github.com/tokio-rs/axum) - Web framework
- [Tokio](https://tokio.rs/) - Async runtime
- [Dominator](https://github.com/Pauan/rust-dominator) - WASM UI framework
- [Tungstenite](https://github.com/snapview/tungstenite-rs) - WebSocket implementation
-- [jsonwebtoken](https://github.com/Keats/jsonwebtoken) - JWT support
+- [hmac](https://github.com/RustCrypto/MACs), [sha2](https://github.com/RustCrypto/hashes), and [base64](https://github.com/marshallpierce/rust-base64) - HMAC-signed JWT support
- [async-trait](https://github.com/dtolnay/async-trait) - Async traits
diff --git a/agent-research/rust-api-to-ts-client.md b/agent-research/rust-api-to-ts-client.md
deleted file mode 100644
index 45a7a53..0000000
--- a/agent-research/rust-api-to-ts-client.md
+++ /dev/null
@@ -1,233 +0,0 @@
-# Rust API to TypeScript Client Generation with ras-file-macro
-
-## Overview
-
-The `ras-file-macro` provides a powerful procedural macro that generates TypeScript/WASM bindgen compatible clients from Rust API definitions. This enables seamless integration between Rust backend services and TypeScript web applications through WebAssembly.
-
-## How It Works
-
-### 1. Macro Definition
-
-The `file_service!` macro (defined in `crates/rest/ras-file-macro/`) takes a service definition and generates:
-- Native Rust client implementation
-- WASM-bindgen compatible wrapper client
-- Server-side implementation
-- TypeScript type definitions
-
-Example macro usage:
-```rust
-file_service!({
- service_name: DocumentService,
- base_path: "/api/documents",
- body_limit: 104857600, // 100 MB
- endpoints: [
- UPLOAD UNAUTHORIZED upload() -> UploadResponse,
- UPLOAD WITH_PERMISSIONS(["user"]) upload_profile_picture() -> UploadResponse,
- DOWNLOAD UNAUTHORIZED download/{file_id:String}() -> (),
- DOWNLOAD WITH_PERMISSIONS(["user"]) download_secure/{file_id:String}() -> (),
- ]
-});
-```
-
-### 2. Code Generation Process
-
-#### WASM Client Generation (`src/client.rs`)
-
-The macro generates a WASM-bindgen wrapper struct that:
-
-1. **Wraps the native client** with `#[wasm_bindgen]` attributes
-2. **Conditionally compiles** with `#[cfg(all(target_arch = "wasm32", feature = "wasm-client"))]`
-3. **Provides JavaScript-friendly APIs**:
- - Constructor accepting base URL string
- - Authentication method (`set_bearer_token`)
- - Async methods for each endpoint
-
-#### Method Generation
-
-For each endpoint, the macro generates specialized handlers:
-
-**Upload Operations:**
-- Accepts JavaScript `File` objects
-- Extracts file content as `Uint8Array`
-- Reads content type from the File object
-- Converts to Rust `Vec` for processing
-
-**Download Operations:**
-- Returns data as JavaScript `Uint8Array`
-- Handles binary data transfer efficiently
-
-### 3. Build Process
-
-The WASM client is built using `wasm-pack`:
-
-```bash
-wasm-pack build --target web --out-dir pkg --features wasm-client
-```
-
-This generates:
-- TypeScript definitions (`.d.ts` files)
-- JavaScript glue code
-- WASM binary module
-- Package.json for npm integration
-
-Generated TypeScript interface example:
-```typescript
-export class WasmDocumentServiceClient {
- constructor(base_url: string);
- set_bearer_token(token?: string | null): void;
- upload(file: File): Promise;
- upload_profile_picture(file: File): Promise;
- download(file_id: string): Promise;
- download_secure(file_id: string): Promise;
-}
-```
-
-## Architectural Benefits for Web Applications
-
-### 1. Type Safety Across Stack
-- Single source of truth for API definitions in Rust
-- Automatic TypeScript type generation ensures client-server contract consistency
-- Compile-time validation prevents API mismatches
-
-### 2. Performance Advantages
-- Direct WASM execution for data processing
-- Efficient binary data handling without base64 encoding
-- Reduced serialization overhead compared to traditional REST clients
-
-### 3. Developer Experience
-- No manual API client maintenance
-- Automatic updates when API changes
-- IDE autocomplete and type checking in TypeScript
-
-### 4. Authentication Integration
-- Built-in bearer token support
-- Seamless integration with existing auth systems
-- Per-endpoint permission configuration
-
-### 5. Cross-Platform Compatibility
-- Same macro generates both native and WASM clients
-- Conditional compilation separates platform-specific code
-- Server code excluded from WASM builds
-
-## TypeScript Usage
-
-### Client Initialization
-
-```typescript
-import init, { WasmDocumentServiceClient } from '@wasm/file_service_api.js';
-
-// Initialize WASM module once
-let wasmInitialized = false;
-let clientInstance: WasmDocumentServiceClient | null = null;
-
-export async function getClient(): Promise {
- if (!wasmInitialized) {
- await init();
- wasmInitialized = true;
- }
-
- if (!clientInstance) {
- clientInstance = new WasmDocumentServiceClient(window.location.origin);
- }
-
- return clientInstance;
-}
-```
-
-### File Upload Example
-
-```typescript
-const client = await getClient();
-
-// Set authentication token if needed
-client.set_bearer_token(authToken);
-
-// Upload file directly from input element
-const fileInput = document.querySelector('input[type="file"]');
-const file = fileInput.files[0];
-
-try {
- const response = await client.upload(file);
- console.log('Upload successful:', response);
-} catch (error) {
- console.error('Upload failed:', error);
-}
-```
-
-### File Download Example
-
-```typescript
-const client = await getClient();
-
-try {
- const data = await client.download(fileId);
-
- // Convert Uint8Array to Blob for download
- const blob = new Blob([data], { type: 'application/octet-stream' });
- const url = URL.createObjectURL(blob);
-
- // Trigger download
- const a = document.createElement('a');
- a.href = url;
- a.download = fileName;
- a.click();
-
- URL.revokeObjectURL(url);
-} catch (error) {
- console.error('Download failed:', error);
-}
-```
-
-## Integration with Modern Web Frameworks
-
-The generated client works seamlessly with modern frameworks like:
-
-- **React/Solid.js**: Direct integration with hooks and state management
-- **Vue**: Compatible with composition API
-- **Svelte**: Works with reactive stores
-
-Example with Solid.js:
-```typescript
-export default function FileUpload() {
- const [uploading, setUploading] = createSignal(false);
-
- const handleUpload = async (file: File) => {
- setUploading(true);
- try {
- const client = await getClient();
- const response = await client.upload(file);
- // Handle success
- } finally {
- setUploading(false);
- }
- };
-
- // Component JSX...
-}
-```
-
-## Key Architectural Patterns
-
-### 1. Separation of Concerns
-- API definitions in dedicated crate (`file-service-api`)
-- Backend implementation separate from client code
-- WASM client feature-gated to avoid bloat
-
-### 2. Error Handling
-- Rust errors automatically converted to JavaScript exceptions
-- Consistent error structure across platforms
-- Type-safe error responses
-
-### 3. Resource Management
-- Automatic memory management through WASM bindgen
-- Efficient binary data transfer
-- No manual cleanup required
-
-### 4. Scalability
-- Stateless client design
-- Connection pooling handled by browser
-- Compatible with CDN distribution
-
-## Conclusion
-
-The `ras-file-macro` represents a powerful approach to building type-safe, performant web applications with Rust backends. By generating TypeScript clients through WASM bindgen, it eliminates the traditional pain points of API integration while providing native-like performance for data-intensive operations. This architecture is particularly beneficial for applications dealing with file uploads, binary data processing, or requiring strong type safety across the full stack.
\ No newline at end of file
diff --git a/book.toml b/book.toml
new file mode 100644
index 0000000..51713d3
--- /dev/null
+++ b/book.toml
@@ -0,0 +1,13 @@
+[book]
+title = "Rust Agent Stack API Builder Guide"
+description = "Rationale and usage guide for the Rust Agent Stack service macros."
+authors = ["Rust Agent Stack contributors"]
+language = "en"
+src = "documentation/src"
+
+[build]
+build-dir = "target/mdbook"
+
+[output.html]
+git-repository-url = "https://github.com/JedimEmO/rust-api-stack"
+edit-url-template = "https://github.com/JedimEmO/rust-api-stack/edit/master/{path}"
diff --git a/crates/core/ras-auth-core/Cargo.toml b/crates/core/ras-auth-core/Cargo.toml
index 6b46fbf..3e382f5 100644
--- a/crates/core/ras-auth-core/Cargo.toml
+++ b/crates/core/ras-auth-core/Cargo.toml
@@ -2,8 +2,16 @@
name = "ras-auth-core"
version = "0.1.0"
edition = "2024"
+rust-version = "1.88"
+description = "Core authentication and authorization traits for Rust Agent Stack services"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/JedimEmO/rust-api-stack"
+homepage = "https://github.com/JedimEmO/rust-api-stack"
+readme = "README.md"
[dependencies]
+cookie = { workspace = true }
+http = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
-thiserror = { workspace = true }
\ No newline at end of file
+thiserror = { workspace = true }
diff --git a/crates/core/ras-auth-core/README.md b/crates/core/ras-auth-core/README.md
index cf00d04..41de2ee 100644
--- a/crates/core/ras-auth-core/README.md
+++ b/crates/core/ras-auth-core/README.md
@@ -1,14 +1,19 @@
# ras-auth-core
-Core authentication traits and types for the Rust Agent Stack authentication system.
+Core authentication and authorization traits for Rust Agent Stack services.
## Overview
-This crate provides the foundational traits and types used across all RAS authentication implementations:
+This crate defines the shared authentication contract used by the REST,
+JSON-RPC, bidirectional JSON-RPC, and identity crates:
- `AuthProvider` - Main trait for authentication providers
- `AuthenticatedUser` - Represents an authenticated user with permissions
- `AuthError` - Common error types for authentication failures
+- `AuthFuture` - Boxed future type returned by authentication providers
+- `AuthTransportConfig` - HTTP credential transport configuration for bearer and cookie auth
+- `AuthCookieConfig` - Secure session cookie settings and `Set-Cookie` helpers
+- `CsrfConfig` - CSRF guard for cookie-authenticated unsafe requests
## Key Types
@@ -17,21 +22,27 @@ This crate provides the foundational traits and types used across all RAS authen
The main trait that authentication providers must implement:
```rust
-#[async_trait]
-pub trait AuthProvider: Send + Sync {
- async fn authenticate(&self, token: &str) -> Result;
+use ras_auth_core::{AuthFuture, AuthProvider};
+
+pub trait AuthProvider: Send + Sync + 'static {
+ fn authenticate(&self, token: String) -> AuthFuture<'_>;
}
```
+The trait also provides a default `check_permissions` implementation that
+requires every requested permission to be present in the authenticated user.
+
### AuthenticatedUser
Represents a successfully authenticated user:
```rust
+use std::collections::HashSet;
+
pub struct AuthenticatedUser {
- pub id: String,
- pub username: String,
- pub permissions: Vec,
+ pub user_id: String,
+ pub permissions: HashSet,
+ pub metadata: Option,
}
```
@@ -42,13 +53,53 @@ Common authentication error types:
```rust
pub enum AuthError {
InvalidToken,
- ExpiredToken,
- InvalidCredentials,
- InsufficientPermissions,
- InternalError(String),
+ TokenExpired,
+ InsufficientPermissions {
+ required: Vec,
+ has: Vec,
+ },
+ AuthenticationRequired,
+ Internal(String),
}
```
+### HTTP Credential Transport
+
+`AuthProvider` still validates a token string. HTTP services can choose how the
+token reaches the server:
+
+```rust
+use ras_auth_core::{AuthCookieConfig, AuthTransportConfig, CsrfConfig};
+
+let transport = AuthTransportConfig::default()
+ .with_cookie(AuthCookieConfig::default())
+ .with_csrf(CsrfConfig::default());
+```
+
+Bearer tokens remain enabled by default. If both `Authorization: Bearer ...` and
+the configured cookie are present, bearer wins. If the bearer header is present
+but malformed, the request fails instead of falling back to the cookie.
+
+Cookie helpers emit secure defaults:
+
+```rust
+use ras_auth_core::AuthCookieConfig;
+
+let cookie = AuthCookieConfig::default();
+let set_cookie = cookie.session_cookie_header_value("jwt-token")?;
+let clear_cookie = cookie.clear_cookie_header_value()?;
+# Ok::<(), Box>(())
+```
+
+The default cookie is `HttpOnly`, `Secure`, `SameSite=Lax`, `Path=/`, and uses a
+`__Host-` name. Use `insecure_for_local_development()` only for local HTTP.
+
+`CsrfConfig::default()` uses a double-submit token: issue a CSRF cookie with
+`csrf_cookie_header_value(...)`, then have browser clients echo the same token in
+the `x-ras-csrf` header on cookie-authenticated `POST`, `PUT`, `PATCH`, and
+`DELETE` requests. Use `header_presence_only(...)` only behind restrictive
+credentialed CORS where a presence-only custom header is an intentional tradeoff.
+
## Usage
This crate is typically used as a dependency by:
@@ -59,19 +110,27 @@ This crate is typically used as a dependency by:
## Example
```rust
-use ras_auth_core::{AuthProvider, AuthenticatedUser, AuthError};
-use async_trait::async_trait;
+use std::collections::HashSet;
+
+use ras_auth_core::{AuthError, AuthFuture, AuthProvider, AuthenticatedUser};
struct MyAuthProvider;
-#[async_trait]
impl AuthProvider for MyAuthProvider {
- async fn authenticate(&self, token: &str) -> Result {
- // Your authentication logic here
- Ok(AuthenticatedUser {
- id: "user-123".to_string(),
- username: "john.doe".to_string(),
- permissions: vec!["read".to_string(), "write".to_string()],
+ fn authenticate(&self, token: String) -> AuthFuture<'_> {
+ Box::pin(async move {
+ if token != "valid-token" {
+ return Err(AuthError::InvalidToken);
+ }
+
+ Ok(AuthenticatedUser {
+ user_id: "user-123".to_string(),
+ permissions: HashSet::from([
+ "read".to_string(),
+ "write".to_string(),
+ ]),
+ metadata: None,
+ })
})
}
}
@@ -79,8 +138,15 @@ impl AuthProvider for MyAuthProvider {
## Integration
-This crate integrates seamlessly with:
+This crate is used by:
- `ras-jsonrpc-macro` - For JSON-RPC service authentication
- `ras-rest-macro` - For REST API authentication
- `ras-identity-session` - For JWT-based authentication
-- `ras-jsonrpc-bidirectional-server` - For WebSocket authentication
\ No newline at end of file
+- `ras-jsonrpc-bidirectional-server` - For WebSocket authentication
+
+## Checks
+
+```bash
+cargo test -p ras-auth-core --locked
+cargo clippy -p ras-auth-core --all-targets --all-features --locked -- -D warnings
+```
diff --git a/crates/core/ras-auth-core/src/lib.rs b/crates/core/ras-auth-core/src/lib.rs
index f5cad16..cbd7edf 100644
--- a/crates/core/ras-auth-core/src/lib.rs
+++ b/crates/core/ras-auth-core/src/lib.rs
@@ -1,5 +1,7 @@
//! Authentication and authorization traits for JSON-RPC services.
+mod transport;
+
use std::collections::HashSet;
use std::future::Future;
use std::pin::Pin;
@@ -7,6 +9,8 @@ use std::pin::Pin;
use serde::{Deserialize, Serialize};
use thiserror::Error;
+pub use transport::*;
+
/// Errors that can occur during authentication or authorization.
#[derive(Debug, Error, Clone, Serialize, Deserialize)]
pub enum AuthError {
@@ -99,3 +103,172 @@ pub trait AuthProvider: Send + Sync + 'static {
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use std::collections::HashSet;
+ use std::sync::Arc;
+ use std::task::{Context, Poll, Wake, Waker};
+
+ use serde_json::json;
+
+ use super::*;
+
+ struct TestAuthProvider;
+
+ impl AuthProvider for TestAuthProvider {
+ fn authenticate(&self, _token: String) -> AuthFuture<'_> {
+ unreachable!("permission tests only exercise the default helper")
+ }
+ }
+
+ struct TokenAuthProvider;
+
+ impl AuthProvider for TokenAuthProvider {
+ fn authenticate(&self, token: String) -> AuthFuture<'_> {
+ Box::pin(async move {
+ if token != "good-token" {
+ return Err(AuthError::InvalidToken);
+ }
+
+ Ok(AuthenticatedUser {
+ user_id: "user-1".to_string(),
+ permissions: HashSet::from(["widgets:read".to_string()]),
+ metadata: Some(json!({ "tenant": "acme" })),
+ })
+ })
+ }
+ }
+
+ struct NoopWaker;
+
+ impl Wake for NoopWaker {
+ fn wake(self: Arc) {}
+ }
+
+ fn poll_auth_future(mut future: AuthFuture<'_>) -> AuthResult {
+ let waker = Waker::from(Arc::new(NoopWaker));
+ let mut context = Context::from_waker(&waker);
+
+ match future.as_mut().poll(&mut context) {
+ Poll::Ready(result) => result,
+ Poll::Pending => panic!("test auth future should complete immediately"),
+ }
+ }
+
+ fn user_with_permissions(permissions: &[&str]) -> AuthenticatedUser {
+ AuthenticatedUser {
+ user_id: "user-1".to_string(),
+ permissions: permissions
+ .iter()
+ .map(|permission| permission.to_string())
+ .collect(),
+ metadata: Some(json!({ "tenant": "acme" })),
+ }
+ }
+
+ #[test]
+ fn check_permissions_allows_user_when_all_required_permissions_are_present() {
+ let provider = TestAuthProvider;
+ let user = user_with_permissions(&["users:read", "users:write"]);
+ let required = vec!["users:read".to_string(), "users:write".to_string()];
+
+ let result = provider.check_permissions(&user, &required);
+
+ assert!(result.is_ok());
+ }
+
+ #[test]
+ fn check_permissions_allows_user_when_no_permissions_are_required() {
+ let provider = TestAuthProvider;
+ let user = user_with_permissions(&[]);
+
+ let result = provider.check_permissions(&user, &[]);
+
+ assert!(result.is_ok());
+ }
+
+ #[test]
+ fn check_permissions_returns_required_and_actual_permissions_when_one_is_missing() {
+ let provider = TestAuthProvider;
+ let user = user_with_permissions(&["users:read"]);
+ let required = vec!["users:read".to_string(), "users:write".to_string()];
+
+ let result = provider.check_permissions(&user, &required);
+
+ let AuthError::InsufficientPermissions { required, has } = result.unwrap_err() else {
+ panic!("expected insufficient permissions");
+ };
+ assert_eq!(required, vec!["users:read", "users:write"]);
+ assert_eq!(
+ has.into_iter().collect::>(),
+ HashSet::from(["users:read".to_string()])
+ );
+ }
+
+ #[test]
+ fn authenticated_user_serializes_permissions_and_metadata() {
+ let user = user_with_permissions(&["users:read", "users:write"]);
+
+ let json = serde_json::to_value(&user).expect("serialize user");
+ let round_trip: AuthenticatedUser = serde_json::from_value(json).expect("deserialize user");
+
+ assert_eq!(round_trip.user_id, "user-1");
+ assert_eq!(round_trip.permissions, user.permissions);
+ assert_eq!(round_trip.metadata, Some(json!({ "tenant": "acme" })));
+ }
+
+ #[test]
+ fn auth_error_display_messages_are_stable_for_clients() {
+ assert_eq!(AuthError::InvalidToken.to_string(), "Invalid token");
+ assert_eq!(AuthError::TokenExpired.to_string(), "Token expired");
+ assert_eq!(
+ AuthError::AuthenticationRequired.to_string(),
+ "Authentication required"
+ );
+ assert_eq!(
+ AuthError::Internal("store unavailable".to_string()).to_string(),
+ "Authentication error: store unavailable"
+ );
+ }
+
+ #[test]
+ fn auth_provider_future_alias_returns_authenticated_user() {
+ let provider = TokenAuthProvider;
+
+ let user = poll_auth_future(provider.authenticate("good-token".to_string()))
+ .expect("token authenticates");
+
+ assert_eq!(user.user_id, "user-1");
+ assert!(user.permissions.contains("widgets:read"));
+ assert_eq!(user.metadata, Some(json!({ "tenant": "acme" })));
+
+ assert!(poll_auth_future(provider.authenticate("bad-token".to_string())).is_err());
+ }
+
+ #[test]
+ fn auth_error_serializes_structured_permission_details() {
+ let error = AuthError::InsufficientPermissions {
+ required: vec!["admin".to_string()],
+ has: vec!["user".to_string()],
+ };
+
+ let value = serde_json::to_value(&error).expect("serialize auth error");
+ assert_eq!(
+ value,
+ json!({
+ "InsufficientPermissions": {
+ "required": ["admin"],
+ "has": ["user"]
+ }
+ })
+ );
+
+ let decoded: AuthError = serde_json::from_value(value).expect("deserialize auth error");
+ let AuthError::InsufficientPermissions { required, has } = decoded else {
+ panic!("expected insufficient permissions");
+ };
+ assert_eq!(required, vec!["admin"]);
+ assert_eq!(has, vec!["user"]);
+ }
+}
diff --git a/crates/core/ras-auth-core/src/transport.rs b/crates/core/ras-auth-core/src/transport.rs
new file mode 100644
index 0000000..5d797e0
--- /dev/null
+++ b/crates/core/ras-auth-core/src/transport.rs
@@ -0,0 +1,944 @@
+//! HTTP credential transport helpers for bearer and cookie-based sessions.
+
+use cookie::{
+ Cookie, SameSite,
+ time::{Duration, OffsetDateTime},
+};
+use http::header::{AUTHORIZATION, COOKIE, HeaderName, SET_COOKIE};
+use http::{HeaderMap, HeaderValue};
+use thiserror::Error;
+
+const DEFAULT_COOKIE_NAME: &str = "__Host-ras-session";
+const DEFAULT_CSRF_COOKIE_NAME: &str = "__Host-ras-csrf";
+const DEFAULT_CSRF_HEADER: &str = "x-ras-csrf";
+
+/// Source from which an authentication token was extracted.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum AuthTokenSource {
+ /// `Authorization: Bearer ...`
+ Bearer,
+ /// Configured HTTP cookie.
+ Cookie,
+}
+
+/// Authentication token extracted from an HTTP request.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct AuthCredential {
+ token: String,
+ source: AuthTokenSource,
+}
+
+impl AuthCredential {
+ /// Create a credential for tests or custom extractors.
+ pub fn new(token: impl Into, source: AuthTokenSource) -> Self {
+ Self {
+ token: token.into(),
+ source,
+ }
+ }
+
+ /// The token value to pass to `AuthProvider::authenticate`.
+ pub fn token(&self) -> &str {
+ &self.token
+ }
+
+ /// The transport that supplied the token.
+ pub fn source(&self) -> AuthTokenSource {
+ self.source
+ }
+}
+
+/// Errors that can occur while extracting or validating HTTP auth credentials.
+#[derive(Debug, Clone, PartialEq, Eq, Error)]
+pub enum AuthTransportError {
+ /// No configured credential transport found a token.
+ #[error("missing authentication credentials")]
+ MissingCredentials,
+
+ /// The `Authorization` header was present but was not a valid bearer token.
+ #[error("invalid authorization header")]
+ InvalidAuthorizationHeader,
+
+ /// Cookie-authenticated request failed CSRF validation.
+ #[error("CSRF validation failed")]
+ CsrfValidationFailed,
+
+ /// Cookie configuration is internally inconsistent.
+ #[error("invalid cookie configuration: {0}")]
+ InvalidCookieConfig(String),
+
+ /// The request contained ambiguous or invalid cookie credentials.
+ #[error("invalid cookie header: {0}")]
+ InvalidCookieHeader(String),
+
+ /// CSRF configuration is internally inconsistent.
+ #[error("invalid CSRF configuration: {0}")]
+ InvalidCsrfConfig(String),
+
+ /// Auth transport configuration is internally inconsistent.
+ #[error("invalid auth transport configuration: {0}")]
+ InvalidAuthTransportConfig(String),
+
+ /// Generated cookie header could not be represented as an HTTP header.
+ #[error("invalid set-cookie header: {0}")]
+ InvalidSetCookieHeader(String),
+}
+
+/// SameSite setting for generated session cookies.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum CookieSameSite {
+ /// Send cookies for same-site requests and top-level cross-site navigations.
+ Lax,
+ /// Send cookies only for same-site requests.
+ Strict,
+ /// Send cookies cross-site. Requires `Secure`.
+ None,
+}
+
+impl CookieSameSite {
+ fn as_cookie_same_site(self) -> SameSite {
+ match self {
+ Self::Lax => SameSite::Lax,
+ Self::Strict => SameSite::Strict,
+ Self::None => SameSite::None,
+ }
+ }
+}
+
+/// Configuration for accepting and emitting a session cookie.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct AuthCookieConfig {
+ /// Cookie name. Defaults to a host-only secure-cookie prefix.
+ pub name: String,
+ /// Cookie path. Defaults to `/`.
+ pub path: String,
+ /// Optional cookie domain. Must remain `None` for `__Host-` cookies.
+ pub domain: Option,
+ /// Whether to emit `Secure`.
+ pub secure: bool,
+ /// Whether to emit `HttpOnly`.
+ pub http_only: bool,
+ /// SameSite policy.
+ pub same_site: CookieSameSite,
+ /// Optional `Max-Age` in seconds for the set-cookie helper.
+ pub max_age_seconds: Option,
+}
+
+impl Default for AuthCookieConfig {
+ fn default() -> Self {
+ Self {
+ name: DEFAULT_COOKIE_NAME.to_string(),
+ path: "/".to_string(),
+ domain: None,
+ secure: true,
+ http_only: true,
+ same_site: CookieSameSite::Lax,
+ max_age_seconds: None,
+ }
+ }
+}
+
+impl AuthCookieConfig {
+ /// Create a secure cookie configuration with a custom name.
+ ///
+ /// Prefer [`Self::default`] or [`Self::host_prefixed`] for production browser sessions.
+ /// Plain shared-domain names are easier to confuse with cookies set by subdomains.
+ pub fn new(name: impl Into) -> Self {
+ Self {
+ name: name.into(),
+ ..Self::default()
+ }
+ }
+
+ /// Create a secure `__Host-` prefixed cookie configuration with a custom suffix.
+ pub fn host_prefixed(name: impl Into) -> Self {
+ let name = name.into();
+ let suffix = name.strip_prefix("__Host-").unwrap_or(&name);
+ Self {
+ name: format!("__Host-{suffix}"),
+ ..Self::default()
+ }
+ }
+
+ /// Relax `Secure` for local HTTP development.
+ ///
+ /// Do not use this in production.
+ pub fn insecure_for_local_development(mut self) -> Self {
+ self.secure = false;
+ if let Some(name) = self.name.strip_prefix("__Host-") {
+ self.name = name.to_string();
+ }
+ self
+ }
+
+ /// Validate cookie prefix and browser-enforced security invariants.
+ pub fn validate(&self) -> Result<(), AuthTransportError> {
+ validate_cookie_name(&self.name)?;
+
+ if self.path.trim().is_empty() {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "cookie path must not be empty".to_string(),
+ ));
+ }
+
+ if !self.path.starts_with('/') {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "cookie path must start with '/'".to_string(),
+ ));
+ }
+
+ if self.name.starts_with("__Secure-") && !self.secure {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "__Secure- cookies must be Secure".to_string(),
+ ));
+ }
+
+ if self.name.starts_with("__Host-") {
+ if !self.secure {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "__Host- cookies must be Secure".to_string(),
+ ));
+ }
+ if self.domain.is_some() {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "__Host- cookies must not set Domain".to_string(),
+ ));
+ }
+ if self.path != "/" {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "__Host- cookies must use Path=/".to_string(),
+ ));
+ }
+ }
+
+ if self.same_site == CookieSameSite::None && !self.secure {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "SameSite=None cookies must be Secure".to_string(),
+ ));
+ }
+
+ if let Some(domain) = &self.domain
+ && domain.trim().is_empty()
+ {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "cookie domain must not be empty".to_string(),
+ ));
+ }
+
+ Ok(())
+ }
+
+ /// Build a `Set-Cookie` header value for a newly issued session token.
+ pub fn session_cookie_header_value(
+ &self,
+ token: &str,
+ ) -> Result {
+ self.validate()?;
+
+ let mut builder = Cookie::build((self.name.clone(), token.to_string()))
+ .path(self.path.clone())
+ .secure(self.secure)
+ .http_only(self.http_only)
+ .same_site(self.same_site.as_cookie_same_site());
+
+ if let Some(domain) = &self.domain {
+ builder = builder.domain(domain.clone());
+ }
+
+ if let Some(max_age) = self.max_age_seconds {
+ builder = builder.max_age(Duration::seconds(max_age));
+ }
+
+ set_cookie_value(builder.build().to_string())
+ }
+
+ /// Build a `Set-Cookie` header value that clears this session cookie.
+ pub fn clear_cookie_header_value(&self) -> Result {
+ self.validate()?;
+
+ let mut builder = Cookie::build((self.name.clone(), ""))
+ .path(self.path.clone())
+ .secure(self.secure)
+ .http_only(self.http_only)
+ .same_site(self.same_site.as_cookie_same_site())
+ .max_age(Duration::seconds(0))
+ .expires(OffsetDateTime::UNIX_EPOCH);
+
+ if let Some(domain) = &self.domain {
+ builder = builder.domain(domain.clone());
+ }
+
+ set_cookie_value(builder.build().to_string())
+ }
+}
+
+fn validate_cookie_name(name: &str) -> Result<(), AuthTransportError> {
+ if name.trim().is_empty() {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "cookie name must not be empty".to_string(),
+ ));
+ }
+
+ if name.trim() != name {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "cookie name must not contain leading or trailing whitespace".to_string(),
+ ));
+ }
+
+ for byte in name.bytes() {
+ if byte <= 0x20
+ || byte >= 0x7f
+ || matches!(
+ byte,
+ b'(' | b')'
+ | b'<'
+ | b'>'
+ | b'@'
+ | b','
+ | b';'
+ | b':'
+ | b'\\'
+ | b'"'
+ | b'/'
+ | b'['
+ | b']'
+ | b'?'
+ | b'='
+ | b'{'
+ | b'}'
+ )
+ {
+ return Err(AuthTransportError::InvalidCookieConfig(
+ "cookie name must be a valid RFC6265 token".to_string(),
+ ));
+ }
+ }
+
+ Ok(())
+}
+
+fn set_cookie_value(value: String) -> Result {
+ HeaderValue::from_str(&value)
+ .map_err(|err| AuthTransportError::InvalidSetCookieHeader(err.to_string()))
+}
+
+/// CSRF guard configuration for cookie-authenticated unsafe requests.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct CsrfConfig {
+ /// Header that must be present on unsafe cookie-authenticated requests.
+ pub header_name: HeaderName,
+ /// Optional exact value the header must carry. If set, this value is used
+ /// instead of double-submit cookie validation.
+ pub expected_value: Option,
+ /// Cookie whose value must match the CSRF header. Enabled by default.
+ pub cookie_name: Option,
+}
+
+impl Default for CsrfConfig {
+ fn default() -> Self {
+ Self {
+ header_name: HeaderName::from_static(DEFAULT_CSRF_HEADER),
+ expected_value: None,
+ cookie_name: Some(DEFAULT_CSRF_COOKIE_NAME.to_string()),
+ }
+ }
+}
+
+impl CsrfConfig {
+ /// Require a custom header and the default double-submit CSRF cookie.
+ pub fn new(header_name: HeaderName) -> Self {
+ Self {
+ header_name,
+ ..Self::default()
+ }
+ }
+
+ /// Require the custom header to carry an exact value.
+ ///
+ /// This is intended for callers that validate a session-specific CSRF token
+ /// outside of the default double-submit cookie flow.
+ pub fn with_expected_value(mut self, expected_value: impl Into) -> Self {
+ self.expected_value = Some(expected_value.into());
+ self.cookie_name = None;
+ self
+ }
+
+ /// Require the custom header to match this CSRF cookie.
+ pub fn with_cookie_name(mut self, cookie_name: impl Into) -> Self {
+ self.cookie_name = Some(cookie_name.into());
+ self.expected_value = None;
+ self
+ }
+
+ /// Require only a non-empty custom header.
+ ///
+ /// This mode depends on restrictive credentialed CORS and is not a complete
+ /// CSRF defense by itself. Prefer [`Self::default`] for browser sessions.
+ pub fn header_presence_only(header_name: HeaderName) -> Self {
+ Self {
+ header_name,
+ expected_value: None,
+ cookie_name: None,
+ }
+ }
+
+ /// Build a `Set-Cookie` header value for the double-submit CSRF token.
+ ///
+ /// The CSRF cookie is intentionally not `HttpOnly` so browser clients can
+ /// copy its value into the configured CSRF header.
+ pub fn csrf_cookie_header_value(&self, token: &str) -> Result {
+ self.csrf_cookie_config()?
+ .session_cookie_header_value(token)
+ }
+
+ /// Build a `Set-Cookie` header value that clears the CSRF cookie.
+ pub fn clear_csrf_cookie_header_value(&self) -> Result {
+ self.csrf_cookie_config()?.clear_cookie_header_value()
+ }
+
+ /// Validate CSRF configuration.
+ pub fn validate(&self) -> Result<(), AuthTransportError> {
+ if let Some(expected) = &self.expected_value
+ && expected.trim().is_empty()
+ {
+ return Err(AuthTransportError::InvalidCsrfConfig(
+ "expected CSRF value must not be empty".to_string(),
+ ));
+ }
+
+ if let Some(cookie_name) = &self.cookie_name {
+ let cookie = AuthCookieConfig {
+ name: cookie_name.clone(),
+ http_only: false,
+ ..AuthCookieConfig::default()
+ };
+ cookie.validate()?;
+ }
+
+ Ok(())
+ }
+
+ fn validate_headers(&self, headers: &HeaderMap) -> Result<(), AuthTransportError> {
+ self.validate()?;
+
+ let value = headers
+ .get(&self.header_name)
+ .ok_or(AuthTransportError::CsrfValidationFailed)?;
+ let value = value
+ .to_str()
+ .map_err(|_| AuthTransportError::CsrfValidationFailed)?;
+
+ if value.trim().is_empty() {
+ return Err(AuthTransportError::CsrfValidationFailed);
+ }
+
+ if let Some(expected) = &self.expected_value
+ && value != expected
+ {
+ return Err(AuthTransportError::CsrfValidationFailed);
+ }
+
+ if self.expected_value.is_some() {
+ return Ok(());
+ }
+
+ if let Some(cookie_name) = &self.cookie_name {
+ let Some(cookie_value) = extract_cookie(headers, cookie_name)? else {
+ return Err(AuthTransportError::CsrfValidationFailed);
+ };
+
+ if cookie_value.trim().is_empty() || cookie_value != value {
+ return Err(AuthTransportError::CsrfValidationFailed);
+ }
+ }
+
+ Ok(())
+ }
+
+ fn csrf_cookie_config(&self) -> Result {
+ let cookie_name = self.cookie_name.as_ref().ok_or_else(|| {
+ AuthTransportError::InvalidCsrfConfig(
+ "CSRF cookie helper requires cookie validation mode".to_string(),
+ )
+ })?;
+
+ let cookie = AuthCookieConfig {
+ name: cookie_name.clone(),
+ http_only: false,
+ ..AuthCookieConfig::default()
+ };
+ cookie.validate()?;
+ Ok(cookie)
+ }
+}
+
+/// Configures which HTTP transports a generated service accepts for auth.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct AuthTransportConfig {
+ /// Accept `Authorization: Bearer ...`.
+ pub bearer: bool,
+ /// Optional secure cookie credential transport.
+ pub cookie: Option,
+ /// Optional CSRF guard for cookie-authenticated unsafe requests.
+ pub csrf: Option,
+}
+
+impl Default for AuthTransportConfig {
+ fn default() -> Self {
+ Self {
+ bearer: true,
+ cookie: None,
+ csrf: None,
+ }
+ }
+}
+
+impl AuthTransportConfig {
+ /// Enable cookie auth alongside the default bearer transport.
+ pub fn with_cookie(mut self, cookie: AuthCookieConfig) -> Self {
+ self.cookie = Some(cookie);
+ self
+ }
+
+ /// Enable CSRF protection for cookie-authenticated unsafe requests.
+ pub fn with_csrf(mut self, csrf: CsrfConfig) -> Self {
+ self.csrf = Some(csrf);
+ self
+ }
+
+ /// Disable bearer-token extraction.
+ pub fn without_bearer(mut self) -> Self {
+ self.bearer = false;
+ self
+ }
+
+ /// Validate all configured auth transports.
+ pub fn validate(&self) -> Result<(), AuthTransportError> {
+ if !self.bearer && self.cookie.is_none() {
+ return Err(AuthTransportError::InvalidAuthTransportConfig(
+ "at least one auth transport must be enabled".to_string(),
+ ));
+ }
+
+ if let Some(cookie) = &self.cookie {
+ cookie.validate()?;
+ }
+
+ if let Some(csrf) = &self.csrf {
+ csrf.validate()?;
+ }
+
+ Ok(())
+ }
+}
+
+/// Extract an auth credential from configured HTTP transports.
+pub fn extract_auth_credential(
+ headers: &HeaderMap,
+ config: &AuthTransportConfig,
+) -> Result {
+ config.validate()?;
+
+ if config.bearer
+ && let Some(header) = headers.get(AUTHORIZATION)
+ {
+ let header = header
+ .to_str()
+ .map_err(|_| AuthTransportError::InvalidAuthorizationHeader)?;
+ let (scheme, token) = header
+ .split_once(' ')
+ .ok_or(AuthTransportError::InvalidAuthorizationHeader)?;
+ if !scheme.eq_ignore_ascii_case("Bearer") || token.trim().is_empty() {
+ return Err(AuthTransportError::InvalidAuthorizationHeader);
+ }
+ let token = token.trim();
+
+ return Ok(AuthCredential::new(token, AuthTokenSource::Bearer));
+ }
+
+ if let Some(cookie_config) = &config.cookie
+ && let Some(token) = extract_cookie(headers, &cookie_config.name)?
+ {
+ return Ok(AuthCredential::new(token, AuthTokenSource::Cookie));
+ }
+
+ Err(AuthTransportError::MissingCredentials)
+}
+
+/// Validate CSRF policy for a previously extracted credential.
+pub fn validate_csrf_for_credential(
+ method: &str,
+ headers: &HeaderMap,
+ credential: &AuthCredential,
+ config: &AuthTransportConfig,
+) -> Result<(), AuthTransportError> {
+ config.validate()?;
+
+ if credential.source != AuthTokenSource::Cookie || !is_unsafe_method(method) {
+ return Ok(());
+ }
+
+ match &config.csrf {
+ Some(csrf) => csrf.validate_headers(headers),
+ None => Ok(()),
+ }
+}
+
+/// Header name used by cookie helper return values.
+pub fn set_cookie_header_name() -> HeaderName {
+ SET_COOKIE
+}
+
+/// Clone headers with known credential-bearing values replaced by `[REDACTED]`.
+pub fn redact_sensitive_headers(headers: &HeaderMap) -> HeaderMap {
+ let mut redacted = headers.clone();
+
+ redact_header(&mut redacted, AUTHORIZATION);
+ redact_header(&mut redacted, COOKIE);
+ redact_header(&mut redacted, SET_COOKIE);
+ redact_header(
+ &mut redacted,
+ HeaderName::from_static("proxy-authorization"),
+ );
+ redact_header(&mut redacted, HeaderName::from_static("x-auth-token"));
+ redact_header(&mut redacted, HeaderName::from_static("x-api-key"));
+ redact_header(&mut redacted, HeaderName::from_static("x-csrf-token"));
+ redact_header(&mut redacted, HeaderName::from_static("x-xsrf-token"));
+ redact_header(&mut redacted, HeaderName::from_static(DEFAULT_CSRF_HEADER));
+ redact_header(
+ &mut redacted,
+ HeaderName::from_static("sec-websocket-protocol"),
+ );
+
+ redacted
+}
+
+/// Clone headers with default sensitive values and configured auth transport
+/// header secrets replaced by `[REDACTED]`.
+pub fn redact_sensitive_headers_for_auth_transport(
+ headers: &HeaderMap,
+ config: &AuthTransportConfig,
+) -> HeaderMap {
+ let mut redacted = redact_sensitive_headers(headers);
+
+ if let Some(csrf) = &config.csrf {
+ redact_header(&mut redacted, csrf.header_name.clone());
+ }
+
+ redacted
+}
+
+fn redact_header(headers: &mut HeaderMap, name: HeaderName) {
+ if headers.contains_key(&name) {
+ headers.remove(&name);
+ headers.insert(name, HeaderValue::from_static("[REDACTED]"));
+ }
+}
+
+fn is_unsafe_method(method: &str) -> bool {
+ matches!(
+ method.to_ascii_uppercase().as_str(),
+ "POST" | "PUT" | "PATCH" | "DELETE"
+ )
+}
+
+fn extract_cookie(
+ headers: &HeaderMap,
+ cookie_name: &str,
+) -> Result