atproto_auth 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b5a970c60c05fb183389ef64b1fbd38bfdfc1e2cda615189e0c0e74362f6097
4
- data.tar.gz: a841c5f2eebcb6aaf093566e2abda9d0e53cd2e298d0ce20d308e96aa51bdbbf
3
+ metadata.gz: 1543cc3c9cf5c099a76a62e75990217400930bfd00f8fa19b53b4bef9c035940
4
+ data.tar.gz: 294daf80d312117a27d7bcfda8fdb1e48865793736aa3a491bf13f61f73caeaa
5
5
  SHA512:
6
- metadata.gz: 663b4810b6e888ac345a2d3a67eb8d506a2bd41257c318a7d61978172078a69b1b084f13fee6d0a42f0c982b85c46922a6c4b2b8134f8a84d88b07a36a6ce697
7
- data.tar.gz: 0e3c7cd954d9a8a7803c2aba41f12d45d3ecf877b7c130ee732f844d75cb352fabb9bf88173006610962604eff8752baf966939be5aa0263d09e808a97b35328
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- atproto_auth (0.2.1)
4
+ atproto_auth (0.2.2)
5
5
  jose (~> 1.2)
6
6
  jwt (~> 2.9)
7
7
  redis (~> 5.3)
@@ -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
- validate_did!(data["id"])
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
- validate_did!(did)
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
- validate_did!(did)
175
+ DID.new(did).validate!
182
176
  get_did_info(did)
183
177
  end
184
178
 
185
179
  def fetch_did_document(did)
186
- # Fetch document from PLC directory
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AtprotoAuth
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
5
5
  end
data/lib/atproto_auth.rb CHANGED
@@ -33,6 +33,7 @@ require "atproto_auth/state/session"
33
33
  require "atproto_auth/state/session_manager"
34
34
 
35
35
  require "atproto_auth/identity"
36
+ require "atproto_auth/identity/did"
36
37
  require "atproto_auth/identity/document"
37
38
  require "atproto_auth/identity/resolver"
38
39
 
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.1
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 00:00:00.000000000 Z
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