authproto 0.3.0.beta2 → 0.3.0.beta3

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +108 -5
  4. data/examples/confidential_client/README.md +10 -0
  5. data/examples/confidential_client/app.rb +8 -7
  6. data/examples/confidential_client/scripts/generate_keys.rb +1 -1
  7. data/examples/minisky_console/Gemfile.lock +2 -2
  8. data/examples/minisky_console/README.md +20 -1
  9. data/examples/minisky_console/localhost.rb +5 -3
  10. data/examples/minisky_console/production.rb +9 -3
  11. data/lib/authproto/client.rb +73 -90
  12. data/lib/authproto/configuration.rb +37 -16
  13. data/lib/authproto/dpop/client.rb +105 -40
  14. data/lib/authproto/dpop/{key_manager.rb → key_set.rb} +54 -120
  15. data/lib/authproto/dpop/nonce_manager.rb +33 -20
  16. data/lib/authproto/dpop/proof_generator.rb +17 -32
  17. data/lib/authproto/dpop.rb +19 -0
  18. data/lib/authproto/http_helpers.rb +85 -0
  19. data/lib/authproto/metadata/authorization_server.rb +12 -6
  20. data/lib/authproto/metadata/client_metadata.rb +18 -5
  21. data/lib/authproto/metadata/resource_server.rb +4 -2
  22. data/lib/authproto/minisky.rb +36 -34
  23. data/lib/authproto/par/client.rb +22 -73
  24. data/lib/authproto/par/client_assertion.rb +47 -16
  25. data/lib/authproto/par/request.rb +4 -8
  26. data/lib/authproto/par.rb +2 -1
  27. data/lib/authproto/serialization/session.rb +31 -13
  28. data/lib/authproto/serialization/token_set.rb +1 -2
  29. data/lib/authproto/state/session.rb +66 -6
  30. data/lib/authproto/state/session_manager.rb +95 -21
  31. data/lib/authproto/state/token_set.rb +16 -16
  32. data/lib/authproto/state.rb +1 -1
  33. data/lib/authproto/storage/key_builder.rb +3 -11
  34. data/lib/authproto/storage/memory.rb +8 -2
  35. data/lib/authproto/token/refresh.rb +26 -59
  36. data/lib/authproto/validated_uri.rb +23 -0
  37. data/lib/authproto/version.rb +1 -1
  38. data/lib/authproto.rb +0 -1
  39. data/sig/authproto/client.rbs +5 -7
  40. data/sig/authproto/dependencies.rbs +2 -0
  41. data/sig/authproto/dpop/client.rbs +11 -4
  42. data/sig/authproto/dpop/{key_manager.rbs → key_set.rbs} +9 -11
  43. data/sig/authproto/dpop/nonce_manager.rbs +4 -4
  44. data/sig/authproto/dpop/proof_generator.rbs +5 -10
  45. data/sig/authproto/dpop.rbs +6 -0
  46. data/sig/authproto/http_helpers.rbs +7 -0
  47. data/sig/authproto/localhost_server.rbs +1 -1
  48. data/sig/authproto/metadata/authorization_server.rbs +1 -0
  49. data/sig/authproto/metadata/client_metadata.rbs +2 -1
  50. data/sig/authproto/metadata/resource_server.rbs +1 -0
  51. data/sig/authproto/minisky_oauth.rbs +5 -2
  52. data/sig/authproto/par/client.rbs +4 -8
  53. data/sig/authproto/par/client_assertion.rbs +4 -0
  54. data/sig/authproto/par/request.rbs +0 -9
  55. data/sig/authproto/state/session.rbs +10 -3
  56. data/sig/authproto/state/session_manager.rbs +8 -3
  57. data/sig/authproto/state/token_set.rbs +1 -2
  58. data/sig/authproto/storage/key_builder.rbs +1 -2
  59. data/sig/authproto/token/refresh.rbs +3 -4
  60. data/sig/authproto.rbs +5 -2
  61. metadata +14 -19
  62. data/.rspec +0 -1
  63. data/.rubocop.yml +0 -31
  64. data/.tm_properties +0 -1
  65. data/.yardopts +0 -5
  66. data/AGENTS.md +0 -80
  67. data/Rakefile +0 -8
  68. data/examples/confidential_client/.gitignore +0 -6
  69. data/examples/minisky_console/.gitignore +0 -2
  70. data/lib/authproto/serialization/dpop_key.rb +0 -38
  71. data/misc/yard_attributes.rb +0 -34
  72. data/sig/authproto/serialization/dpop_key.rbs +0 -14
