== REST API
U2F-val exposes its functionality over a REST API, which is made accessible to
authenticated clients. Clients are responsible for supplying a unique-per-user
persistent identifier for each user in its system in the form of a string no
more than 32 characters long. Usernames should only be used if they are
immutable. This user identification string is denoted userId in the API below.

=== JavaScript object type definitions
The following JavaScript objects are used when interacting with the REST API.
In addition to these, the +RegisterRequest+, +RegisterResponse+,
+AuthenticationRequest+, and +AuthenticationResponse+ types from the U2F_V2
specification are used.

==== Error
Whenever an API call results in an error, an +Error+ object is returned. The
errorCode determines the type of error, and the errorMessage gives a textual
description of the error. If applicable to the specific error, additional data
will be available in the errorData field. The HTTP status code for an error is
always a 4XX status code, such as +400 (Bad Request)+ or +404 (Not Found)+.

[source,javascript]
----
dictionary Error {
  int errorCode;
  DOMString errorMessage;
  optional any errorData;
}
----

===== Error codes
[options="header",cols="2,^1,20"]
|==================================
|Name             |Code|Description

|BadInput         |10  |
The arguments passed to the function are invalid.

|NoEligableDevices|11  |
The user has no eligable devices capable of performing the requested action.
A +DeviceDescriptor[]+ containing the users devices will be passed along with
this error, as it is often desirable to handle a user with no registered
devices differently from a user with devices that have been marked conpromised
and therefore been disabled.

|DeviceCompromised|12  |
The requested action caused the server to determine that one of the users
devices may be compromised, and has been disabled. The +DeviceDescriptor+ in
question is returned with the error.
|=================================

==== Device Descriptor
The +DeviceDescriptor+ describes a registered U2F device. Each Device has a 
unique handle used to identify the device, as well as fields showing when the
device was registered (+created+) and last successfully used (+lastUsed+).
When available, metadata about the device will be present in the +metadata+
field, containing vendor and device information. This field will be omitted if
no such metadata exists. A dictionary of key-value +properties+ is available,
which can be used by the client to store arbitrary data. Lastly, a boolean
shows if the device has been marked as compromised. A compromised device cannot
be used for authentication. The system will mark a device as compromised if it
detects something which may indicate this, and a compromised device should be
replaced.

[source,javascript]
----
dictionary DeviceDescriptor {
  DOMString handle;
  DOMString created;
  DOMString lastUsed;
  DeviceMetadata metadata;
  dictionary properties;
  boolean compromised;
};
----

==== DeviceMetadata
The metadata provided in the +DeviceDescriptor+ contains metadata about the
device vendor as well as the device itself. The two contained fields
(+VendorInfo+ and +DeviceInfo+) are described link:Metadata_Format.adoc[here].
If no metadata exists for either (or both) of these fields the fields will be
omitted.

[source,javascript]
----
dictionary DeviceMetadata {
  optional VendorInfo vendor;
  optional DeviceInfo device;
};
----

==== RegisterRequestData
The RegisterRequestData contains the parameters needed to invoke the _register_
function of a FIDO client.

[source,javascript]
----
dictionary RegisterRequestData {
  AuthenticateRequest[] authenticateRequests;
  RegisterRequest[] registerRequests;
};
----

===== Members
*authenticateRequests* of type +array+ of +AuthenticateRequest+::
  A list of AuthenticateRequest dictionaries, one for each U2F device already
  registered by the user.
*registerRequests* of type +array+ of +RegisterRequest+::
  A list of RegisterRequest dictionaries, one for each protocol version that
  the server is willing to support.

==== RegisterResponseData
The +RegisterResponseData+ contains the +RegisterResponse+ returned by a successful
call to the _register_ function of a FIDO client, as well as any properties to
set, and names of properties to return, if the registration succeeds.

[source,javascript]
----
dictionary RegisterResponseData {
  RegisterResponse registerResponse;
  Dictionary properties;
};
----

===== Members
*registerResponse* of type +RegisterResponse+::
  The RegisterResponse to return to the server for validation.
*properties* of type +Dictionary+::
  A Dictionary of properties to set for the Device created upon successful
  validation of the RegisterResponse.

==== AuthenticationRequestData
The AuthenticationRequestData contains the parameters needed to invoke the
_authenticate_ function of a FIDO client.

[source,javascript]
----
dictionaty AuthenticateRequestData {
  AuthenticateRequest[] authenticateRequests;
}
----

===== Members
*authenticateRequests* of type +array+ of +AuthenticateRequest+::
  A list of AuthenticateRequest dictionaries, one for each previously
  registered U2F device for the user.

==== AuthenticationResponseData
The AuthenticationResponseData contains the AuthenticateResponse returned by a
successful call to the _authenticate_ function of a FIDO client, as well as any
properties to set, and names of properties to return, if the authentication
succeeds.

[source,javascript]
----
dictionary AuthenticateResponseData {
  AuthenticateResponse authenticateResponse;
  Dictionary properties;
};
----

===== Members
*authenticateResponse* of type +AuthenticateResponse+::
  The AuthenticateResponse to return to the server for validation.
*properties* of type +Dictionary+::
  A Dictionary of properties to set for the Device for which authentication is
  perfomed, if authentication succeeds.

=== HTTP resources

==== /:userId
*Example*::
_https://example.com/johndoe_

==== +HTTP GET+
Returns a list of device handles, with their properties.

===== Server response
+DeviceDescriptor[]+

==== +HTTP DELETE+
Deletes all data associated with the user.


==== /:userId/register
*Example*::
_https://example.com/johndoe/register_

==== +HTTP GET+
Initializes registration for the given user (all registered devices).

===== Server response
+RegisterRequestData+
  
==== +HTTP POST+
Completes the registration, storing a new device associated with the user.

===== Client request body
+RegisterResponseData+

===== Server response
+DeviceDescriptor+


==== /:userId/authenticate
*Example*::
_https://example.com/johndoe/authenticate_

==== +HTTP GET+
Initializes authentication for the given user (all registered devices).

===== Server response
+AuthenticateRequestData+

==== +HTTP POST+
Completes the authentication, updating and returning properties for the device
which signed the challenge.

===== Client request
+AuthenticateResponseData+

===== Server response
+DeviceDescriptor+


==== /:uid/:handle
*Example*::
_https://example.com/johndoe/0f0f0f0f0f...0f_

==== +HTTP GET+
Returns properties for the device.

===== Server Response
+DeviceDescriptor+

==== +HTTP POST+
Sets properties for the device, then returns the devices (updated) properties.

===== Client Request
+Dictionary+

===== Server Response
+DeviceDescriptor+

==== +HTTP DELETE+
Removes the device registration.

===== Server Response
HTTP 204 No Content
