Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add producer and consumer modules and pin challenge * Add account delegation and device linking * Update user challenge naming and type * Add consumer onCompletion callback * Add start config types and fine tune onCompletion Add onCompletion to producer. The producer implicitly knows it is done after the challenge, but in the future the producer may stay active for multiple account link requests for consumers. The producer onCompletion will be useful then as a signal that all link requests have been handled. * Change delegateAccount and linkDevice types These are the paired functions that developers will implement. delegateAccount returns a record and linkDevice takes a record. It will be up to developers to make sure they the records match. * Add username to producer onCompletion Returning the username is mostly a convenience for developers, but moving it to the link state might prove useful for multiple accounts at some point in the future. Also, a small change in the consuer to reset the username on reseting the link state. It's not clear yet whether this should also happen in the producer, and in general whether the producer should keep listening after a consumer has been linked. * Convert callback interface to event emitter Instead of expecting callbacks to handle events, the event emitter lets a developer add event listeners. This interface is more flexible for developers and for our internal implementation -- developers can subscribe to events multiple times and we can add events in the future if we want to. At the moment, this is incomplete and we need to handle timeouts and think about cancellation semantics. Various edge cases should also be considered. * Add account linking declined message The consumer should be informed when linking was declined. A message was added when a proder declines, and an approved field was added to the link event of both the consumer and producer. * Refactor to remove module global state and more We want to avoid module global state because it may modules may be re-instantiated in some cases, which can produce unpleasant and hard to debug situations. This refactor also removes channel and user interaction side effects from many of the account linking functions, which should make them easier to test. Lastly, the dependency injected channel functions are reduced to a single createChannel function. It generates send, receive, and close functions. At the moment, the receive function is unused and maybe won't be needed. * Short circuit dispatch when no listeners An event is only created when we have at least one listener. This change prevents dispatch for events when no listeners have been added. * Add error handling * Decouple linking functions from linking state The functions are easier to test if they do not depend on the entire linking state. In addition, this will make it easier to re-use them for other AWAKE use cases. * Export linking functions for testing * Add unit tests and prop checks * Add producer state transition to delegation * Add consumer temporary key exchange retry We can't be certain that users will open a window with the producer before they request account linking in a consumer. The retry keeps trying until the consumer receives a session key from a producer. In addition, retries will be useful in cases where the producer is busy with another consumer, at least in this version. In a future version, the producer will queue up consumers that want to be linked. * Add consumer broadcast state warning There is a narrow window between when the consumer is initialized and they have broadcast a temporary RSA key. This warning will be triggered in that window and any message dropped. * Add producer warning for spurious DID messages A producer may be in the midst of linking a consumer when a request to link arrives from another consumer. The request is a DID string and we can implicitly ignore it when JSON.parse throws and display a warning instead. * Add producer check for stored username * Add received message while delegating warning * Add producer linking preflight We want to check that the producer can actually delegate the account before broadcast. The producer can delegate if it has the original keypair the account was created with or if it has a UCAN that delegates it SUPER_USER capabilities. In the first case, we check that the public key matches the DID in DNS. In the second case, we check the root issuer matches the DID in DNS and capabilities are granted in the UCAN. * Add websocket data type * Dependency inject checkCapability The checkCapability functions checks whether a producer can delegate an account given a username. The semantics of "can delegate" will depend on the implementations of the delegateAccount and linkDevice functions. Both delegateAccount and linkDevice are dependency injected, and making checkCapability dependency injectable lets implementers align all three functions. * Add username param to delegateAccount We currently set the username internally in storage at webnative.auth_username, but developers want to use username in other ways when linking a device. We pass the username into delegateAccount, which can then forward it to linkDevice during the linking process. * Print linking warnings when debug enabled * Convert confirm and reject pin to call delegation Returning a function from delegateAccount and declineDelegation was problematic because confirm or reject pin would call the returned functions multiple times. Wrapping the call internally works better and will be easier to test. * Add tryParseMessage guard We want to guard message when they expect JSON with a specific shape, but instead receive a string (a temporary DID) or a message that doesn't have the shape they expect. These cases warn because they are likely noise on the channel. A few test cases updated and fixed here as well. * Add more integration tests * Re-export account linking functions from top level The consumer closed in prematuraly in warning cases. Moved its done call to when and if it has successfully linked. * Add linkDevice unit tests * Add delegateAccount and declineDelegation unit tests * Rename and export provider and requestor types * Add auth lobby DI implementation * Add docstrings to external calls * Mark multiple consumer test as skipped We want to keep this test around for when we implement account linking message queues, but it is inconsistent and we should skip it for now. * Update changelog * Update version * Rename WebSocketData to ChannelData * Add once guard to confirm and reject pin We only want these functions to be called once and only one or the other should be called. * Rename createChannel to createWssChannel * Decrease number of filesystem API test runs * Move LinkingStep type to common linking module * Fix account registration exports Destructuring the implemenation and exporting its functions does not work because it only happens when the module evaluates. Instead, we can export wrapped versions of the implementation functions. * Rename provider and requestor Rename provider to producer and requestor to consumer. Export them at the top level under account instead of auth. * Convert linking steps to an enum * Remove unused temporaryRsaPair from producer * Use event maps (typed EventEmitter) * Convert event emitter to node style interface Co-authored-by: Brian Ginsburg <gins@brianginsburg.com> Co-authored-by: Philipp Krüger <philipp.krueger1@gmail.com>
- Loading branch information