@@ -1,25 +1,23 @@
1
1
  module AuthProto
2
2
  module DPoP
3
- class KeyManager
3
+ class KeySet
4
4
  class KeyError < AuthProto::Error
5
5
  end
6
6
 
7
7
  CURVE: String
8
- ALGORITHM: String
9
- attr_reader keypair: JOSE::JWK
8
+ attr_reader key: JOSE::JWK
10
9
 
11
- def initialize: (?JOSE::JWK? keypair) -> void
12
- def generate_keypair: () -> JOSE::JWK
10
+ def initialize: (?JOSE::JWK? key) -> void
13
11
  def public_jwk: () -> json_object
14
- def sign: (String data) -> JOSE::SignedBinary
15
12
  def sign_segments: (Hash[String | Symbol, untyped] header, Hash[String | Symbol, untyped] payload) -> JOSE::SignedBinary
16
- def deep_stringify_keys: (untyped obj) -> untyped
17
- def verify: (String signed_jws) -> bool
18
- def to_jwk: (?include_private: bool) -> JOSE::Map
19
- def self.from_jwk: (json_object | JOSE::Map jwk) -> KeyManager
13
+ def private_jwk: () -> json_object
14
+ def self.from_jwk: (json_object | JOSE::Map jwk) -> KeySet
20
15
 
21
16
  private
22
- def generate_kid: (json_object | JOSE::Map jwk) -> String
17
+ def generate_keypair: () -> JOSE::JWK
18
+ def sign: (String data) -> JOSE::SignedBinary
19
+ def deep_stringify_keys: (untyped obj) -> untyped
20
+ def verify: (String signed_jws) -> bool
23
21
  def validate_keypair: () -> void
24
22
  end
25
23
  end
@@ -7,13 +7,13 @@ module AuthProto
7
7
  class NonceError < AuthProto::Error
8
8
  end
9
9
 
10
- DEFAULT_TTL: Integer
11
10
  def initialize: (?ttl: Integer?) -> void
12
- def update: (nonce: String, server_url: String) -> void
13
- def get: (String server_url) -> String?
14
- def clear: (String server_url) -> bool
11
+ def update: (nonce: String, server_url: String, session_id: String) -> void
12
+ def get: (server_url: String, session_id: String) -> String?
13
+ def clear: (server_url: String, session_id: String) -> bool
15
14
 
16
15
  private
16
+ def validate_session_id: (String session_id) -> void
17
17
  def normalize_server_url: (String url) -> String
18
18
  def validate_inputs: (String nonce, String server_url) -> void
19
19
  def validate_server_url: (String server_url) -> void
@@ -1,35 +1,30 @@
1
1
  module AuthProto
2
2
  module DPoP
3
3
  class ProofGenerator
4
- @key_manager: AuthProto::DPoP::KeyManager
5
-
6
4
  class ProofError < AuthProto::Error
7
5
  end
8
6
 
9
- attr_reader key_manager: AuthProto::DPoP::KeyManager
10
-
11
- def initialize: (AuthProto::DPoP::KeyManager key_manager) -> void
7
+ def initialize: () -> void
12
8
 
13
9
  def generate: (
10
+ key_set: KeySet,
14
11
  method: String,
15
12
  uri: String,
16
13
  ?nonce: String?,
17
- ?access_token: String?,
18
- ?ath: bool?
14
+ ?access_token: String?
19
15
  ) -> JOSE::SignedBinary
20
16
 
21
17
  private
22
18
 
23
19
  def validate_inputs: (String method, String uri) -> void
24
20
 
25
- def build_header: () -> { typ: "dpop+jwt", alg: "ES256", jwk: Hash[String, untyped] }
21
+ def build_header: (KeySet key_set) -> { typ: "dpop+jwt", alg: "ES256", jwk: Hash[String, untyped] }
26
22
 
