diff --git a/index.html b/index.html index 9a9686a..0e2892b 100644 --- a/index.html +++ b/index.html @@ -46,7 +46,22 @@ } ] }, - ] + ], + localBiblio: { + "NFC_SECURITY": { + href: "https://github.com/w3c/web-nfc/security-privacy.html", + title: "Web NFC Security and Privacy", + publisher: "W3C", + date: "25 April 2015", + }, + "NFC_USECASES": { + href: "https://github.com/w3c/web-nfc/use-cases.html", + title: "Web NFC Use Cases", + publisher: "W3C", + date: "25 April 2015", + }, + }, + }; @@ -93,17 +108,6 @@ product: the user agent that implements the interfaces it contains.

- -

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the @@ -174,6 +178,15 @@ via user interface or host device platform features, via which the user approves the permission of a web app to access the Web NFC API.

+

+ The term obtain permission for a certain operation refers to + obtain expressed permission or to ensure the existence of a + prearranged trust relationship. +

+

+ URL + is defined in [[!URL]]. +

Blob is defined in [[!FILEAPI]]. @@ -190,7 +203,7 @@ are defined in [[!WEBIDL]].

- NFC stands for Near Field Communications, short-range wireless + NFC stands for Near Field Communications, short-range wireless technology operating at 13.56 MHz which enables communication between devices at a distance less than 10 cm. The NFC communications protocols and data exchange formats, and are based on existing radio-frequency @@ -201,13 +214,13 @@

An NFC adapter is the software entity in the underlying platform which provides access to NFC functionality implemented in a - given hardware element (NFC chip). A device may contain multiple NFC - adapters. + given hardware element (NFC chip). A device may have multiple NFC + adapters, for instance a built-in one, and one attached via USB.

An NFC tag is a passive, unpowered NFC device. The NFC tag is powered by magnetic induction when an active NFC - device is in proximity range. A NFC tag contains a single + device is in proximity range. An NFC tag contains a single NDEF message.

The way of reading the message may happen through proprietary @@ -281,6 +294,16 @@ URI, Smart Poster (containing a URI or other data and possible actions).

+

+ A Web NFC message is an NDEF message which contains at + least one Web NFC record. +

+

+ A Web NFC record is an NDEF record with TNF=4 + (External Type Record), and the type field set to + "urn:nfc:ext:w3.org:webnfc". Further formatting details are + described Data Types. +

An NFC handover defines NFC Forum Well Known Types and the corresponding message structure that allows negotiation and activation of an alternative communication carrier, such as Bluetooth or WiFi. @@ -294,6 +317,8 @@ web app which is invoking the methods of this API has been checked to comply with the security policies set by the underlying platform and API implementation in the moment and context of invoking the API method. + Further details are described in + Security and Privacy.

The term @@ -304,8 +329,6 @@ The term URL scope is introduced in this document for NFC operations as a sub-domain match to the web app's document URL, which includes the domain of the calling web app. - The URL scope is stored in the identifier field of an - NDEF record.

