You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: improve SignedPayload structure and harden edge cases
- Extract duplicated payload/HMAC logic into private instance methods
(payloadData(), sign()) to reduce code noise (DRY)
- Reorder methods: public static -> public instance -> private static
-> private instance (standard PHP convention)
- Make handleSignedCall() and methodIsSigned() private (minimal surface)
- Combine chained filter() calls into single filter in methodIsSigned()
and Signed::resolveMethodTtl()
- Use nullsafe operator in resolveMethodTtl() ($signed?->ttl)
- Replace implicit TTL falsy coercion ($ttl ?) with explicit $ttl > 0
- Add test for __callSigned called with no params
- Add documentation comments for design tradeoffs (public constructor,
replay behavior, TTL 0->null normalization, $__livewire dependency)
- Update docs to reflect current architecture
Copy file name to clipboardExpand all lines: docs/signed-actions.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,7 +78,7 @@ Replace inline method calls with the `@livewireAction` directive:
78
78
79
79
1.**At render time**, `@livewireAction` generates an HMAC-SHA256 signature over the method name, parameters, and component ID using a purpose-specific key derived from your `APP_KEY` (domain-separated so that other subsystems sharing the same key cannot produce cross-valid signatures)
80
80
2. The signed payload is encoded as a base64 string and rendered as `__callSigned('eyJ...')`
81
-
3.**When clicked**, the `SupportSignedActions` hook intercepts the call, verifies the HMAC, checks the component ID matches, and only then executes the method
81
+
3.**When clicked**, the `SupportSignedActions` hook intercepts the call and verifies in sequence: payload structure → field types → HMAC signature → expiry (if TTL is set) → component ID match. Only then is the method executed
82
82
4. Direct calls to `#[Signed]` methods (e.g., `$wire.call('delete', 5)`) are **blocked**
83
83
84
84
### What's protected
@@ -87,6 +87,7 @@ Replace inline method calls with the `@livewireAction` directive:
87
87
|--------|--------|
88
88
| Change parameters in DOM | ❌ HMAC verification fails |
89
89
| Call signed method directly via JS | ❌ Blocked - must use signed payload |
90
+
| Call `__callSigned` with no payload | ❌ Blocked - payload parameter required |
90
91
| Replay payload on different component | ❌ Component ID mismatch |
0 commit comments