27
23
  def build_payload: (
28
24
  method: String,
29
25
  uri: String,
30
26
  ?nonce: String?,
31
- ?access_token: String?,
32
- ?include_ath: bool?
27
+ ?access_token: String?
33
28
  ) -> Hash[String, untyped]
34
29
 
35
30
  def normalize_uri: (String uri) -> String
@@ -0,0 +1,6 @@
1
+ module AuthProto
2
+ module DPoP
3
+ ALGORITHM: String
4
+ ERROR_USE_NONCE: String
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module AuthProto
2
+ module HTTPHelpers
3
+ private
4
+ def authentication_challenge: (String? header, scheme: String) -> Hash[String, String]?
5
+ def response_header: (http_response response, String name, ?strip_parameters: bool) -> String?
6
+ end
7
+ end
@@ -1,6 +1,6 @@
1
1
  module AuthProto
2
2
  class LocalhostServer
3
- type metadata = Hash[String | Symbol, untyped]
3
+ type metadata = Hash[String | Symbol, untyped] | Metadata::ClientMetadata
4
4
  type callback_params = { code: String, state: String, iss: String }
5
5
 
6
6
  MAX_HEADER_BYTES: Integer
@@ -1,6 +1,7 @@
1
1
  module AuthProto
2
2
  module Metadata
3
3
  class AuthorizationServer
4
+ extend HTTPHelpers
4
5
  @issuer: String
5
6
  @authorization_endpoint: String
6
7
  @token_endpoint: String
@@ -2,6 +2,7 @@ module AuthProto
2
2
  module Metadata
3
3
  # Handles and validates AT Protocol OAuth client metadata.
4
4
  class ClientMetadata
5
+ extend HTTPHelpers
5
6
  AUTH_METHOD_PRIVATE_KEY_JWT: String
6
7
  AUTH_METHOD_NONE: String
7
8
  SCOPE_PATTERN: Regexp
@@ -55,7 +56,7 @@ module AuthProto
55
56
 
56
57
  def self.from_url: (String url) -> ClientMetadata
57
58
 
58
- def self.from_localhost_url: (String url) -> ClientMetadata
59
+ private def self.from_localhost_url: (String url) -> ClientMetadata
59
60
 
60
61
  def confidential?: () -> bool
61
62
 
@@ -1,6 +1,7 @@
1
1
  module AuthProto
2
2
  module Metadata
3
3
  class ResourceServer
4
+ extend HTTPHelpers
4
5
  @authorization_server: String
5
6
 
6
7
  attr_reader authorization_server: String
@@ -2,15 +2,18 @@
2
2
  # Additional methods mixed in from Minisky::Requests belong to the minisky gem.
3
3
  class Minisky
4
4
  class OAuthClient
5
+ include AuthProto::HTTPHelpers
5
6
  MAX_NONCE_RETRIES: Integer
6
7
  attr_reader host: String
7
8
  attr_reader oauth_client: AuthProto::Client
8
9
  attr_reader session_id: String?
9
10
 
10
- def initialize: (String host, client_id: String, redirect_uri: String, ?metadata: AuthProto::json_object?, ?dpop_key: (AuthProto::json_object | JOSE::Map)?, ?signing_key: (AuthProto::json_object | JOSE::JWK)?, ?session_id: String?) -> void
11
+ def initialize: (String host, client_id: String, redirect_uri: String, ?metadata: AuthProto::json_object?, ?signing_key: (AuthProto::json_object | JOSE::JWK)?, ?session_id: String?) -> void
11
12
  def config: () -> nil
12
13
  def authorize: (?handle: String?, ?pds: String?, ?scope: String) -> AuthProto::authorization_result
13
- def handle_callback: (code: String, state: String, iss: String) -> AuthProto::callback_result
14
+ def handle_callback: (
15
+ code: String, state: String, iss: String, expected_session_id: String
16
+ ) -> AuthProto::callback_result
14
17
  def get_request: (String | URI::HTTP method, ?Hash[untyped, untyped]? params, ?auth: bool, ?headers: Hash[String, String]?) -> untyped
15
18
  def post_request: (String | URI::HTTP method, ?untyped data, ?auth: bool, ?headers: Hash[String, String]?, ?params: Hash[untyped, untyped]?) -> untyped
16
19
  def log_in: (*untyped args) -> bot
@@ -1,23 +1,19 @@
1
1
  module AuthProto
2
2
  module PAR
3
3
  class Client
4
+ include HTTPHelpers
4
5
  attr_reader authorization_server: Metadata::AuthorizationServer
5
6
  attr_reader par_endpoint: String
6
7
  attr_reader dpop_client: DPoP::Client
7
8
 
8
9
  def initialize: (authorization_server: Metadata::AuthorizationServer, dpop_client: DPoP::Client) -> void
9
- def submit: (Request request) -> Response
10
- def extract_nonce: (http_response response) -> String
10
+ def submit: (Request request, session: State::Session) -> Response
11
11
  def build_authorization_url: (request_uri: String, client_id: String) -> String
12
12
 
13
13
  private
14
- def make_request: (Request request) -> http_response
15
- def build_headers: (Request request, String dpop_proof) -> Hash[String, String]
16
- def requires_nonce?: (http_response response) -> bool
17
- def store_nonce: (String nonce) -> void
18
- def server_origin: () -> String
14
+ def make_request: (Request request, session: State::Session) -> http_response
19
15
  def handle_error_response: (http_response response) -> bot
20
- def process_response: (http_response response) -> Response
16
+ def handle_success_response: (http_response response) -> Response
21
17
  end
22
18
  end
23
19
  end
@@ -3,9 +3,13 @@ module AuthProto
3
3
  class ClientAssertion
4
4
  class Error < AuthProto::Error
5
5
  end
6
+ ALGORITHM: String
6
7
  attr_reader signing_key: JOSE::JWK
7
8
  def initialize: (client_id: String, signing_key: (json_object | JOSE::JWK)) -> void
8
9
  def generate_jwt: (audience: String, ?lifetime: Integer) -> String
10
+
11
+ private
12
+ def validate_signing_key: ((json_object | JOSE::JWK) signing_key) -> JOSE::JWK
9
13
  end
10
14
  end
11
15
  end
@@ -8,7 +8,6 @@ module AuthProto
8
8
  @scope: String
9
9
  @login_hint: String?
10
10
  @nonce: String?
11
- @dpop_proof: String?
12
11
  @client_assertion: ClientAssertion?
13
12
 
14
13
  class Configuration
@@ -19,7 +18,6 @@ module AuthProto
19
18
  attr_accessor scope: String?
20
19
  attr_accessor login_hint: String?
21
20
  attr_accessor nonce: String?
22
- attr_accessor dpop_proof: String?
23
21
  attr_accessor client_assertion: ClientAssertion?
24
22
  end
25
23
 
@@ -30,7 +28,6 @@ module AuthProto
30
28
  attr_reader scope: String
31
29
  attr_reader login_hint: String?
32
30
  attr_reader nonce: String?
33
- attr_reader dpop_proof: String?
34
31
  attr_reader client_assertion: ClientAssertion?
35
32
 
36
33
  def self.build: () { (Configuration) -> untyped } -> Request
@@ -43,16 +40,10 @@ module AuthProto
43
40
 
44
41
  def build_params: (audience: String?) -> Hash[String, String]
45
42
 
46
- def add_optional_params: (Hash[String, String] params) -> void
47
-
48
- def add_client_auth_params: (Hash[String, String] params) -> void
49
-
50
43
  def validate_request: () -> void
51
44
 
52
45
  def validate_required_params: () -> void
53
46
 
54
- def validate_scope: () -> void
55
-
56
47
  def validate_client_auth: () -> void
57
48
  end
58
49
  end
@@ -4,8 +4,12 @@ module AuthProto
4
4
  include MonitorMixin
5
5
 
6
6
  attr_reader session_id: String
7
- attr_reader state_token: String
7
+ attr_reader state_token: String?
8
+ attr_reader authorization_expires_at: Time?
8
9
  attr_reader client_id: String