@@ -317,12 +340,14 @@
  • Hold a device close to a passive wireless tag (which could be in the form of a plastic card) to read and write or overwrite data (in the - case the tag is not read-only). + case the tag is not read-only, and it is empty or contains a + Web NFC message.
  • Hold two powered devices, e.g. phones or tablets, close to each other - in order to push data from one to the other, or to initiate a connection - using another wireless carrier such as Bluetooth or WiFi. + in order to push a Web NFC message from one to the other, or to + initiate a connection using another wireless carrier such as Bluetooth + or WiFi.
  • Card emulation
      @@ -340,17 +365,17 @@

      NFC works using magnetic induction, meaning that the reader will emit a small electric charge which then creates a magnetic field. This field powers - the passive device which turns it in to electrical impulses to communicate + the passive device which turns it into electrical impulses to communicate data. Thus, when the devices are within range, a read is always performed (see NFC Analog Specification and NFC Digital Protocol, NFC Forum, 2006). The peer-to-peer connection works in a similar way, as the device periodically switches into a so-called initiator mode in order to scan for - targets, for then to fall back into target mode. If a target is found, the + targets, then later to fall back into target mode. If a target is found, the data is read the same way as for tags.

      - As NFC is based on existing RFID standards, many NFC chipsets support - reading legacy RFIDs tags, but many of these are only supported by single + As NFC is based on existing RFID standards, many NFC chipsets support + reading RFIDs tags, but many of these are only supported by single vendors and not part of the NFC standards. Though certain devices support reading and writing to these, it is not a goal of this specification to support proprietary tags or support interoperability with legacy systems. @@ -419,38 +444,30 @@ that tag. If multiple websites can handle the tag, a choice is presented to the user to pick the preferred web site for handling the tag. - Web sites have a programmatic means to tell the user agent - they are able and interested to handle NFC tags of certain - type. + Optionally, web sites have a programmatic means to tell the + user agent they are able and interested to handle + NFC tags of certain type.

    1. Reading arbitrary tags when a website is currently open: if the user has a website open and that website has indicated that it's able to read a set of tags, it might be fine to allow that - website to read a readonly tag that the user taps without presenting + website to read a read-only tag that the user taps without presenting any permission or security dialog to the user.
    2. -
    3. - Reading "Web NFC" tags: if there is a mechanism which NFC tags - use to indicate which website that they can be read by, the user can - tap on the tag and we can open the web site automatically. There is - no need for the user to have visited the web site first or to have - the website open, and the user agent is not required to display - a dialogue asking the user which website to use. -

    Writing NFC tags

    1. Writing to arbitrary writable tags: the user opens a web page which - can write an NFC tag. This use case should be restricted or - de-scoped for security and privacy reasons. + can write an NFC tag. This use case SHOULD be restricted or + bound to user permissions for security and privacy reasons.
    2. - Writing to "Web NFC" tags: if a tag indicates that it is connected to - a given website, then user agents may allow that web site to - write to the tag without any special security dialogs. + Writing to NFC tags already containing a + Web NFC message: the user agents MAY allow web sites + to write to the tag with using appropriate security dialogs.
    @@ -474,7 +491,7 @@ devices.

    -

    Payment scenarios

    +

    Features

    @@ -532,167 +549,40 @@

    Technical requirements

    The following high level technical requirements result from the - enumerated use cases and high level features: + enumerated use cases and high level features. With this version of the + API, web pages should be able to:

      -
    1. Enumerate NFC adapters.
    2. -
    3. Set up watchers to read for a given scope (a default scope being - set by implementations to the origin of the page).
    4. -
    5. Provide event for read completed as NDEF records from tag or peer - device. Expose payload as MIME type. Eventually expose binary content - of NDEF records.
    6. -
    7. Set a predefined payload, or full binary NDEF records that the user - can push to another device when within range. Provide event for - completed push. +
    8. + Request an NFC adapter. If there are multiple adapters present, then + the user agent MAY display a dialog for selecting one of them.
    9. -
    10. [future] Manage manual connections for various NFC technologies. - Provide proximity events when tags and peers appear and disappears +
    11. + Get notified about NDEF message available from tag or peer + device.
    12. -
    13. [future] Set up the card content to be read by other devices for - Host Card Emulation. +
    14. + Set a data payload that the user can push or write to another + device when within range.
    15. -
    16. [future] Configure a predefined handover to Bluetooth or WiFi.

    - - -

    Mapping data types to NDEF messages

    -

    The following types can be used when writing NFC tags, sending - data to NFC peers, and when reading NDEF messages. -

    -
    -
    -

    - NdefData denotes the data types - supported as NDEF record payload in read and write operations in - this API. -

    -

    - The mapping from supported NdefData to - NDEF record types is as follows: -

    - - - - - - - - - - - - - - - - - - - - - -
    NdefDataNDEF record type
    DOMStringNFC Forum Well Known Type (TNF=1) with type Text
    URL
      -
    • NFC Forum Well Known Type (TNF=1) with type URI
    • -
    • NFC Forum Well Known Type (TNF=1) with type - Smart Poster -
    • -
    • Absolute URI as defined in RFC 3986 (TNF=3)
    • -
    JSONMedia-type as defined in RFC 2046 (TNF=2) with associated - MIME type "application/webnfc+json" -
    Blob -
      -
    • Media-type as defined in RFC 2046 (TNF=2)
    • -
    • NFC Forum External Type (TNF=4)
    • -
    • Unknown (TNF=5)
    • -
    • Any NDEF record type that is not covered by DOMString, - URL and JSON types. -
    • -
    -
    -
    - - -

    Examples

    -

    - This section shows how developers can make use of the various features of - this specification. -

    -
    -    navigator.nfc.findAdapters().then(function(adapters) {
    -      var adapter = adapters[0];
    -      var scope = "example.com/tag/updater";
    -
    -      adapter.onread = (msg) => {
    -        var timesRead = (msg.data.length > 0) ? msg.data[0].json().timesRead : 0;
    -        if (msg.writeable)
    -          adapter.write([{ timesRead: (timesRead + 1) % 1000 }], scope);
    -        else
    -          console.log("Read-only tag; value = " + timesRead);
    -      };
    -
    -      var watchOptions = {
    -          scope: scope,
    -          watchType: "tag-only"
    -      };
    -      adapter.watch(watchOptions).then(function() {
    -          console.log("We are now watching tags via NFC");
    -        });
    -    }).catch(function(err) {
    -      console.log("No NFC adapters found");
    -    });
    -  
    -
    -    navigator.nfc.findAdapters().then(function(adapters) {
    -      var adapter = adapters[0];
    -      var scope = "/example.com/mygame";
    -
    -      adapter.onread = (event) => {
    -        console.log("Game state received from: " + event.scope);
    -        console.log("Game state: " + event.data.json());
    -      };
    -
    -      adapter.onpush = (event) => {  // update values
    -        console.log("Successfully pushed a message to: " + event.scope);
    -        updateGameState();
    -      }
    -
    -      // fetch game state and update push message
    -      function updateGameState() {
    -        var msg =  [ { level: 3, points: 4500, lives: 3 } ];
    -        adapter.setPushMessage(msg, scope).then(function() {
    -          console.log("Game state updated for push");
    -        });
    -      };
    -
    -      var withOptions = {
    -          scope: scope,
    -          watchType: "peer-only"
    -      };
    -      adapter.watch(withOptions).then(function() {
    -        console.log("We are now watching game progress via NFC");
    -      });
    -    });
    -  
    -
    - - -

    Security and Privacy Considerations

    +

    Security and Privacy

    - User agents MUST NOT provide Web NFC API access - to web apps without the - expressed permission of the user. User agents must acquire consent - for permission through a user interface for each call to the methods of this - API, unless a prearranged trust relationship applies. + The Permissions API SHOULD + be supported by user agents for implementing NFC related + [[permissions]]. The required + + permission name is "nfc".

    - User agents may support prearranged trust relationships that do not require - such per-request user interfaces. + User agents MUST NOT provide Web NFC API access + to web apps without the expressed permission of the user. + User agents must acquire consent for [[permissions]] for each call to the + methods of this API, unless a prearranged trust relationship applies.

    Considering adding the following: @@ -702,11 +592,180 @@ for development purposes only.

    - Permissions that are preserved beyond the current browsing session must be + Permissions that are preserved beyond the current browsing session MUST be revocable.

    +

    + The Permissions API does + not yet address the issue of revoking permissions. When it will be + addressed, this section will be updated. +

    +

    + User agents MUST implement the following policies: +

      +
    1. + In order to use NFC, a website MUST be visible and in focus. For + web pages in background, receiving and sending NFC data MUST be + suspended. +
    2. +
    3. + Writing to an NFC tag, including locking the tag to read-only + MUST always obtain permission. +
    4. +
    5. + Sending data to an NFC peer MUST always obtain permission. +
    6. +
    7. + Listening to NDEF messages MUST always obtain permission. +
    8. +
    9. + In addition to the previous, only websites with a schema starting with + "https://" SHOULD be able to read NFC tags that is + not empty or does not contain a Web NFC messages. +
    10. +
    +

    + +

    Data Types

    +

    + Web NFC implementations SHOULD use Web NFC messages, which SHOULD + be sufficiently differentiated in order to avoid accidental matching with + a generic NDEF message used in regular NFC tags or between + NFC peers. This is achieved by using an additional + Web NFC record, and in rest using normal NDEF records in + order to compose the NDEF message. +

    +

    The format of a Web NFC record

    +

    + The format of a Web NFC record is the following. +

      +
    • + Uses NFC Forum External Type record (TNF=4) with the External + Type field set to urn:nfc:ext:w3.org:webnfc. +
    • +
    • + The id field contains the + + ASCII serialized origin which has written the payload. +
    • +
    • + The payload MAY be empty, or MAY contain implementation specific + contextual data encoded as Base64 ([[RFC4648]]), for instance tokens, + authentication keys etc. +
    • +
    +

    +
    +

    Web NFC message payload

    +

    + The payload of a Web NFC message is represented by using normal + NDEF records. + The following types can be used as payload, i.e. when writing to + NFC tags, sending data to NFC peers, and when reading + NDEF messages. +

    +
    +
    +

    + NfcData denotes the data types + supported as NDEF record payload in read and send operations in + this API. +

    +

    + The mapping from supported NfcData to + NDEF record types, as used in the send() + method is as follows: +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    NfcDataNDEF record type
    DOMStringNFC Forum Well Known Type (TNF=1) with type Text
    URL
      +
    • NFC Forum Well Known Type (TNF=1) with type URI
    • +
    • NFC Forum Well Known Type (TNF=1) with type + Smart Poster +
    • +
    • Absolute URI as defined in [[RFC3986]] (TNF=3)
    • +
    JSONMedia-type as defined in [[RFC2046]] (TNF=2) with associated + MIME type "application/json" +
    Blob with MIME typeMedia-type as defined in [[RFC2046]] (TNF=2)
    Blob without MIME typeNFC Forum External Type (TNF=4)
    +

    + The mapping from NDEF record types to NfcData, + as used for incoming NDEF messages exposed by the + NfcMessageEvent, is as follows: +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NDEF record typeNfcData
    NFC Forum Well Known Type (TNF=1) with type TextDOMString
    NFC Forum Well Known Type (TNF=1) with type URIURL object
    NFC Forum Well Known Type (TNF=1) with type + Smart PosterURL object
    Absolute URI as defined in [[RFC3986]] (TNF=3)URL object
    Media-type as defined in [[RFC2046]] (TNF=2) with associated + MIME type "application/json" + JSON object
    Media-type as defined in [[RFC2046]] (TNF=2)Blob object
    NFC Forum External Type (TNF=4) with type other than + urn:nfc:ext:w3.org:webnfcBlob object
    Any other NDEF record typeBlob object
    +

    + Note that Web NFC records are not exposed to client web apps. +

    +
    +
    +

    Extensions to the Navigator interface

    @@ -716,31 +775,30 @@ extends.

    -
    readonly attribute NFC nfc
    +
    readonly attribute Nfc nfc

    The nfc attribute

    When getting the nfc attribute, the - user agent MUST return the NFC object, which provides + user agent MUST return the Nfc object, which provides NFC related functionality.

    -

    The NFC interface

    -
    -
    Promise<sequence<NfcAdapter>> findAdapters()
    +

    The Nfc interface

    +
    +
    Promise<NfcAdapter> requestAdapter()

    - Implementations might expose multiple NFC adapters. By using the + Implementations MAY expose multiple NFC adapters. By using the - findAdapters() method, web apps can obtain adapter objects - providing NFC functionality, - in a similar way to that of service worker extensions [[SERVICE-WORKERS]]. + requestAdapter() method, web apps can obtain an adapter object + providing NFC functionality. When this method is invoked, the user agent MUST run the following steps: -

      +
      1. Let promise be a new Promise object.
      2. @@ -748,34 +806,52 @@ asynchronously.
      3. - If there are no sufficient permissions to use this method, + If sufficient permission has not been granted to use this method, that is, to use NFC technology from the calling web app, - then reject promise with a new - DOMException object whose name property - is set to "SecurityError", and terminate these - steps. + then reject promise with "SecurityError", + and terminate these steps.
      4. If there is no support for NFC adapter handling functionality in hardware, software, or due to physical incompatibility, - then reject promise with a new - DOMException object whose name property - is set to "NotSupportedError", and terminate - these steps. + then reject promise with + "NotSupportedError", and terminate these steps.
      5. Make a request to the underlying platform to initialize NFC functionality and enumerate available adapters. If the request fails, - then reject promise with a new - DOMException object whose name - property is set to "NotSupportedError", - and terminate these steps. + then reject promise with + "NotSupportedError", and terminate these steps. +
      6. +
      7. + If the request is successful, then select one of the adapters based on + the following algorithm: +
          +
        1. Let adapter be null.
        2. +
        3. If there is only one adapter, set adapter to that.
        4. +
        5. + If there are multiple adapters available, and there is a system or + user setting available with a default adapter being specified, set + adapter to that. +
        6. +
        7. + Otherwise, the user agent MAY pop up a user dialog for + selecting one of the listed adapters, or none of them, and + set adapter to the selected one, if available. +
        8. +
        9. + If no adapter is selected, then reject promise with + "NotFoundError", and terminate these steps. +
        10. +
        11. + Otherwise if the dialog is blocked or canceled, then select the + first built-in adapter. +
        12. +
        13. Otherwise select the first external (e.g. USB) adapter.
        14. +
      8. - If the request is successful, then resolve promise with an - array of NfcAdapter objects. Implementations SHOULD - maintain a default adapter, which SHOULD be exposed as the first - element in the returned array. + Resolve promise with adapter.

      @@ -783,23 +859,14 @@

      The NfcAdapter interface

      -
      attribute EventHandler onread
      - -
      attribute EventHandler onpush
      -
      Promise<long> watch(WatchOptions? options)
      -
      Promise<void> clearWatch(optional long id)
      -
      Promise<void> write((NdefData[] data, optional USVString scope)
      -
      Promise<void> setPushMessage((NdefData[] data, optional USVString scope)
      -
      Promise<void> clearPushMessage(optional USVString scope)
      +
      attribute EventHandler onmessage
      +
      Promise<void> send(NfcMessage message, optional NfcSendOptions options)

      The NfcAdapter interface handles incoming NDEF messages, - exposed by the NdefReadEvent event, both from - NFC tags and NFC peers. By default, listening to this event - SHOULD be disabled. Applications can subscribe to NDEF messages - originating from a given URL scope by using the watch() - method. Applications can write to an NFC tag, and set up push - messages to NFC peers. + exposed by the NfcMessageEvent event, either from an + NFC tag or an NFC peer. By default, listening to this event + SHOULD be disabled.

      @@ -815,608 +882,263 @@ event type - onread - read - NdefReadEvent - - - - onpush - push - NdefPushEvent + onmessage + message + NfcMessageEvent -

      The read event

      +

      The message event

      - The read event is used for notifying the adapter - object about a message dispatched to the web app via NFC. + The message event is used for notifying the adapter + object about an NDEF message dispatched to the web app.

      -

      The push event

      -

      - As messages are not automatically pushed to peers when they detect each - other, but most often requires some kind of user interaction, the - push event is used for notifying the adapter object about a - message successfully pushed to an NFC peer with a matching - URL scope in range via NFC. -

      -
      - - - - -

      The NdefPushEvent interface

      -
      -
      readonly attribute USVString scope
      -
      ArrayBuffer readAsMessageBuffer()
      -
      -

      - The scope property - represents the URL scope of the NDEF message. -

      -

      - When the - readAsMessageBuffer method is invoked, the - user agent MUST run the following steps: -

        -
      1. - Let arrayBuffer be a new ArrayBuffer - object. -
      2. -
      3. - Read the content of the full NDEF message raw binary data and - copy it to arrayBuffer. -
      4. -
      5. - Return arrayBuffer. -
      6. -
      -

      -
      - - -

      The NdefReadEvent interface

      + +

      The NfcMessageEvent interface

      In this specification, NDEF message content is delivered by an - NdefReadEvent event. + NfcMessageEvent event.

      -
      -

      The NdefReadEvent has all properties and methods of the - NdefPushEvent interface, and the following additional - properties: -

      -
      -
      readonly attribute boolean passive
      -
      readonly attribute boolean writeable
      -
      readonly attribute NdefRecordData[] data
      +
      +
      readonly attribute NfcMessage message

      - The passive - property MUST return true if the source of the NFC data is - a passive NFC tag, and false otherwise. -

      -

      - The writeable - property MUST return true if the source of the NFC data is - a passive NFC tag which is writeable, and false - otherwise. + The message + property MUST return the NfcMessage representing the + payload data of the NDEF message.

      -

      - The data - property represents the array of NdefRecordData - content corresponding to the array of NDEF records payload data of - the NDEF message. -

      -
      +
      - -

      The NdefRecordData interface

      + +

      The NfcMessage interface

      The content of the NDEF message is exposed by the following interface:

      -
      -
      readonly attribute DOMString contentType
      -
      DOMString url ()
      -
      Blob blob ()
      -
      any json ()
      -
      DOMString text ()
      -
      ArrayBuffer arrayBuffer ()
      +
      +
      readonly attribute USVString scope
      +
      readonly attribute sequence<any> data
      +
      // (DOMString or URL or Blob or JSON)

      - NdefRecordData objects have associated data read by the NFC chip - upon creation. + The scope + property MUST return the URL scope which has written the message.

      The - contentType - attribute describes the type of data such as MIME type and additional - information for text messages, e.g. - "text/plain;charset=UTF-8;" + data property MUST return the + payload data of the NDEF message as an array of either + DOMString, or URL object, or Blob + object, or serializable JSON object as a generic Object.

      -

      - The url() - method, when invoked, MUST return a DOMString - representing any URL stored in the NDEF message or - undefined. -

      -

      - The blob() - method, when invoked, MUST return a Blob whose - contents are bytes. -

      -

      - The json() - method, when invoked, MUST return the result of invoking the initial - value of JSON.parse with the result of running - utf-8 decode on bytes as argument. - Re-throw any exceptions thrown by JSON.parse. -

      -

      - The text() - method, when invoked, MUST return the result of running - utf-8 decode onbytes. -

      -

      - The - arrayBuffer() method, when invoked, MUST return an - ArrayBuffer whose contents are bytes. -

      -
      +
      - -

      The watch() method

      +

      The send() method

      The - - watch() method enables listening to incoming - NDEF messages. -

      -

      - As web apps might not be interested in all peer and tag messages, - filtering is possible for watched messages: -

        -
      1. - Messages have an associated identifier represented as a - URL scope, which enables filtering based on this scope. -
      2. -
      3. - Based on content types the web app can or wants to handle. -
      4. -
      5. - Watch only NFC tags, only NFC peers, or both. -
      6. -
      -

      - -

      - Future versions may add additional filtering criteria, e.g. based on - NFC Forum Tag types (such as Type 1 to 4), and NFC technologies (such as - NFC-A, NFC-B, etc). -

      -

      - When writing to tags or pushing messages to peers, the - document base URL serves as the default scope, though another - URL scope can be set with the restriction that it MUST include the - document domain (e.g. http://www.w3.org). -

      -

      - To describe which messages an application is interested in, the following - dictionary is used: -

      - -

      The WatchOptions dictionary

      -
      -
      tag-only
      -
      Only NFC tags are watched.
      - -
      peer-only
      -
      Only NFC peers are watched.
      - -
      all
      -
      Both NFC tags and NFC peers are watched.
      -
      - -
      -
      DOMString? scope
      -
      DOMString[] acceptedContentTypes
      -
      WatchType watchType
      -
      -

      - The scope property - denotes the URL scope for which all messages MUST belong to. - If the value is null or undefined, - then implementations SHOULD use the web app's - document base URL. -

      -

      - The - - acceptedContentTypes property denotes the list of MIME types, that - the registrations wants to handle. -

      -

      - The watchType property - tells whether to watch: -

        -
      • - NFC tags only, denoted by the value - 'tag-only'. -
      • -
      • - NFC peers only, denoted by the value - 'peer-only'. -
      • -
      • - Both NFC tags and NFC peer, denoted by the value - 'all'. -
      • -

        -
        -      var watchOptions = {
        -        scope: "http://www.w3.org",
        -        acceptedContentTypes: ["application/manifest+json", "application/json", "text/json"]
        -      }
        -      
        -
        -      var watchOptions = {
        -        scope: "https://01.org/registration",
        -        acceptedContentTypes: ["application/json"],
        -        watchType: 'tag-only'
        -      }
        -      
        -
      - - -

      The within-scope algorithm

      -

      - Inputs: -

        -
      1. url, a URL to be checked for being within scope;
      2. -
      3. registeredScope, the URL scope to - check url against. -
      4. -
      -

      -

      Output: true or false

      -

      - When filtering NDEF messages with identifiers associated with - url, based on URL scope, run the following steps - atomically. -

        -
      1. - If registeredScope is undefined, then let - scope be the calling web app's - document base URL. -
      2. -
      3. - Otherwise let scope be registeredScope. -
      4. -
      5. - If url is a sub-domain of scope, - and scope ends with "/*", then - return true. -
      6. -
      7. - If url is an exact match of scope, - return true. -
      8. -
      9. - Otherwise return false. -
      10. -
      -

      -
      - -

      - When the - - watch() method is invoked, the user agent MUST run - the following steps: -

        -
      1. Let promise be a new Promise object. -
      2. -
      3. - Return promise and continue the following steps - asynchronously. -
      4. -
      5. - If there are no sufficient permissions to use this method, - then reject promise with a new - DOMException object whose name property - is set to "SecurityError", - and terminate these steps. -
      6. -
      7. - Parse the argument options. If it is invalid in the given - platform, then reject promise with a new - DOMException object whose name property - is set to "SyntaxError", and terminate these steps. -
      8. -
      9. - Make a request to the underlying platform to listen to - NDEF messages, and set up within-scope filtering for - options.scope, and also set up filtering for accepted - content types, as described by the - options.acceptedContentTypes parameter. -
      10. -
      11. - As a consequence, fire read events only for - messages, whose URL scope is within-scope for any of the - elements of the list of URL scopes registered during successive - calls of the watch() method, - and for which the content type matches the list of accepted content - types. -
      12. -
      13. - If the request fails, then reject promise with a new - DOMException object whose name property - is set to "NotSupportedError" , and terminate these steps. -
      14. -
      15. - If the request is successful, then resolve promise with an - identifier for the listener, which later can be used with the - clearWatch() method to remove the listener. -
      16. + + send() method is used for sending an NDEF message to + either an NFC tag for writing, or to an NFC peer device, + next time when they get into proximity range. + When this method is invoked, the user agent MUST run the following + steps: +
        1. - Whenever the user agent detects an NFC tag or - NFC peer data that matches the filtering options set by the - watcher, queue a task to fire an "read" event at - the adapter object. -
        2. -
        -

        -
      - - -

      The clearWatch() method

      -

      - When the - clearWatch() method is invoked, the user agent - MUST run the following steps: -

        -
      1. Let promise be a new Promise object. + Let promise be a new Promise object.
      2. Return promise and continue the following steps asynchronously.
      3. - If there are no sufficient permissions to use this method, - then reject promise with a new - DOMException object whose name property - is set to "SecurityError", - and terminate these steps. -
      4. -
      5. - If the parameter id is undefined, then make - a request to the underlying platform to remove all listeners and - filters set by successive calls of the watch() - method. -
      6. -
      7. - Otherwise, make a request to the underlying platform to remove the - listener corresponding to the value of id. + If sufficient permission has not been granted to use this + method, then reject promise with + "SecurityError", and terminate these steps.
      8. - If the request fails, then reject promise with a new - DOMException object whose name property - is set to "NotSupportedError", and terminate these steps. -
      9. -
      10. - If the request is successful, then resolve promise. -
      11. -
      -

      -
      - - - -

      The write() method

      -

      - The - write() method is used for writing an NFC tag, if - possible. When this method is invoked, the user agent MUST run the - following steps: -

        -
      1. - Let promise be a new Promise object. -
      2. -
      3. - Return promise and continue the following steps - asynchronously. -
      4. -
      5. - If there are no sufficient permissions to use this method, then reject - promise with a new DOMException object - whose name property is set to - "SecurityError", and terminate these steps. + If there is no support for the functionality of sending data to an + NFC peer in proximity range, or to write data to an + NFC tag, then reject promise with + "NotSupportedError", and terminate these steps.
      6. - If there is no support for the functionality of writing an - NFC tag in proximity range, then reject promise with - a new DOMException object whose name - property is set to "NotSupportedError", and - terminate these steps. + Parse the argument options. If it is undefined + or null, then use the default values. + Otherwise if invalid, then reject promise with + "SyntaxError", and terminate these steps.
      7. - Parse the argument scope. If it is invalid in the given - platform, then reject promise with a new - DOMException - object whose name property is set - to "SyntaxError", and terminate these steps. - If the value is undefined, then attribute to - scope the DOMString describing the - document base URL. + Parse the argument message.scope. + If the value is undefined, then set scope to + the DOMString describing the document base URL. + If it is invalid in the given platform, or if it is not a + sub-domain match of the document base URL, then reject + promise with "SyntaxError", and terminate + these steps.
      8. - For each element the array argument data, check the type - to be one of the types defined in NdefData. + For each element in the array message.data, + check the type + to be one of the supported types. If the value is invalid on the given platform, then reject - promise with a new DOMException - object whose name property is set to - "SyntaxError", and terminate these steps. + promise with "SyntaxError", and + terminate these steps. For each valid element create an NDEF record. The implementation choose the best suitable NDEF record format for the given platform. - Each element in the input array given in data SHOULD - map to a separate NDEF record in the NDEF message to be - sent. - Assemble an NDEF message from the NDEF records and - referred to as output. + Each element in the input array given in message.data + SHOULD map to a separate NDEF record in the NDEF message + to be sent.
      9. - Make a request to the underlying platform to write output - with the URL scope provided by scope - to the NFC tag in proximity range. If the request fails, then - reject promise with a new DOMException - object whose name property is set to - "NotSupportedError", and terminate these steps. -
      10. -
      11. - If the request is successful, then resolve promise. -
      12. -
      -

      -
      - -

      The setPushMessage() method

      -

      - The - - setPushMessage() method is used for setting the messages - which the user can push to another peer when it gets into proximity range. - When this method is invoked, the user agent MUST run the following - steps: -

        -
      1. - Let promise be a new Promise object. + Assemble an NDEF message from the NDEF records and an + additional Web NFC record, referred to as output.
      2. - Return promise and continue the following steps - asynchronously. + Make a request to the underlying platform to send output + to the next device which comes in proximity range.
      3. - If there are no sufficient permissions to use this method, then reject - promise with a new DOMException object - whose name property is set to - "SecurityError", and terminate these steps. + If options.target has the value "tag", then + the sending should only happen if an NFC tag is tapped within + a platform specific timeout, otherwise reject promise with + a "TimeoutError" in the case of timeout, or + "InvalidAccessError" if an NFC peer is + tapped instead of a tag.
      4. - If there is no support for the functionality of sending data to an - NFC peer in proximity range, then reject promise - with a new DOMException object whose - name property is set to - "NotSupportedError", and terminate these steps. + If options.target has the value "peer", then + the sending should only happen if an NFC peer is tapped within + a platform specific timeout, otherwise reject promise with + a "TimeoutError" in the case of timeout, or + "InvalidAccessError" if an NFC tag is + tapped instead of a peer.
      5. - Parse the argument scope. If it is invalid in the given - platform, then reject promise with a new - DOMException - object whose name property is set - to "SyntaxError", and terminate these steps. - If the value is undefined, then attribute to - scope the DOMString describing the - document base URL. -
      6. -
      7. - For each element the array argument data, check the type - to be one of the types defined in NdefData. - If the value is invalid on the given platform, then reject - promise with a new DOMException - object whose name property is set to - "SyntaxError", and terminate these steps. - For each valid element create an NDEF record. - The implementation choose the best suitable NDEF record format - for the given platform. - Each element in the input array given in data SHOULD - map to a separate NDEF record in the NDEF message to be - sent. - Assemble an NDEF message from the NDEF records and - referred to as output. -
      8. -
      9. - Make a request to the underlying platform to send output - to the NFC peers in proximity range. If the request fails, then - reject promise with a new DOMException - object whose name property is set to - "NotSupportedError", and terminate these steps. + If options.target has the value "any" (which + is the default value), then the sending should happen if either an + NFC peer or an NFC tag is tapped within a platform + specific timeout, otherwise reject promise with + "TimeoutError".
      10. If the request is successful, then resolve promise.

      -
      - -

      The clearPushMessage() method

      +

      The NfcSendOptions dictionary

      +
      +
      tag
      +
      Only NFC tags are targeted.
      + +
      peer
      +
      Only NFC peers are targeted.
      + +
      any
      +
      Both NFC tags and NFC peers are targeted.
      +
      + +
      +
      NfcTarget target
      +
      +

      + The target property + denotes the intended target for the pending send() + operation. The default value is "any". +

      +
      +
      +
      + + + +

      Examples

      - When the - - clearPushMessage() method is invoked, the - user agent MUST run the following steps: -

        -
      1. Let promise be a new Promise object. -
      2. -
      3. - Return promise and continue the following steps - asynchronously. -
      4. -
      5. - If there are no sufficient permissions to use this method, - then reject promise with a new - DOMException object whose name property - is set to "SecurityError", - and terminate these steps. -
      6. -
      7. - If the parameter scope is undefined, then make - a request to the underlying platform to remove and cancel pushing any - previously set messages to NFC peer devices in range or coming - into range. -
      8. -
      9. - Otherwise, make a request to the underlying platform to remove and - cancel pushing messages to NFC peer devices in range or coming - into range, whose URL scope is within-scope for - scope. -
      10. -
      11. - If the request fails, then reject promise with a new - DOMException object whose name property - is set to "NotSupportedError", and terminate these steps. -
      12. -
      13. - If the request is successful, then resolve promise. -
      14. -
      + This section shows how developers can make use of the various features of + this specification.

      -
      -
      +
      +    navigator.permissions.query({name: 'nfc'}).then((result) => {
      +        if (result.status == 'granted') {
      +          enableNfcUseCase();  // Do things here.
      +        } else if (result.status == 'prompt') {
      +          // The user agent will prompt.
      +        }
      +        // Otherwise don't do anything since it will fail.
      +      });
      +  
      +
      +    var adapter = null;
      +    navigator.nfc.requestAdapter().then((nfcAdapter) => {
      +      adapter = nfcAdapter;
      +      adapter.onmessage = onMessage;
      +    };
      +
      +    function onMessage(event) {
      +      console.log("NDEF message received from scope " + event.message.scope);
      +      var data = event.message.data;
      +
      +      if (!data) { // empty tag
      +        writeMessageOnTag({data: “Initializing a passive tag”});
      +      }
      +
      +      if (typeof data == ‘string’) {
      +        console.log(“Data is string: “ + data);
      +      } else if (data instanceof Blob) {
      +        processBlob(data);
      +      } else if (data instanceof URL) {
      +        console.log(“Data is URL: “ + data.toString());
      +      } else if (typeof data == ‘object’) {
      +        processJson(data);
      +      }
      +    };
      +
      +    function writeMessageOnTag(msg) {
      +        adapter.send(msg, {target: "tag"})
      +          .then(() => { console.log("Send was successful")})
      +          .catch(() => { console.log("Send failed")});
      +    };
      +
      +    function processBlob(data) {
      +        console.log(“Blob size: ” + data.size + “ bytes”);
      +        console.log(“Blob type: ” + data.type);
      +        var reader = new FileReader();
      +        reader.addEventListener(“loadend”, function() {
      +          console.log(“Blob data: ” + reader.result);
      +          // Now send a response based on the data.
      +          adapter.send({data: “Response to blob” })
      +            .then(() => { console.log("Send was successful")})
      +            .catch(() => { console.log("Send failed")});
      +        });
      +        reader.readAsText(data);
      +    };
      +
      +    function processJson(data) {
      +      if (myCondition(data.myKnownProperty)) {
      +        adapter.send({data: “Custom data”});
      +    };
      +  
      +
      +    navigator.nfc.requestAdapter().then((adapter) => {
      +      console.log("Waiting for game state");
      +      adapter.onmessage = (event) => {
      +        console.log("Game state received from: " + event.message.scope);
      +        console.log("Game state: " + event.message.data);
      +        // Now do some calculations and update the state.
      +        adapter.send({ scope: event.message.scope,
      +                       data: [ { level: 3, points: 4500, lives: 3 } ] })
      +          .then(() => { console.log("Send was successful")})
      +          .catch(() => { console.log("Send failed")});
      +      };
      +    });
      +  
      +

    Changes

    @@ -1429,19 +1151,50 @@ recently closed bugs.

      -
    • Redesigned the API to follow contemporary web design patterns
    • -
    • Change of editors
    • +
    • Changed handling of NFC adapters.
    • +
    • + Removed watches/filters. +
    • +
    • + Unified handling of peer push and tag writing. +
    • +
    • + Rewritten mapping data types to NDEF records. +
    • +
    • + Added Open Issues section, for summarizing present development topics. +
    + +

    Open issues

    +

    + The following problems are being discussed and need most attention: +

    +

    +

    Acknowledgements

    The editors would like to express their gratitude to the former editors - Luc Yriarte and Samuel Ortiz, and also to Don Coleman, Salvatore Iovene and - Jeffrey Yasskin for their technical guidance, implementation feedback and - support. + Luc Yriarte and Samuel Ortiz, and also to Don Coleman, Jeffrey Yasskin, + Salvatore Iovene, and Alexander Shalamov for their technical guidance, + implementation feedback and support.

    diff --git a/security-privacy.html b/security-privacy.html index 70c19ed..36c5227 100644 --- a/security-privacy.html +++ b/security-privacy.html @@ -154,7 +154,8 @@ and the data read may constitute an attack vector on the user agent This is a generic problem with all existing NFC tags; - implementations need security hardening; involuntary touch is low probability due to short range and critical angle for reading; + implementations need security hardening; involuntary touch is low + probability due to short range and critical angle for reading; it’s easier to attack elsewhere (e.g. WiFi and Bluetooth) @@ -196,12 +197,13 @@
    • an identification mechanism for telling apart “Web NFC tags” from generic NFC tags
    • -
    • a mechanism for whitelisting URL's that can read, or write a certain - Web NFC tag
    • +
    • a mechanism for conveying implementation specific contextual data + which is not exposed to applications.

    +

    The encoded JSON format for Web NFC data and metadata is useful for abstracting away NFC Forum types, and for supporting implementations where @@ -367,6 +364,7 @@

    +-->

    Acknowledgments

    diff --git a/use-cases.html b/use-cases.html index 7b43d3d..16cca8e 100644 --- a/use-cases.html +++ b/use-cases.html @@ -140,6 +140,7 @@ and other data.

    +

    Acknowledgments