Labs/F1/Modularity/WebMod-API: Difference between revisions

From MozillaWiki
< Labs‎ | F1‎ | Modularity
Jump to navigation Jump to search
(another pass)
(add "validation" as an error result)
 
(6 intermediate revisions by the same user not shown)
Line 5: Line 5:
== Authentication ==
== Authentication ==


'''Note: ''' This section is just ideas from markh.  Alternative ideas can be found at http://etherpad.mozilla.com:9000/howa.  Further, authentication is so fundamental that the agreed authentication spec should be formalized in the OWA specification rather than the F1 specification (ie, this section should be moved!)
Authentication is all performed by the WMF library - see [[Labs/F1/Modularity#Authentication]] for details.


The APIs used for authentication also provide the functionality for obtaining information about the user, such as their name, favicon, etc.
== Sharing ==


To be implemented by the app (ie, APIs called by F1)
To be implemented by the app (ie, APIs called by F1)


=== getUserInfos() ===
=== link.send.getCharacteristics() ===
 
Get enough metadata about the application so the necessary UI for the service can be dynamically built.  This is similar to the current F1 "services" global, and allows F1 to offer "send to wall" for facebook versus "send to my contacts" for linkedin.


Returns an object with <tt>users</tt> and optionally <tt>login</tt> attributes.
The information returned by this method is static and must not depend on the logged-in user, if any.  IOW, this method may be called before a user is logged in and may not be called again after login/logout events.


<tt>users</tt> is a ''list'' of infos for each logged in user to the serviceIf the list contains more than 1 item, multiple accounts against that service are being used (eg, 2 twitter accounts are configured).  The user-info will include some pre-defined fields (eg, name, username, avatar, logout/revoke related links, etc) and any other values the service desiresThe full user info (including the service specific "blobs") will be passed back into the service for many future operations.
  NOTE: As all the information here is relatively static, there was some
  discussion about putting them directly in the app manifestHowever,
  in the interests of keeping the manifest small and not requiring regular
  refreshes of the manifest to get new information, it is currently defined  
  as a methodThis may want to be re-evaluated if these calls add to a
  perception of poor performance.


Note that these user infos are not stored by F1 or the browser - but the app itself is free to manage the storage of credentials etc itself.  Thus, the service specific data should not contain the credentials but instead could be used to identify the user when multiple accounts are supported (eg, it may store an internal "user id" used internally by the app to locate the specific credentials.)
The result is an object with the following fields (mostly taken from the current F1 implementation)


Optionally, the return value will include <tt>login</tt> object, itself with a number of attributes which specify alternative login methods.  Eg, a <tt>dialog</tt> entry can specify a URL which will be loaded in a popup Window created by F1.  Services which only allow one user at a time will only return the <tt>login</tt> object when the list of logged-in users is zeroServices which allow multiple users/accounts will return this object even when there are returned users.
; name : The (localized) name of the service as displayed to the user.  If not specified the service name as defined in the manifest will be used.  The name may be rendered as a link to the 'serviceUrl'.
; serviceUrl; A link to the 'home page' for this particular service.  If not specified the application's origin (as defined by the app manifest) will be used.
; subject : Whether the app supports a 'subject' field.
; shareTypes : A list of ways an item can be shared with this service.  If the service supports direct messaging, then this must be reflected in shareTypes.  Each element in the list may have fields <tt>type</tt> (an identifier passed back to the service if this item is selected), <tt>label</tt> (what is shown to the user) and <tt>toLabel</tt> (the label for the 'to' field - if not specified, the 'to' field is hidden)
; textLimit: The maximum number of characters allowedIf specified, a counter will be displayed and the limit will be enforced.


When login is required/desired and a 'dialog' method is supported, F1 will open the popup and establish a postMessage channel between the popup and the invisible iframe, so the login screen and the application itself can directly communicate.  When login is complete, the app itself will be able to communicate this back to F1 (which will then re-execute this request and presumably get an extra user in the returned list, and adjust the UI accordingly)
Note the following fields from the current F1 implementation have been removed (mainly as they can be derived from the above fields.)


==== Example ====
; shorten: A boolean indicating if links must be shortened, but this can be derived on a per-share basis based on the specified textLimit and the amount of text currently entered.
; icon: The webapp manifest already defines the icons.
; features/direct: Indicated if direct messaging is supported, but this can be reflected in the 'shareTypes' field and need not have its own flag.
; revokeUrl: This URL is (or may be) specific to the currently logged in user,
so is reflected in the user-info field.
; accountLink: As above.
; signOutUrl: The service ''logout()'' method will be used.
; forceLogin: Why is this needed in F1 and why can't the service work this out itself?
; overlays: This referred to F1 implementation details so can't be supported generically.  If F1 still chooses to use overlays for selected services, these will need to be defined internally and not reflected here.
; features/medium: Seems to be a hangover from an old F1 impl?
; shareTypes[].showTo: Can be derived from whether the 'toLabel' field exists.


In these examples, we assume the service only uses a popup-based login technique.  If no users are currently logged in, the result might be:
=== link.send.getAutocompleteEntries(user_info, send_to, to_prefix, callback) ===


  {users: [], login: {dialog: 'https://example.com/login'}}
Get all the autocomplete entries for the "to" field based on the current setting of the "send to" field for the specified user and the text currently entered in the 'to' field.  For example, the facebook app might return the (filtered) list of all groups you are a member of if send_to="group wall", and twitter would send a (filtered) list of all your followers for send_to="direct".


If one user is logged in and the user only supports a single user, the result might be:
There is no concept of "paging" the results as it seem unlikely users will actively "page" an auto-complete list - instead they should focus on providing a shorter list of relevant results.


  {users: [{name: 'Joe Blow', userid: 'joeblow', favicons: [...]]}
The size of the returned list is not constrained by this method, but WebMods will be encouraged to keep the result list to a reasonable (but relevant) size, or risk offering a poor UX for users of that service.


If one user is logged in but the service supports logging in multiple users, the result might be:
If the above size restrictions are a problem, we probably need to add the concept of a "chooser ui" which is different from the auto-complete UI?


   {users: [{name: 'Joe Blow', userid: 'joeblow', favicons: [...]], login: {dialog: 'https://example.com/login'}}
   NOTE: This method exists as a way to avoid introducing a full-blown Contacts
  concept and the complexity that would involve.  However, a key downside is
  that cross-service sharing of this information becomes impossible - eg, if 2
  different services provide email addresses, nothing in this spec allows F1
  to notice that fact and reuse the email addresses for all services which
  support sending emails.


To be implemented by F1 (ie, APIs called by the app)
  NOTE: This might need fine-tuning for performance reasons - currently F1 uses
  a cache of contacts, but the technique described here probably needs one
  call per character typed.  I guess we can still make the caching (or lack
  thereof) the responsibility of the service itself (so while we may still make
  one call per character typed, that call need not result in network activity)


=== userInfosChanged() ===
=== link.send.send(credentials_blob, data) ===


Inform F1 that the list of logged-in users for the app has changed. F1 will refresh the service by calling getUserInfos() and adjust itself accordingly - eg, by creating a second visible iframe for the service if a new user appears, or displaying special UI if no logins exist at all.
  NOTE: The OWA spec defines that this method should be called ''confirm'' -
  this needs to be clarified.


== Sharing ==
Send an item as described by "data" - ie, perform the actual share.


To be implemented by the app (ie, APIs called by F1)
credentials_blob is the blob returned by the authentication process, or null if the WebMod does not provide the blob during auth.


=== getShareCharacteristics() ===
data is a json object describing the message to be send.  The fields are TBD but will be based closely on the F1 implementation.  No user info will be included in this data.


Get enough metadata about the application so the necessary UI for the service can be dynamically builtThis is similar to the current F1 "services" global, and allows F1 to offer "send to wall" for facebook versus "send to my contacts" for linkedin.
==== success result ====
The result will be a json object with the following fields:
; status: The status of the sendCurrently the only supported value is ''sent'', but services may also return, eg, ''pending'' to indicate it has been queued and will be sent when (eg) the network becomes available.


The result is an object with the following fields (mostly taken from the current F1 implementation)
; link: A link to the message that was just shared - eg, if the message was sent via twitter, the link would point at the specific tweet.


; name : The (localized) name of the service as displayed to the user.  If 'serviceUrl' is specified, the name will be rendered as a link to that URL, otherwise it will be rendered as plain text.
==== error result ====
; serviceUrl: The main URL for this service.
If an error occurs, it will be reported via the normal jschannel error callback (ie, with ''error'' and ''message'' parameters, where the content of ''message'' will depend on the value of ''error''All strings which will be displayed to the user should be localized. The following error values are supported:
; icon : The favicon to be displayed for this service.
; subject : Whether the app supports a 'subject' field.
; shareTypes : A list of ways an item can be shared with this service.  If the service supports direct messaging, then this must be reflected in shareTypes.  Each element in the list may have fields <tt>type</tt> (an identifier passed back to the service if this item is selected), <tt>label</tt> (what is shown to the user) and <tt>toLabel</tt> (the label for the 'to' field - if not specified, the 'to' field is hidden)
; textLimit: The maximum number of characters allowedIf specified, a counter will be displayed and the limit will be enforced.
; shorten: A boolean indicating if links must be shortened.  (XXX - is this necessary?  Can't we determine whether to shorten links based on the specified textLimit and the amount of text currently entered?)


;authentication: Indicates the message failed due to an authentication problem (eg, the cookie expired).  Authentication will be re-performed and the user will be given the opportunity of retrying the error.  ''message'' will be null.


=== getAutocompleteEntries(user_info, send_to, to_prefix, callback) ===
;validation: Indicates validation of the data failed for some reason.  ''message'' will be an object with properties ''name'' (the name of the field in the send data which failed validation) and ''reason'' (the reason the field is invalid).  The F1 UI will display the error and focus the appropriate field so the user can fix it and retry.


Get all the autocomplete entries for the "to" field based on the current setting of the "send to" field for the specified userFor example, the facebook app might return the list of all groups you are a member of if send_to="group wall", and twitter would send a list of all your followers for send_to="direct".
;http_error: Indicates a HTTP error occurred sending the item.  ''message'' will be the http error codeThis would be an appropriate error if a back-end server returned a 500 error (eg, twitter was down), but is '''not''' appropriate for a 401 error - the service should translate a 401 to an ''authentication'' error if re-authentication is necessary.


=== send(user_info, data) ===
; captcha: Indicates that even though the user is correctly logged in, the service requested a captcha be solved before the message can be sent.  ''message'' will be an object with fields ''imageurl'', ''audiourl'' and ''message''.  F1 will display the message and the image, and provide a way to play the audio, and after the user enters the answer, will re-try the send request with the optional captcha fields included.


Send an item as described by "data" - ie, perform the actual share.
Any other value will cause ''message'' to be displayed in a generic error dialog, after which the user may either retry or abandon the share.

Latest revision as of 05:46, 10 June 2011

F1 defines the following javascript postMessage/jschannel based APIs.

For simplicity, the functions are described as if they are regular blocking functions (ie, they specify a return value). However, as they are implemented using jschannels, the actual implementation will be that the caller obtains the "return value" via jschannel 'success' callback.

Authentication

Authentication is all performed by the WMF library - see Labs/F1/Modularity#Authentication for details.

Sharing

To be implemented by the app (ie, APIs called by F1)

link.send.getCharacteristics()

Get enough metadata about the application so the necessary UI for the service can be dynamically built. This is similar to the current F1 "services" global, and allows F1 to offer "send to wall" for facebook versus "send to my contacts" for linkedin.

The information returned by this method is static and must not depend on the logged-in user, if any. IOW, this method may be called before a user is logged in and may not be called again after login/logout events.

 NOTE: As all the information here is relatively static, there was some 
 discussion about putting them directly in the app manifest.  However, 
 in the interests of keeping the manifest small and not requiring regular 
 refreshes of the manifest to get new information, it is currently defined 
 as a method.  This may want to be re-evaluated if these calls add to a 
 perception of poor performance.

The result is an object with the following fields (mostly taken from the current F1 implementation)

name
The (localized) name of the service as displayed to the user. If not specified the service name as defined in the manifest will be used. The name may be rendered as a link to the 'serviceUrl'.
serviceUrl; A link to the 'home page' for this particular service. If not specified the application's origin (as defined by the app manifest) will be used.
subject
Whether the app supports a 'subject' field.
shareTypes
A list of ways an item can be shared with this service. If the service supports direct messaging, then this must be reflected in shareTypes. Each element in the list may have fields type (an identifier passed back to the service if this item is selected), label (what is shown to the user) and toLabel (the label for the 'to' field - if not specified, the 'to' field is hidden)
textLimit
The maximum number of characters allowed. If specified, a counter will be displayed and the limit will be enforced.

Note the following fields from the current F1 implementation have been removed (mainly as they can be derived from the above fields.)

shorten
A boolean indicating if links must be shortened, but this can be derived on a per-share basis based on the specified textLimit and the amount of text currently entered.
icon
The webapp manifest already defines the icons.
features/direct
Indicated if direct messaging is supported, but this can be reflected in the 'shareTypes' field and need not have its own flag.
revokeUrl
This URL is (or may be) specific to the currently logged in user,

so is reflected in the user-info field.

accountLink
As above.
signOutUrl
The service logout() method will be used.
forceLogin
Why is this needed in F1 and why can't the service work this out itself?
overlays
This referred to F1 implementation details so can't be supported generically. If F1 still chooses to use overlays for selected services, these will need to be defined internally and not reflected here.
features/medium
Seems to be a hangover from an old F1 impl?
shareTypes[].showTo
Can be derived from whether the 'toLabel' field exists.

link.send.getAutocompleteEntries(user_info, send_to, to_prefix, callback)

Get all the autocomplete entries for the "to" field based on the current setting of the "send to" field for the specified user and the text currently entered in the 'to' field. For example, the facebook app might return the (filtered) list of all groups you are a member of if send_to="group wall", and twitter would send a (filtered) list of all your followers for send_to="direct".

There is no concept of "paging" the results as it seem unlikely users will actively "page" an auto-complete list - instead they should focus on providing a shorter list of relevant results.

The size of the returned list is not constrained by this method, but WebMods will be encouraged to keep the result list to a reasonable (but relevant) size, or risk offering a poor UX for users of that service.

If the above size restrictions are a problem, we probably need to add the concept of a "chooser ui" which is different from the auto-complete UI?

 NOTE: This method exists as a way to avoid introducing a full-blown Contacts
 concept and the complexity that would involve.  However, a key downside is 
 that cross-service sharing of this information becomes impossible - eg, if 2
 different services provide email addresses, nothing in this spec allows F1
 to notice that fact and reuse the email addresses for all services which
 support sending emails.
 NOTE: This might need fine-tuning for performance reasons - currently F1 uses
 a cache of contacts, but the technique described here probably needs one
 call per character typed.  I guess we can still make the caching (or lack
 thereof) the responsibility of the service itself (so while we may still make
 one call per character typed, that call need not result in network activity)

link.send.send(credentials_blob, data)

 NOTE: The OWA spec defines that this method should be called confirm -
 this needs to be clarified.

Send an item as described by "data" - ie, perform the actual share.

credentials_blob is the blob returned by the authentication process, or null if the WebMod does not provide the blob during auth.

data is a json object describing the message to be send. The fields are TBD but will be based closely on the F1 implementation. No user info will be included in this data.

success result

The result will be a json object with the following fields:

status
The status of the send. Currently the only supported value is sent, but services may also return, eg, pending to indicate it has been queued and will be sent when (eg) the network becomes available.
link
A link to the message that was just shared - eg, if the message was sent via twitter, the link would point at the specific tweet.

error result

If an error occurs, it will be reported via the normal jschannel error callback (ie, with error and message parameters, where the content of message will depend on the value of error. All strings which will be displayed to the user should be localized. The following error values are supported:

authentication
Indicates the message failed due to an authentication problem (eg, the cookie expired). Authentication will be re-performed and the user will be given the opportunity of retrying the error. message will be null.
validation
Indicates validation of the data failed for some reason. message will be an object with properties name (the name of the field in the send data which failed validation) and reason (the reason the field is invalid). The F1 UI will display the error and focus the appropriate field so the user can fix it and retry.
http_error
Indicates a HTTP error occurred sending the item. message will be the http error code. This would be an appropriate error if a back-end server returned a 500 error (eg, twitter was down), but is not appropriate for a 401 error - the service should translate a 401 to an authentication error if re-authentication is necessary.
captcha
Indicates that even though the user is correctly logged in, the service requested a captcha be solved before the message can be sent. message will be an object with fields imageurl, audiourl and message. F1 will display the message and the image, and provide a way to play the audio, and after the user enters the answer, will re-try the send request with the optional captcha fields included.

Any other value will cause message to be displayed in a generic error dialog, after which the user may either retry or abandon the share.