10
+ attr_reader dpop_key: DPoP::KeySet
11
+ attr_reader signing_key_id: String?
12
+ attr_reader signing_key_thumbprint: String?
9
13
  attr_reader scope: String
10
14
  attr_reader pkce_verifier: String
11
15
  attr_reader pkce_challenge: String
@@ -13,12 +17,15 @@ module AuthProto
13
17
  attr_reader did: String?
14
18
  attr_reader tokens: TokenSet?
15
19
 
16
- def initialize: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?) -> void
20
+ def initialize: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?, ?signing_key_id: String?, ?signing_key_thumbprint: String?, ?dpop_key: DPoP::KeySet, ?authorization_expires_at: Time?) -> void
21
+ def clear_state_token: () -> nil
17
22
  def authorization_server=: (Metadata::AuthorizationServer server) -> Metadata::AuthorizationServer
18
23
  def did=: (String did) -> String
19
24
  def tokens=: (TokenSet tokens) -> String
20
25
  def session_data: () -> AuthProto::session_data?
21
- def authorized?: () -> bool
26
+ def pending?: () -> bool
27
+ def tokens_valid?: () -> bool
28
+ alias authorized? tokens_valid?
22
29
  def renewable?: () -> bool
23
30
  end
24
31
  end
@@ -2,14 +2,19 @@ module AuthProto
2
2
  module State
3
3
  class SessionManager
4
4
  @serializer: Serialization::Session
5
+ @supported_signing_keys: Hash[String, String]
5
6
 
6
- def initialize: () -> void
7
- def create_session: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?) -> Session
7
+ def initialize: (?supported_signing_keys: Hash[String, String]) -> void
8
+ def create_session: (client_id: String, scope: String, ?auth_server: Metadata::AuthorizationServer?, ?did: String?, ?signing_key_id: String?) -> Session
8
9
  def update_session: (Session session) -> Session
10
+ def complete_authorization: (Session session) -> Session
9
11
  def get_session: (String session_id) -> Session?
10
- def get_session_by_state: (String? state) -> Session?
12
+ def get_session_by_state_token: (String? state) -> Session?
11
13
  def delete_session: (String session_id) -> void
12
14
  def cleanup_expired: () -> void
15
+
16
+ private
17
+ def session_ttl: (Session session) -> Integer?
13
18
  end
14
19
  end
15
20
  end
@@ -3,14 +3,13 @@ module AuthProto
3
3
  class TokenSet
4
4
  @access_token: String
5
5
  @refresh_token: String?
6
- @token_type: String
7
6
  @scope: String
8
7
  @sub: String
9
8
  @expires_at: Time
10
9
 
11
10
  attr_reader access_token: String
12
11
  attr_reader refresh_token: String?
13
- attr_reader token_type: String
12
+ def token_type: () -> "DPoP"
14
13
  attr_reader scope: String
15
14
  attr_reader expires_at: Time
16
15
  attr_reader sub: String
@@ -5,8 +5,7 @@ module AuthProto
5
5
  NAMESPACE_PREFIX: String
6
6
  def self.session_key: (String id) -> String
7
7
  def self.state_key: (String token) -> String
8
- def self.nonce_key: (String server_url) -> String
9
- def self.dpop_key: (String client_id) -> String
8
+ def self.nonce_key: (String session_id, String server_url) -> String
10
9
  def self.lock_key: (String namespace, String id) -> String
11
10
 
12
11
  private
@@ -17,6 +17,7 @@ module AuthProto
17
17
  end
18
18
 
19
19
  class Refresh
20
+ include HTTPHelpers
20
21
  include MonitorMixin
21
22
  MAX_RETRIES: Integer
22
23
  BASE_DELAY: Integer
@@ -26,7 +27,7 @@ module AuthProto
26
27
  attr_reader auth_server: Metadata::AuthorizationServer
27
28
  attr_reader client_metadata: Metadata::ClientMetadata
28
29
 
