-13
Cargo.lock
-13
Cargo.lock
···
844
844
]
845
845
846
846
[[package]]
847
-
name = "enum_dispatch"
848
-
version = "0.3.13"
849
-
source = "registry+https://github.com/rust-lang/crates.io-index"
850
-
checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd"
851
-
dependencies = [
852
-
"once_cell",
853
-
"proc-macro2",
854
-
"quote",
855
-
"syn 2.0.106",
856
-
]
857
-
858
-
[[package]]
859
847
name = "equivalent"
860
848
version = "1.0.2"
861
849
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1587
1575
"chrono",
1588
1576
"cid",
1589
1577
"ed25519-dalek",
1590
-
"enum_dispatch",
1591
1578
"http",
1592
1579
"ipld-core",
1593
1580
"k256",
+18
-1
Cargo.toml
+18
-1
Cargo.toml
···
5
5
6
6
[workspace.package]
7
7
edition = "2024"
8
-
version = "0.2.0"
8
+
version = "0.3.0"
9
9
authors = ["Orual <orual@nonbinary.computer>"]
10
10
repository = "https://tangled.org/@nonbinary.computer/jacquard"
11
11
keywords = ["atproto", "at", "bluesky", "api", "client"]
···
57
57
# HTTP
58
58
http = "1.3"
59
59
reqwest = { version = "0.12", default-features = false }
60
+
61
+
# Async and runtimes
62
+
async-trait = "0.1"
63
+
tokio = "1"
64
+
65
+
# Encoding and crypto building blocks
66
+
base64 = "0.22"
67
+
percent-encoding = "2.3"
68
+
urlencoding = "2.1.3"
69
+
rand_core = "0.6"
70
+
71
+
# Time
72
+
chrono = "0.4"
73
+
74
+
# Crypto curves and JOSE
75
+
p256 = "0.13"
76
+
jose-jwk = "0.1"
+1
-1
crates/jacquard-api/Cargo.toml
+1
-1
crates/jacquard-api/Cargo.toml
···
22
22
tools_ozone = []
23
23
24
24
[dependencies]
25
-
bon = "3"
25
+
bon.workspace = true
26
26
bytes = { workspace = true, features = ["serde"] }
27
27
jacquard-common = { version = "0.2.0", path = "../jacquard-common" }
28
28
jacquard-derive = { version = "0.2.0", path = "../jacquard-derive" }
+6
-8
crates/jacquard-common/Cargo.toml
+6
-8
crates/jacquard-common/Cargo.toml
···
13
13
14
14
15
15
[dependencies]
16
-
bon = "3"
17
-
base64 = "0.22.1"
16
+
bon.workspace = true
17
+
base64.workspace = true
18
18
bytes.workspace = true
19
-
chrono = "0.4.42"
19
+
chrono.workspace = true
20
20
cid = { version = "0.11.1", features = ["serde", "std"] }
21
-
enum_dispatch = "0.3.13"
22
21
ipld-core = { version = "0.4.2", features = ["serde"] }
23
22
langtag = { version = "0.4.0", features = ["serde"] }
24
23
miette.workspace = true
···
36
35
thiserror.workspace = true
37
36
url.workspace = true
38
37
http.workspace = true
39
-
async-trait = "0.1"
40
-
tokio = { version = "1", features = ["sync"] }
38
+
async-trait.workspace = true
39
+
tokio = { workspace = true, features = ["sync"] }
41
40
reqwest = { workspace = true, optional = true, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }
42
41
serde_ipld_dagcbor.workspace = true
43
42
trait-variant.workspace = true
···
63
62
features = ["arithmetic"]
64
63
65
64
[dependencies.p256]
66
-
version = "0.13"
65
+
workspace = true
67
66
optional = true
68
-
default-features = false
69
67
features = ["arithmetic"]
70
68
71
69
[package.metadata.docs.rs]
+4
-4
crates/jacquard-identity/Cargo.toml
+4
-4
crates/jacquard-identity/Cargo.toml
···
16
16
dns = ["dep:hickory-resolver"]
17
17
18
18
[dependencies]
19
-
async-trait = "0.1.89"
19
+
async-trait.workspace = true
20
20
bon.workspace = true
21
21
bytes.workspace = true
22
22
jacquard-common = { version = "0.2", path = "../jacquard-common" }
23
-
percent-encoding = "2.3.2"
23
+
percent-encoding.workspace = true
24
24
reqwest.workspace = true
25
25
url.workspace = true
26
-
tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] }
26
+
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs"] }
27
27
hickory-resolver = { optional = true, version = "0.24", default-features = false, features = ["system-config", "tokio-runtime"]}
28
28
serde.workspace = true
29
29
serde_json.workspace = true
···
32
32
http.workspace = true
33
33
jacquard-api = { version = "0.2.0", path = "../jacquard-api" }
34
34
serde_html_form.workspace = true
35
-
urlencoding = "2.1.3"
35
+
urlencoding.workspace = true
+9
-9
crates/jacquard-oauth/Cargo.toml
+9
-9
crates/jacquard-oauth/Cargo.toml
···
1
1
[package]
2
2
name = "jacquard-oauth"
3
-
version = "0.1.0"
3
+
version = "0.3.0"
4
4
edition = "2024"
5
5
description = "AT Protocol OAuth 2.1 core types and helpers for Jacquard"
6
6
license = "MPL-2.0"
7
7
8
8
[dependencies]
9
-
jacquard-common = { version = "0.2.0", path = "../jacquard-common" }
9
+
jacquard-common = { version = "0.3.0", path = "../jacquard-common" }
10
10
serde = { workspace = true, features = ["derive"] }
11
11
serde_json = { workspace = true }
12
12
url = { workspace = true }
13
13
smol_str = { workspace = true }
14
-
base64 = { version = "0.22" }
14
+
base64.workspace = true
15
15
sha2 = { version = "0.10" }
16
16
thiserror = { workspace = true }
17
17
serde_html_form = { workspace = true }
18
18
miette = { workspace = true }
19
19
uuid = { version = "1", features = ["v4","std"] }
20
-
p256 = { version = "0.13", features = ["ecdsa"] }
20
+
p256 = { workspace = true, features = ["ecdsa"] }
21
21
signature = "2"
22
-
rand_core = "0.6"
22
+
rand_core.workspace = true
23
23
jose-jwa = "0.1"
24
-
jose-jwk = { version = "0.1", features = ["p256"] }
25
-
chrono = "0.4"
24
+
jose-jwk = { workspace = true, features = ["p256"] }
25
+
chrono.workspace = true
26
26
elliptic-curve = "0.13.8"
27
27
http.workspace = true
28
28
bytes.workspace = true
29
29
rand = { version = "0.8.5", features = ["small_rng"] }
30
-
async-trait = "0.1.89"
30
+
async-trait.workspace = true
31
31
dashmap = "6.1.0"
32
-
tokio = { version = "1.47.1", features = ["sync"] }
32
+
tokio = { workspace = true, features = ["sync"] }
33
33
34
34
reqwest.workspace = true
35
35
trait-variant.workspace = true
+25
-11
crates/jacquard-oauth/src/request.rs
+25
-11
crates/jacquard-oauth/src/request.rs
···
43
43
#[derive(Error, Debug, miette::Diagnostic)]
44
44
pub enum RequestError {
45
45
#[error("no {0} endpoint available")]
46
-
#[diagnostic(code(jacquard_oauth::request::no_endpoint), help("server does not advertise this endpoint"))]
46
+
#[diagnostic(
47
+
code(jacquard_oauth::request::no_endpoint),
48
+
help("server does not advertise this endpoint")
49
+
)]
47
50
NoEndpoint(CowStr<'static>),
48
51
#[error("token response verification failed")]
49
52
#[diagnostic(code(jacquard_oauth::request::token_verification))]
···
51
54
#[error("unsupported authentication method")]
52
55
#[diagnostic(
53
56
code(jacquard_oauth::request::unsupported_auth_method),
54
-
help("server must support `private_key_jwt` or `none`; configure client metadata accordingly")
57
+
help(
58
+
"server must support `private_key_jwt` or `none`; configure client metadata accordingly"
59
+
)
55
60
)]
56
61
UnsupportedAuthMethod,
57
62
#[error("no refresh token available")]
···
76
81
#[diagnostic(code(jacquard_oauth::request::http_build))]
77
82
Http(#[from] http::Error),
78
83
#[error("http status: {0}")]
79
-
#[diagnostic(code(jacquard_oauth::request::http_status), help("see server response for details"))]
84
+
#[diagnostic(
85
+
code(jacquard_oauth::request::http_status),
86
+
help("see server response for details")
87
+
)]
80
88
HttpStatus(StatusCode),
81
89
#[error("http status: {0}, body: {1:?}")]
82
-
#[diagnostic(code(jacquard_oauth::request::http_status_body), help("server returned error JSON; inspect fields like `error`, `error_description`"))]
90
+
#[diagnostic(
91
+
code(jacquard_oauth::request::http_status_body),
92
+
help("server returned error JSON; inspect fields like `error`, `error_description`")
93
+
)]
83
94
HttpStatusWithBody(StatusCode, Value),
84
95
#[error(transparent)]
85
96
#[diagnostic(code(jacquard_oauth::request::identity))]
···
134
145
mod tests {
135
146
use super::*;
136
147
use crate::types::{OAuthAuthorizationServerMetadata, OAuthClientMetadata};
137
-
use http::{Response as HttpResponse, StatusCode};
138
148
use bytes::Bytes;
149
+
use http::{Response as HttpResponse, StatusCode};
139
150
use jacquard_common::http_client::HttpClient;
140
151
use jacquard_identity::resolver::IdentityResolver;
141
152
use std::sync::Arc;
···
249
260
async fn refresh_no_refresh_token() {
250
261
let client = MockClient::default();
251
262
let meta = base_metadata();
252
-
let mut session = ClientSessionData {
263
+
let session = ClientSessionData {
253
264
account_did: jacquard_common::types::string::Did::new_static("did:plc:alice").unwrap(),
254
265
session_id: CowStr::from("state"),
255
266
host_url: url::Url::parse("https://pds").unwrap(),
···
284
295
*client.resp.lock().await = Some(
285
296
HttpResponse::builder()
286
297
.status(StatusCode::OK)
287
-
.body(serde_json::to_vec(&serde_json::json!({
288
-
"access_token":"tok",
289
-
"token_type":"DPoP",
290
-
"expires_in": 3600
291
-
})).unwrap())
298
+
.body(
299
+
serde_json::to_vec(&serde_json::json!({
300
+
"access_token":"tok",
301
+
"token_type":"DPoP",
302
+
"expires_in": 3600
303
+
}))
304
+
.unwrap(),
305
+
)
292
306
.unwrap(),
293
307
);
294
308
let meta = base_metadata();
+12
-12
crates/jacquard/Cargo.toml
+12
-12
crates/jacquard/Cargo.toml
···
2
2
name = "jacquard"
3
3
description.workspace = true
4
4
edition.workspace = true
5
-
version = "0.2.1"
5
+
version = "0.3.0"
6
6
authors.workspace = true
7
7
repository.workspace = true
8
8
keywords.workspace = true
···
30
30
31
31
32
32
[dependencies]
33
-
bon = "3"
34
-
async-trait = "0.1"
33
+
bon.workspace = true
34
+
async-trait.workspace = true
35
35
bytes.workspace = true
36
36
clap.workspace = true
37
37
http.workspace = true
38
-
jacquard-api = { version = "0.2.0", path = "../jacquard-api" }
39
-
jacquard-common = { version = "0.2.0", path = "../jacquard-common", features = ["reqwest-client"] }
40
-
jacquard-oauth = { version = "0.1.0", path = "../jacquard-oauth" }
38
+
jacquard-api = { version = "0.3.0", path = "../jacquard-api" }
39
+
jacquard-common = { version = "0.3.0", path = "../jacquard-common", features = ["reqwest-client"] }
40
+
jacquard-oauth = { version = "0.3.0", path = "../jacquard-oauth" }
41
41
jacquard-derive = { version = "0.2.0", path = "../jacquard-derive", optional = true }
42
42
miette = { workspace = true }
43
43
reqwest = { workspace = true, features = ["charset", "http2", "json", "system-proxy", "gzip", "rustls-tls"] }
···
46
46
serde_ipld_dagcbor.workspace = true
47
47
serde_json.workspace = true
48
48
thiserror.workspace = true
49
-
tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] }
49
+
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "fs"] }
50
50
url.workspace = true
51
51
smol_str.workspace = true
52
-
percent-encoding = "2"
53
-
urlencoding = "2"
54
-
jose-jwk = { version = "0.1", features = ["p256"] }
55
-
p256 = { version = "0.13", features = ["ecdsa"] }
56
-
rand_core = "0.6"
52
+
percent-encoding.workspace = true
53
+
urlencoding.workspace = true
54
+
jose-jwk = { workspace = true, features = ["p256"] }
55
+
p256 = { workspace = true, features = ["ecdsa"] }
56
+
rand_core.workspace = true
57
57
rouille = { version = "3.6.2", optional = true }
58
58
jacquard-identity = { version = "0.2.0", path = "../jacquard-identity" }
+1
-1
crates/jacquard/tests/oauth_flow.rs
+1
-1
crates/jacquard/tests/oauth_flow.rs
···
239
239
keyset: None,
240
240
};
241
241
let login_hint = identity.map(|_| jacquard::CowStr::from("alice.bsky.social"));
242
-
let mut auth_req = jacquard_oauth::request::par(client.as_ref(), login_hint, None, &metadata)
242
+
let auth_req = jacquard_oauth::request::par(client.as_ref(), login_hint, None, &metadata)
243
243
.await
244
244
.unwrap();
245
245
// Construct authorization URL as OAuthClient::start_auth would do