atproto_auth 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/examples/confidential_client/Gemfile.lock +1 -1
- data/lib/atproto_auth/identity/did.rb +26 -0
- data/lib/atproto_auth/identity/document.rb +1 -7
- data/lib/atproto_auth/identity/resolver.rb +38 -9
- data/lib/atproto_auth/version.rb +1 -1
- data/lib/atproto_auth.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1543cc3c9cf5c099a76a62e75990217400930bfd00f8fa19b53b4bef9c035940
|
4
|
+
data.tar.gz: 294daf80d312117a27d7bcfda8fdb1e48865793736aa3a491bf13f61f73caeaa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f58e87d6dddab0421cc3637c166d84468f3b863004e6e22f377a200bb149b4bf51db8bf6b4d5d15161a897bcdee15801352932f7d457b57a53142dc4da42296
|
7
|
+
data.tar.gz: 21ce4544366475e39cce0bc0e52596fbfd9278b32a18c8b30193330f3b9946177c06450c3ddda93d3136bd386e9496279834821b7fec45be5f8c369e015f6ed7
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [0.2.1] - 2024-12-11
|
8
|
+
### Added
|
9
|
+
- Added support for did:web users
|
10
|
+
|
7
11
|
## [0.2.1] - 2024-12-11
|
8
12
|
### Fixed
|
9
13
|
- Fixed a bug with access token hash generation
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "resolv"
|
4
|
+
|
5
|
+
module AtprotoAuth
|
6
|
+
module Identity
|
7
|
+
# Validates decentralized identifiers (DIDs)
|
8
|
+
class DID
|
9
|
+
PREFIXES = ["did:plc:", "did:web:"].freeze
|
10
|
+
|
11
|
+
def initialize(did)
|
12
|
+
@did = did
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate!
|
16
|
+
return if PREFIXES.any? { |prefix| @did.start_with?(prefix) }
|
17
|
+
|
18
|
+
raise Error, "Invalid DID format (must be one of #{PREFIXES.join(", ")}): #{@did}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
@did
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -68,16 +68,10 @@ module AtprotoAuth
|
|
68
68
|
raise DocumentError, "Document must be a Hash" unless data.is_a?(Hash)
|
69
69
|
raise DocumentError, "Document must have id" unless data["id"]
|
70
70
|
|
71
|
-
|
71
|
+
DID.new(data["id"]).validate!
|
72
72
|
validate_services!(data["service"])
|
73
73
|
end
|
74
74
|
|
75
|
-
def validate_did!(did)
|
76
|
-
return if did.start_with?("did:plc:")
|
77
|
-
|
78
|
-
raise DocumentError, "Invalid DID format (must be did:plc:): #{did}"
|
79
|
-
end
|
80
|
-
|
81
75
|
def validate_services!(services)
|
82
76
|
return if services.nil?
|
83
77
|
raise DocumentError, "services must be an array" unless services.is_a?(Array)
|
@@ -39,7 +39,7 @@ module AtprotoAuth
|
|
39
39
|
# @return [Hash] Resolution result with :did, :document, and :pds keys
|
40
40
|
# @raise [ResolutionError] if resolution fails
|
41
41
|
def get_did_info(did)
|
42
|
-
|
42
|
+
DID.new(did).validate!
|
43
43
|
|
44
44
|
# Fetch and parse DID document
|
45
45
|
doc_data = fetch_did_document(did)
|
@@ -108,12 +108,6 @@ module AtprotoAuth
|
|
108
108
|
raise ResolutionError, "Invalid handle format: #{handle}"
|
109
109
|
end
|
110
110
|
|
111
|
-
def validate_did!(did)
|
112
|
-
return if did.start_with?(DID_PLC_PREFIX)
|
113
|
-
|
114
|
-
raise ResolutionError, "Invalid DID format (must be did:plc:): #{did}"
|
115
|
-
end
|
116
|
-
|
117
111
|
def normalize_handle(handle)
|
118
112
|
normalized = handle.start_with?("@") ? handle[1..] : handle
|
119
113
|
normalized.downcase
|
@@ -178,17 +172,52 @@ module AtprotoAuth
|
|
178
172
|
response = AtprotoAuth.configuration.http_client.get(uri.to_s)
|
179
173
|
did = response[:body].strip
|
180
174
|
|
181
|
-
|
175
|
+
DID.new(did).validate!
|
182
176
|
get_did_info(did)
|
183
177
|
end
|
184
178
|
|
185
179
|
def fetch_did_document(did)
|
186
|
-
|
180
|
+
if did.start_with?("did:web:")
|
181
|
+
fetch_web_did_document(did)
|
182
|
+
else
|
183
|
+
fetch_plc_did_document(did)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def fetch_plc_did_document(did)
|
187
188
|
uri = URI.join(@plc_directory, "/#{did}")
|
188
189
|
response = AtprotoAuth.configuration.http_client.get(uri.to_s)
|
189
190
|
JSON.parse(response[:body])
|
190
191
|
end
|
191
192
|
|
193
|
+
def fetch_web_did_document(did)
|
194
|
+
# Strip off the "did:web:" prefix
|
195
|
+
identifier = did.delete_prefix("did:web:")
|
196
|
+
|
197
|
+
# Convert colons to slashes for path components
|
198
|
+
# But we need to handle any percent-encoded colons in the domain portion first
|
199
|
+
parts = identifier.split(":", 2) # Split on first colon to separate domain from path
|
200
|
+
domain = parts[0]
|
201
|
+
path = parts[1]
|
202
|
+
|
203
|
+
# Construct the URL
|
204
|
+
url = if path
|
205
|
+
# Replace remaining colons with slashes and append did.json
|
206
|
+
path_with_slashes = path.tr(":", "/")
|
207
|
+
"https://#{domain}/#{path_with_slashes}/did.json"
|
208
|
+
else
|
209
|
+
# No path - use .well-known location
|
210
|
+
"https://#{domain}/.well-known/did.json"
|
211
|
+
end
|
212
|
+
|
213
|
+
begin
|
214
|
+
response = AtprotoAuth.configuration.http_client.get(url)
|
215
|
+
JSON.parse(response[:body])
|
216
|
+
rescue StandardError => e
|
217
|
+
raise ResolutionError, "Failed to fetch did:web document: #{e.message}"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
192
221
|
def validate_pds_url!(url)
|
193
222
|
uri = URI(url)
|
194
223
|
return if uri.is_a?(URI::HTTPS)
|
data/lib/atproto_auth/version.rb
CHANGED
data/lib/atproto_auth.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atproto_auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Huckabee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jose
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- lib/atproto_auth/errors.rb
|
93
93
|
- lib/atproto_auth/http_client.rb
|
94
94
|
- lib/atproto_auth/identity.rb
|
95
|
+
- lib/atproto_auth/identity/did.rb
|
95
96
|
- lib/atproto_auth/identity/document.rb
|
96
97
|
- lib/atproto_auth/identity/resolver.rb
|
97
98
|
- lib/atproto_auth/par.rb
|