29
- def initialize: (session: State::Session, dpop_client: DPoP::Client, auth_server: Metadata::AuthorizationServer, client_metadata: Metadata::ClientMetadata, ?signing_key: (json_object | JOSE::JWK)?) -> void
30
+ def initialize: (session: State::Session, dpop_client: DPoP::Client, auth_server: Metadata::AuthorizationServer, client_metadata: Metadata::ClientMetadata, ?client_assertion: PAR::ClientAssertion?) -> void
30
31
  def perform_refresh: () -> State::TokenSet
31
32
 
32
33
  private
@@ -34,12 +35,10 @@ module AuthProto
34
35
  def calculate_delay: () -> Float
35
36
  def request_token_refresh: () -> State::TokenSet
36
37
  def make_token_request: (State::Session session) -> http_response
37
- def requires_dpop_nonce?: (http_response response) -> bool
38
- def extract_dpop_nonce: (http_response response) -> String
39
38
  def add_client_authentication: (Hash[Symbol, untyped] body) -> void
40
39
  def handle_refresh_response: (http_response response) -> State::TokenSet
41
40
  def process_successful_response: (http_response response) -> State::TokenSet
42
- def handle_400_response: (http_response response) -> bot
41
+ def handle_error_response: (http_response response) -> bot
43
42
  def handle_rate_limit_response: (http_response response) -> bot
44
43
  def validate_refresh_response: (json_object data) -> void
45
44
  end
data/sig/authproto.rbs CHANGED
@@ -34,16 +34,19 @@ module AuthProto
34
34
  end
35
35
 
36
36
  class Configuration
37
- attr_accessor default_token_lifetime: Integer
37
+ attr_accessor client_assertion_lifetime: Integer
38
38
  attr_accessor dpop_nonce_lifetime: Integer
39
- attr_accessor encryption: untyped
40
39
  attr_accessor http_client: _HTTPClient?
41
40
  attr_accessor logger: Logger
41
+ attr_accessor pending_session_ttl: Integer
42
42
  attr_accessor storage: Storage::Interface
43
43
  def initialize: () -> void
44
44
  def validate: () -> true
45
45
 
46
46
  private
47
+ def validate_client_assertion_lifetime: () -> void
48
+ def validate_dpop_nonce_lifetime: () -> void
49
+ def validate_pending_session_ttl: () -> void
47
50
  def validate_storage: () -> void
48
51
  def validate_http_client: () -> void
49
52
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authproto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.beta2
4
+ version: 0.3.0.beta3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Huckabee
8
8
  - Kuba Suder
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
11
  date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
@@ -55,21 +55,16 @@ dependencies:
55
55
  description: A Ruby library for implementing AT Protocol OAuth flows, including DPoP,
56
56
  PAR, and dynamic client registration. Supports both client and server-side implementations
57
57
  with comprehensive security features.
58
+ email:
59
+ - jakub.suder@gmail.com
58
60
  executables: []
59
61
  extensions: []
60
62
  extra_rdoc_files: []
61
63
  files:
62
- - ".rspec"
63
- - ".rubocop.yml"
64
- - ".tm_properties"
65
- - ".yardopts"
66
- - AGENTS.md
67
64
  - CHANGELOG.md
68
65
  - MIT-LICENSE.txt
69
66
  - README.md
70
- - Rakefile
71
67
  - SECURITY.md
72
- - examples/confidential_client/.gitignore
73
68
  - examples/confidential_client/Gemfile
74
69
  - examples/confidential_client/Gemfile.lock
75
70
  - examples/confidential_client/README.md
@@ -83,7 +78,6 @@ files:
83
78
  - examples/confidential_client/views/authorized.erb
84
79
  - examples/confidential_client/views/index.erb
85
80
  - examples/confidential_client/views/layout.erb
86
- - examples/minisky_console/.gitignore
87
81
  - examples/minisky_console/Gemfile
88
82
  - examples/minisky_console/Gemfile.lock
89
83
  - examples/minisky_console/README.md
@@ -95,14 +89,16 @@ files:
95
89
  - lib/authproto.rb
96
90
  - lib/authproto/client.rb
97
91
  - lib/authproto/configuration.rb
92
+ - lib/authproto/dpop.rb
98
93
  - lib/authproto/dpop/client.rb
99
- - lib/authproto/dpop/key_manager.rb
94
+ - lib/authproto/dpop/key_set.rb
100
95
  - lib/authproto/dpop/nonce_manager.rb
101
96
  - lib/authproto/dpop/proof_generator.rb
102
97
  - lib/authproto/dpop/stored_nonce.rb
103
98
  - lib/authproto/encryption.rb
104
99
  - lib/authproto/errors.rb
105
100
  - lib/authproto/http_client.rb
101
+ - lib/authproto/http_helpers.rb
106
102
  - lib/authproto/insecure_http_client.rb
107
103
  - lib/authproto/localhost_server.rb
108
104
  - lib/authproto/metadata.rb
@@ -117,7 +113,6 @@ files:
117
113
  - lib/authproto/par/response.rb
118
114
  - lib/authproto/pkce.rb
119
115
  - lib/authproto/serialization/base.rb
120
- - lib/authproto/serialization/dpop_key.rb
121
116
  - lib/authproto/serialization/session.rb
122
117
  - lib/authproto/serialization/stored_nonce.rb
123
118
  - lib/authproto/serialization/token_set.rb
@@ -133,17 +128,18 @@ files:
133
128
  - lib/authproto/token/refresh.rb
134
129
  - lib/authproto/validated_uri.rb
135
130
  - lib/authproto/version.rb
136
- - misc/yard_attributes.rb
137
131
  - sig/authproto.rbs
138
132
  - sig/authproto/client.rbs
139
133
  - sig/authproto/dependencies.rbs
134
+ - sig/authproto/dpop.rbs
140
135
  - sig/authproto/dpop/client.rbs
141
- - sig/authproto/dpop/key_manager.rbs
136
+ - sig/authproto/dpop/key_set.rbs
142
137
  - sig/authproto/dpop/nonce_manager.rbs
143
138
  - sig/authproto/dpop/proof_generator.rbs
144
139
  - sig/authproto/dpop/stored_nonce.rbs
145
140
  - sig/authproto/encryption.rbs
146
141
  - sig/authproto/http_client.rbs
142
+ - sig/authproto/http_helpers.rbs
147
143
  - sig/authproto/insecure_http_client.rbs
148
144
  - sig/authproto/localhost_server.rbs
149
145
  - sig/authproto/metadata/authorization_server.rbs
@@ -157,7 +153,6 @@ files:
157
153
  - sig/authproto/par/response.rbs
158
154
  - sig/authproto/pkce.rbs
159
155
  - sig/authproto/serialization/base.rbs
160
- - sig/authproto/serialization/dpop_key.rbs
161
156
  - sig/authproto/serialization/session.rbs
162
157
  - sig/authproto/serialization/stored_nonce.rbs
163
158
  - sig/authproto/serialization/token_set.rbs
@@ -174,13 +169,13 @@ files:
174
169
  - sig/authproto/token/refresh.rbs
175
170
  - sig/authproto/validated_uri.rbs
176
171
  - sig/authproto/version.rbs
177
- homepage: https://github.com/mackuba/authproto
172
+ homepage: https://tangled.org/mackuba.eu/authproto
178
173
  licenses:
179
174
  - MIT
180
175
  metadata:
181
- homepage_uri: https://github.com/mackuba/authproto
182
- source_code_uri: https://github.com/mackuba/authproto
183
- changelog_uri: https://github.com/mackuba/authproto/blob/main/CHANGELOG.md
176
+ bug_tracker_uri: https://tangled.org/mackuba.eu/authproto/issues
177
+ changelog_uri: https://tangled.org/mackuba.eu/authproto/blob/master/CHANGELOG.md
178
+ source_code_uri: https://tangled.org/mackuba.eu/authproto
184
179
  rubygems_mfa_required: 'true'
185
180
  rdoc_options: []
