Skip to content

feat(protocol): signals structs#574

Merged
james-d-elliott merged 4 commits intomasterfrom
feat-signals-struct
Feb 6, 2026
Merged

feat(protocol): signals structs#574
james-d-elliott merged 4 commits intomasterfrom
feat-signals-struct

Conversation

@james-d-elliott
Copy link
Copy Markdown
Member

No description provided.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 2, 2026

Walkthrough

Introduces WebAuthn signaling types and constructors, adds helpers to emit unknown-credential signals from descriptors and credentials, expands unit tests (including credential parsing subtests), and reformats a comment. Several new exported types, methods, and tests were added; no exported APIs were removed.

Changes

Cohort / File(s) Summary
Signals & Interface
protocol/signals.go
New exported types: SignalAllAcceptedCredentials, SignalCurrentUserDetails, SignalUnknownCredential; new interface AllAcceptedCredentialsUser; constructor NewSignalAllAcceptedCredentials that returns nil for nil user and encodes credential IDs.
Signal Tests
protocol/signals_test.go
Tests for NewSignalAllAcceptedCredentials covering nil and normal cases, verifying fields and JSON marshaling; includes a test helper implementing AllAcceptedCredentialsUser.
Descriptor Helper & Tests
protocol/options.go, protocol/options_test.go
Added CredentialDescriptor.SignalUnknownCredential(rpid string) *SignalUnknownCredential and tests verifying returned struct and JSON serialization for descriptors with and without IDs.
Credential Convenience & Tests
webauthn/credential.go, webauthn/credential_test.go
Added Credential.SignalUnknownCredential(rpid string) *protocol.SignalUnknownCredential delegating to descriptor; tests validate behavior and JSON output; added tests for credential-descriptor serialization.
Credential Parsing Tests
protocol/credential_test.go
Refactored TestParseCredentialCreationResponse to run subtests for three input forms (HTTP Response, ResponseBody, Bytes), routing to respective parsers and asserting parsed fields including CBOR public-key round-trip and complete attestation/transports checks.
Minor Formatting
webauthn/types.go
Comment block reflow for WebAuthnName() only (no behavioral change).

Sequence Diagram(s)

