+1
.gitignore
+1
.gitignore
+511
-4
Cargo.lock
+511
-4
Cargo.lock
··········································································································································
··········································································································································
+8
crates/jacquard-common/Cargo.toml
+8
crates/jacquard-common/Cargo.toml
···
···+reqwest = { workspace = true, optional = true, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }+hickory-resolver = { version = "0.24", default-features = false, features = ["system-config", "tokio-runtime"], optional = true }
+7
crates/jacquard-common/src/cowstr.rs
+7
crates/jacquard-common/src/cowstr.rs
+64
crates/jacquard-common/src/http_client.rs
+64
crates/jacquard-common/src/http_client.rs
···
···
+399
crates/jacquard-common/src/ident_resolver.rs
+399
crates/jacquard-common/src/ident_resolver.rs
···
···+//! `resolveHandle` (when `pds_fallback` is configured) → public API fallback → Slingshot `resolveHandle` (if configured).+//! - DID → Doc: did:web well-known → PLC/Slingshot HTTP → PDS XRPC `resolveDid` (when configured),+/// - `validate_doc_id`: if true (default), convenience helpers validate doc `id` against the requested DID,+/// `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle` as an unauth fallback.+/// There is no public fallback for DID documents; when `PdsResolveDid` is chosen and the PDS XRPC+/// client fails, the resolver falls back to Slingshot mini-doc (partial) if `PlcSource::Slingshot` is configured.
+15
crates/jacquard-common/src/lib.rs
+15
crates/jacquard-common/src/lib.rs
···
+76
crates/jacquard-common/src/session.rs
+76
crates/jacquard-common/src/session.rs
···
···
+1
-1
crates/jacquard-common/src/types/did.rs
+1
-1
crates/jacquard-common/src/types/did.rs
···/// method-specific-id allows alphanumerics, dots, colons, hyphens, underscores, and percent signs.
+1
-1
crates/jacquard-common/src/types/nsid.rs
+1
-1
crates/jacquard-common/src/types/nsid.rs
+2
-2
crates/jacquard-common/src/types/string.rs
+2
-2
crates/jacquard-common/src/types/string.rs
······
······
+446
-1
crates/jacquard-common/src/types/xrpc.rs
+446
-1
crates/jacquard-common/src/types/xrpc.rs
······
······+/// `atproto-proxy` header - specifies which service (app server or other atproto service) the user's PDS should forward requests to as appropriate.+/// `atproto-accept-labelers` header used by clients to request labels from specific labelers to be included and applied in the response. See [label](https://atproto.com/specs/label) specification for details.
+29
crates/jacquard-oauth/Cargo.toml
+29
crates/jacquard-oauth/Cargo.toml
···
···
+360
crates/jacquard-oauth/src/atproto.rs
+360
crates/jacquard-oauth/src/atproto.rs
···
···+"`private_key_jwt` auth method requires `token_endpoint_auth_signing_alg`, otherwise must not be provided"+"http://localhost?redirect_uri=http%3A%2F%2F127.0.0.1%2Fcallback&redirect_uri=http%3A%2F%2F%5B%3A%3A1%5D%2Fcallback&scope=account%3Aemail+atproto+transition%3Ageneric"
+260
crates/jacquard-oauth/src/dpop.rs
+260
crates/jacquard-oauth/src/dpop.rs
···
···
+42
crates/jacquard-oauth/src/error.rs
+42
crates/jacquard-oauth/src/error.rs
···
···
+14
crates/jacquard-oauth/src/jose.rs
+14
crates/jacquard-oauth/src/jose.rs
···
···
+85
crates/jacquard-oauth/src/jose/jws.rs
+85
crates/jacquard-oauth/src/jose/jws.rs
···
···
+101
crates/jacquard-oauth/src/jose/jwt.rs
+101
crates/jacquard-oauth/src/jose/jwt.rs
···
···
+21
crates/jacquard-oauth/src/jose/signing.rs
+21
crates/jacquard-oauth/src/jose/signing.rs
···
···
+128
crates/jacquard-oauth/src/keyset.rs
+128
crates/jacquard-oauth/src/keyset.rs
···
···
+14
crates/jacquard-oauth/src/lib.rs
+14
crates/jacquard-oauth/src/lib.rs
···
···
+214
crates/jacquard-oauth/src/resolver.rs
+214
crates/jacquard-oauth/src/resolver.rs
···
···+// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-08#name-authorization-server-metada+// https://drafts.aaronpk.com/draft-parecki-oauth-client-id-metadata-document/draft-parecki-oauth-client-id-metadata-document.html
+1969
crates/jacquard-oauth/src/scopes.rs
+1969
crates/jacquard-oauth/src/scopes.rs
···
···+//! Derived from https://tangled.org/@smokesignal.events/atproto-identity-rs/raw/main/crates/atproto-oauth/src/scopes.rs+/// let scopes = Scope::parse_multiple_reduced("atproto repo:app.bsky.feed.post repo:*").unwrap();+Scope::parse("rpc?lxm=com.example.method1&lxm=com.example.method2&aud=did:plc:yfvwmnlztr4dwkb7hwz55r2g")+"account:email?action=manage account:email account:repo account:repo?action=read identity:* identity:handle"+Scope::parse("rpc:com.example.service?aud=did:plc:yfvwmnlztr4dwkb7hwz55r2g&lxm=com.example.method")+let to_remove = Scope::parse("blob?accept=image/jpeg&accept=image/png").unwrap(); // Note: normalized order
+23
crates/jacquard-oauth/src/session.rs
+23
crates/jacquard-oauth/src/session.rs
···
···
+61
crates/jacquard-oauth/src/types.rs
+61
crates/jacquard-oauth/src/types.rs
···
···
+55
crates/jacquard-oauth/src/types/client_metadata.rs
+55
crates/jacquard-oauth/src/types/client_metadata.rs
···
···
+144
crates/jacquard-oauth/src/types/metadata.rs
+144
crates/jacquard-oauth/src/types/metadata.rs
···
···+// https://drafts.aaronpk.com/draft-parecki-oauth-client-id-metadata-document/draft-parecki-oauth-client-id-metadata-document.html#section-5+// https://datatracker.ietf.org/doc/html/draft-ietf-oauth-resource-metadata-08#name-authorization-server-metada
+134
crates/jacquard-oauth/src/types/request.rs
+134
crates/jacquard-oauth/src/types/request.rs
···
···
+56
crates/jacquard-oauth/src/types/response.rs
+56
crates/jacquard-oauth/src/types/response.rs
···
···
+36
crates/jacquard-oauth/src/types/token.rs
+36
crates/jacquard-oauth/src/types/token.rs
···
···
+9
-3
crates/jacquard/Cargo.toml
+9
-3
crates/jacquard/Cargo.toml
······reqwest = { workspace = true, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }···
······+jacquard-common = { version = "0.2.0", path = "../jacquard-common", features = ["reqwest-client"] }reqwest = { workspace = true, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }···
+90
-184
crates/jacquard/src/client.rs
+90
-184
crates/jacquard/src/client.rs
·········-pub async fn set_session(&self, session: Session) -> core::result::Result<(), TokenStoreError> {···-/// `atproto-proxy` header - specifies which service (app server or other atproto service) the user's PDS should forward requests to as appropriate.-/// `atproto-accept-labelers` header used by clients to request labels from specific labelers to be included and applied in the response. See [label](https://atproto.com/specs/label) specification for details.···-impl From<jacquard_api::com_atproto::server::create_session::CreateSessionOutput<'_>> for Session {······
···+pub struct BasicClient(AtClient<reqwest::Client, MemorySessionStore<Did<'static>, AuthSession>>);··················
+99
-53
crates/jacquard/src/client/at_client.rs
+99
-53
crates/jacquard/src/client/at_client.rs
···-use crate::client::{self as super_mod, AuthorizationToken, HttpClient, Response, Session, error};·····················
························
+21
-21
crates/jacquard/src/client/error.rs
crates/jacquard-common/src/error.rs
+21
-21
crates/jacquard/src/client/error.rs
crates/jacquard-common/src/error.rs
···············
···············
-198
crates/jacquard/src/client/response.rs
-198
crates/jacquard/src/client/response.rs
···
···
+30
-57
crates/jacquard/src/client/token.rs
+30
-57
crates/jacquard/src/client/token.rs
·········
·········
-154
crates/jacquard/src/client/xrpc_call.rs
-154
crates/jacquard/src/client/xrpc_call.rs
···-pub async fn send<R: XrpcRequest + Send>(self, request: R) -> super_mod::Result<Response<R>> {
···
-3
crates/jacquard/src/identity/mod.rs
-3
crates/jacquard/src/identity/mod.rs
+86
-388
crates/jacquard/src/identity/resolver.rs
crates/jacquard/src/identity.rs
+86
-388
crates/jacquard/src/identity/resolver.rs
crates/jacquard/src/identity.rs
······-/// - `validate_doc_id`: if true (default), convenience helpers validate doc `id` against the requested DID,-/// `https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle` as an unauth fallback.-/// There is no public fallback for DID documents; when `PdsResolveDid` is chosen and the PDS XRPC-/// client fails, the resolver falls back to Slingshot mini-doc (partial) if `PlcSource::Slingshot` is configured.··················-/// Build a resolver configured to use Slingshot (`https://slingshot.microcosm.blue`) for PLC and
··················+/// Build a resolver configured to use Slingshot (`https://slingshot.microcosm.blue`) for PLC and······
+14
-11
crates/jacquard/src/lib.rs
+14
-11
crates/jacquard/src/lib.rs
·····················
············+//! `AtClient<reqwest::Client, MemorySessionStore<AuthSession>>` with a `new(Url)` constructor.·········
+5
-4
crates/jacquard/src/main.rs
+5
-4
crates/jacquard/src/main.rs
·········
·········