186
181
  require_paths:
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,31 +0,0 @@
1
- AllCops:
2
- NewCops: enable
3
- SuggestExtensions: false
4
- TargetRubyVersion: 3.2
5
-
6
- Metrics/BlockLength:
7
- Enabled: false
8
-
9
- Metrics/ClassLength:
10
- Enabled: false
11
-
12
- Metrics/ModuleLength:
13
- Enabled: false
14
-
15
- Metrics/MethodLength:
16
- Enabled: false
17
-
18
- Metrics/AbcSize:
19
- Enabled: false
20
-
21
- Metrics/PerceivedComplexity:
22
- Enabled: false
23
-
24
- Metrics/CyclomaticComplexity:
25
- Enabled: false
26
-
27
- Style/StringLiterals:
28
- EnforcedStyle: double_quotes
29
-
30
- Style/StringLiteralsInInterpolation:
31
- EnforcedStyle: double_quotes
data/.tm_properties DELETED
@@ -1 +0,0 @@
1
- excludeInFolderSearch = "{$excludeInFolderSearch,coverage,doc}"
data/.yardopts DELETED
@@ -1,5 +0,0 @@
1
- --protected
2
- --no-private
3
- --markup markdown
4
- --load misc/yard_attributes.rb
5
- lib/**/*.rb
data/AGENTS.md DELETED
@@ -1,80 +0,0 @@
1
- ### Ruby code:
2
-
3
- - always add `# frozen_string_literal: true` at the beginning of Ruby files (both library and tests)
4
- - keep `require`s and `require_relative`s organized in separate blocks, ordered alphabetically in each:
5
-
6
- ```
7
- require 'ipaddr'
8
- require 'socket'
9
- require 'timeout'
10
- require 'uri'
11
-
12
- require_relative 'client_metadata'
13
- require_relative 'validated_uri'
14
- ```
15
-
16
- - wrap lines longer than 120 characters
17
- - for multi-line `if ... end` / `unless ... end` blocks, keep one empty line above/below separating them from the rest of the code in the method, unless it's at the beginning/end of the method, e.g.:
18
-
19
- ```
20
- def validate_grant_types(grant_types)
21
- unless grant_types.include?('authorization_code')
22
- raise InvalidClientMetadata, "grant_types must include authorization_code"
23
- end
24
-
25
- valid_types = %w[authorization_code refresh_token]
26
- ```
27
-
28
- - prefer single-quote strings for strings containing identifiers without spaces, like `'code'`, `'access_token'`, and for `require`s
29
- - prefer double-quote strings for strings containing messages with spaces meant to be shown to the user, e.g. `puts "grant_types must include authorization_code"`
30
-
31
- ### Unit tests:
32
-
33
- - use the classic RSpec `foo.should be_...` matcher style instead of `expect()`
34
- - except for calling matchers on blocks as in `expect { ... }.to(not) raise_error...`
35
- - use the classic `it "should do this"` naming for test cases instead of `it "does this"`
36
- - use raw `describe` instead of `RSpec.describe` at the top level
37
-
38
- ### Documentation:
39
-
40
- - use YARD with Markdown formatting
41
- - for class comments, keep one empty # line at the beginning and end, and one empty line above and below that, like:
42
-
43
- ```
44
-
45
- #
46
- # OAuth client implementation class.
47
- #
48
-
49
- class ...
50
- ```
51
-
52
- - for method comments, leave one empty line above, no empty # starting line, and one empty # trailing line that is immediately followed by the method definition, like:
53
-
54
- ```
55
-
56
- # Reads tokens for a session with a currently valid access token.
57
- #
58
- # @param session_id [String] session identifier
59
- # @return [Hash{Symbol => String, Integer, nil}, nil] token details, or `nil` for missing/unauthorized sessions
60
- #
61
- def get_tokens(session_id)
62
- ```
63
-
64
- - for properties, and also for one-liner classes like error types, use a compact style like:
65
-
66
- ```
67
-
68
- # Identifier of the session associated with the failure, if known.
69
- # @return [String, nil]
70
- attr_reader :session_id
71
-
72
- # Error raised when token operations fail
73
- class TokenError < Error; end
74
-
75
- ```
76
-
77
-
78
- ### Running code:
79
-
80
- - make sure you don't use the ancient system Ruby 2.6, but a version supported by the library (my installation uses `asdf`)
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: %i[spec]
@@ -1,6 +0,0 @@
1
- .env
2
- /config/client-metadata.json
3
- /config/oauth-client-metadata.json
4
- /config/keys.json
5
- /config/public-keys.json
6
- /db/