(Skipped — changes do not introduce a multi-component sequential control flow suitable for diagramming.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰
I nibble on signals, bright and new,
IDs curled in base64 hue,
Unknowns I trumpet from my lair,
Tests hop by with tidy care,
A joyful rabbit, code and cheer! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No description was provided by the author, making it impossible to assess whether the description relates to the changeset. Add a pull request description explaining the purpose and scope of the signal structs being introduced and their intended use cases.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: introducing new signal struct types and constructors in the protocol package.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat-signals-struct

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 54.09%. Comparing base (9e7f4e8) to head (827db4c).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #574      +/-   ##
==========================================
+ Coverage   52.71%   54.09%   +1.37%     
==========================================
  Files          40       41       +1     
  Lines        2464     2481      +17     
==========================================
+ Hits         1299     1342      +43     
+ Misses        951      923      -28     
- Partials      214      216       +2     
Files with missing lines Coverage Δ
protocol/options.go 100.00% <100.00%> (ø)
protocol/signals.go 100.00% <100.00%> (ø)
webauthn/credential.go 19.69% <100.00%> (+10.32%) ⬆️
webauthn/types.go 73.68% <ø> (ø)

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@james-d-elliott james-d-elliott marked this pull request as ready for review January 3, 2026 23:08
@james-d-elliott james-d-elliott requested a review from a team as a code owner January 3, 2026 23:08
Copilot AI review requested due to automatic review settings January 3, 2026 23:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces WebAuthn protocol signal structures to support signaling various credential states. The changes add new types and helper methods for creating signal responses that can be marshaled to JSON.

  • Adds new signal structs (SignalAllAcceptedCredentials, SignalCurrentUserDetails, SignalUnknownCredential) with appropriate JSON tags
  • Implements helper methods for creating signal responses from credentials and descriptors
  • Refactors TestParseCredentialCreationResponse to test three different parsing entry points (Response, ResponseBody, Bytes)

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
protocol/signals.go New file defining signal structs and NewSignalAllAcceptedCredentials constructor function
protocol/signals_test.go Tests for the new signal functionality
protocol/options.go Adds SignalUnknownCredential method to CredentialDescriptor
protocol/options_test.go Tests for the new SignalUnknownCredential method
webauthn/credential.go Adds SignalUnknownCredential method to Credential type
webauthn/credential_test.go Tests for credential signal methods and descriptors
protocol/credential_test.go Refactors test to validate three parsing functions with the same test cases
webauthn/types.go Reformats multi-line comment for better readability

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread webauthn/credential_test.go Outdated
Comment thread protocol/signals_test.go Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
protocol/signals_test.go (1)

45-49: Consider marshaling actual instead of tc.expected for complete verification.

Line 47 marshals tc.expected rather than actual. While the assert.Equal on line 45 ensures structural equality, marshaling actual would provide end-to-end validation that the constructor's output serializes correctly.

🔎 Proposed fix
 			assert.Equal(t, tc.expected, actual)

-			data, err := json.Marshal(tc.expected)
+			data, err := json.Marshal(actual)
 			assert.NoError(t, err)
 			assert.Equal(t, tc.expectedJSON, string(data))
webauthn/credential_test.go (1)

84-129: Remove unused rpid field from test case struct.

The rpid field defined on line 87 is never used in the test execution (lines 117-128). This appears to be leftover from copy-paste.

🔎 Proposed fix
 func TestCredentials_CredentialDescriptors(t *testing.T) {
 	testCases := []struct {
 		name         string
-		rpid         string
 		have         Credentials
 		expected     []protocol.CredentialDescriptor
 		expectedJSON string
 	}{
 		{
 			"ShouldHandleStandard",
-			"example.com",
 			Credentials{
 				Credential{
 					ID: []byte("1234"),
 				},
 			},
 			[]protocol.CredentialDescriptor{
 				{
 					Type:         protocol.PublicKeyCredentialType,
 					CredentialID: protocol.URLEncodedBase64("1234"),
 				},
 			},
 			`[{"type":"public-key","id":"MTIzNA"}]`,
 		},
 		{
 			"ShouldHandleEmpty",
-			"example.com",
 			Credentials{},
 			[]protocol.CredentialDescriptor{},
 			`[]`,
 		},
 	}
protocol/credential_test.go (1)

150-151: Remove duplicate assertion.

Line 151 duplicates the assertion from line 150 - both assert ParsedPublicKeyCredential equality.

🔎 Proposed fix
 					assert.Equal(t, tc.expected.ParsedCredential, actual.ParsedCredential)
 					assert.Equal(t, tc.expected.ParsedPublicKeyCredential, actual.ParsedPublicKeyCredential)
-					assert.Equal(t, tc.expected.ParsedPublicKeyCredential, actual.ParsedPublicKeyCredential)
 					assert.Equal(t, tc.expected.Raw, actual.Raw)
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16a1b65 and 9b6cc60.

📒 Files selected for processing (8)
  • protocol/credential_test.go
  • protocol/options.go
  • protocol/options_test.go
  • protocol/signals.go
  • protocol/signals_test.go
  • webauthn/credential.go
  • webauthn/credential_test.go
  • webauthn/types.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-26T05:23:05.652Z
Learnt from: james-d-elliott
Repo: go-webauthn/webauthn PR: 497
File: webauthn/login.go:385-387
Timestamp: 2025-08-26T05:23:05.652Z
Learning: The `AttestationType` field in the webauthn.Credential struct actually contains the attestation format (like "none", "packed", "fido-u2f") rather than the attestation type. This is evident from the comment "The attestation format used (if any) by the authenticator when creating the credential" and the assignment from c.Response.AttestationObject.Format during credential creation.

Applied to files:

  • protocol/options.go
  • webauthn/types.go
🧬 Code graph analysis (7)
protocol/options.go (1)
protocol/signals.go (1)
  • SignalUnknownCredential (36-39)
protocol/credential_test.go (2)
protocol/credential.go (6)
  • ParsedCredentialCreationData (56-61)
  • ParseCredentialCreationResponse (65-76)
  • ParseCredentialCreationResponseBody (80-88)
  • ParseCredentialCreationResponseBytes (92-100)
  • ParsedCredential (29-32)
  • ParsedPublicKeyCredential (42-48)
protocol/func_test.go (1)
  • AssertIsProtocolError (12-43)
webauthn/credential_test.go (5)
webauthn/credential.go (2)
  • Credential (23-48)
  • Credentials (59-59)
protocol/signals.go (1)
  • SignalUnknownCredential (36-39)
protocol/base64.go (1)
  • URLEncodedBase64 (12-12)
protocol/options.go (2)
  • CredentialDescriptor (62-74)
  • PublicKeyCredentialType (105-105)
webauthn/types_test.go (1)
  • id (11-14)
protocol/signals.go (2)
protocol/base64.go (1)
  • URLEncodedBase64 (12-12)
protocol/credential.go (3)
  • ID (16-25)
  • Credential (34-40)
  • ID (29-32)
protocol/signals_test.go (3)
protocol/signals.go (3)
  • AllAcceptedCredentialsUser (41-44)
  • SignalAllAcceptedCredentials (23-27)
  • NewSignalAllAcceptedCredentials (3-21)
protocol/base64.go (1)
  • URLEncodedBase64 (12-12)
protocol/webauthncbor/webauthncbor.go (1)
  • Marshal (31-33)
protocol/options_test.go (3)
protocol/options.go (1)
  • CredentialDescriptor (62-74)
protocol/signals.go (1)
  • SignalUnknownCredential (36-39)
protocol/base64.go (1)
  • URLEncodedBase64 (12-12)
webauthn/credential.go (2)
protocol/credential.go (1)
  • Credential (16-25)
protocol/signals.go (1)
  • SignalUnknownCredential (36-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Agent
  • GitHub Check: StepSecurity Harden-Runner
🔇 Additional comments (6)
webauthn/types.go (1)

184-186: LGTM!

Minor documentation formatting adjustment - no functional changes.

protocol/options_test.go (1)

65-107: LGTM!

Well-structured table-driven test with good coverage of both the standard case and the edge case with no credential ID. The JSON marshaling assertions correctly verify the base64url encoding behavior.

protocol/options.go (1)

76-81: LGTM!

Clean factory method that correctly constructs the signal struct. The value receiver is consistent with the struct's usage pattern.

webauthn/credential.go (1)

50-54: LGTM!

Clean delegation pattern that reuses the existing Descriptor() method, avoiding code duplication. The documentation clearly explains the method's purpose.

webauthn/credential_test.go (1)

39-82: LGTM!

Comprehensive test coverage for SignalUnknownCredential with proper handling of both standard and edge cases. JSON marshaling verification ensures correct serialization behavior.

protocol/credential_test.go (1)

114-168: Good test refactoring!

The subtest structure effectively covers all three parsing entry points (ParseCredentialCreationResponse, ParseCredentialCreationResponseBody, ParseCredentialCreationResponseBytes) without duplicating test data. The CBOR unmarshaling verification for public keys adds valuable round-trip validation.

Comment thread protocol/signals.go
Comment thread protocol/signals.go
Comment thread protocol/signals.go
Comment thread protocol/signals.go
Comment thread protocol/signals.go
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@protocol/credential_test.go`:
- Around line 150-151: There is a duplicate assertion comparing
tc.expected.ParsedPublicKeyCredential to actual.ParsedPublicKeyCredential;
remove the redundant assert.Equal so the test only asserts this once (leave a
single assert.Equal(t, tc.expected.ParsedPublicKeyCredential,
actual.ParsedPublicKeyCredential) and delete the duplicate line).
🧹 Nitpick comments (1)
protocol/signals_test.go (1)

47-49: Consider using require.NoError for marshal error.

If json.Marshal fails, using assert.NoError allows the test to continue and compare against potentially invalid data. The other test file in this PR (webauthn/credential_test.go) uses require.NoError for the same pattern.

♻️ Suggested fix for consistency
+	"github.com/stretchr/testify/require"
...
 			data, err := json.Marshal(actual)
-			assert.NoError(t, err)
+			require.NoError(t, err)
 			assert.Equal(t, tc.expectedJSON, string(data))

Comment thread protocol/credential_test.go Outdated
@james-d-elliott james-d-elliott merged commit f75a34a into master Feb 6, 2026
12 checks passed
@james-d-elliott james-d-elliott deleted the feat-signals-struct branch February 6, 2026 10:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants