WildcatIP / other.js

The Chatternet feature platform
GNU Affero General Public License v3.0
7 stars 1 forks source link

Embedder tools w/ network helpers #111

Closed kharmabum closed 7 years ago

kharmabum commented 7 years ago

My current plan here was to provide the identity and account authentication tokens on request to features that we host. If that seems too permissive; we could alternatively modify the fetch event in such a way as to signify that the request requires the addition of the authentication headers.

tonygentilcore commented 7 years ago

We need to discuss this design. I started to explain in #otherjs, but probably better to brainstorm in person. For now, dropping the mstone. In the meantime, it'd be helpful if you could explain the motivation behind what you'd like to achieve.

kharmabum commented 7 years ago

The majority of features that the iOS client provides display results that have actions (selection or custom like "delete", "invite", "promote") that are light-weight wrappers around authenticated courier requests. Adding support for these requests to Other.js allows us to (1) move all of the shared network related code into Other.js which enables (2) a jQuery-like interface on top of the REST interface that > 90% of feature functionality will be based off of.

Assuming that only the iOS client will leverage this ability at the moment (ie respond to the request for headers), is there something obviously unsafe about simply checking the host that a feature was downloaded from; as a preliminary measure for determining trustworthiness?

tonygentilcore commented 7 years ago

My plan is to have events for those kinds of things (e.g. a DELETE_IDENTITY event from the feature to the client). Putting it together:

embedder -> other.js (user types): SET_STAGED_MESSAGE {text: '/delete @123'} (existing)

other.js -> embedder (feature decides what to do in response to that): SET_CHAT_COMPLETE_RESULTS [{identity: 123, actions: ['delete', ...]}] (existing)

embedder -> other.js (user clicks an action): ACTIVATE_CHAT_COMPLETE_RESULT {identity: 123, action: 'delete'} (existing)

other.js -> embedder (feature decides what to do in response to that): DELETE_IDENTITY {id: 123} (new)

The basic difference here is that we're telling the embedder semantically to delete the identity which gives it complete control in how to handle that (speculative UI update, retries, queuing if offline, denying if not permitted, sending to a different backed, or something we haven't thought of yet) vs telling it to just make an opaque network request.

If it's a top level goal to share the network stack, we should talk about that priority and the right way to accomplish that.

kharmabum commented 7 years ago

@tonygentilcore yes, that was super helpful. I am arguing in favor of doing away with the last step, ie the semantic layer, in the majority of cases. The API between the embedder and other.js to support layers 1-3 is very manageable and constrained largely by user interactions (like typing and selecting results). Supporting the final layer would require creating a semantic event for every kind of operation. Even if, ultimately, we decide to go that direction to support a fine-grained permission model; to the extent that it is possible, I think the logic for enforcing those permissions should be contained within other.js.

For the time being I'm arguing for a very simple permissions model:

The only difference between these two levels is the first can request to add authentication headers to its requests and the latter can't. Having this difference allows all of the existing feature functionality in iOS to move into Other.js with very few additions to the embedder-other.js contract.

kharmabum commented 7 years ago

The clients don't need to share a network stack at the moment, but building a network stack into Other.js allows us to eventually move in that direction, if desired.

The reason I'm arguing for this network layer is constructing one would be much simpler than adding a semantic layer to the API and require minimal upfront and ongoing support from embedders.

tonygentilcore commented 7 years ago

Okay, so @kharmabum had an excellent idea in #otherjs that allows us to have the best of both worlds. We keep the semantic event model between the feature and embedder, but build a trusted convenience library of "embedder tools" that the client can use to enforce permissions and handle certain events it doesn't understand (including going to the network).

tonygentilcore commented 7 years ago

This is ready for feedback on iOS integration now. Basically, I factored out all the REST API logic from the web client into a class that can just be used directly (ChatternetRestClient). Then I created a library that embedders can use to just listen for all known chatternet events (FeatureHost). Finally I refactored combinator to use the new API. So the embedder of our cloud features (echo, rechat) no longer knows anything about the rest api or supported methods.

Next step is to replace the web client's delete message menu item w/ a feature.