Category Archives: Specifications

ECMAScript ES6 (ES2015) changes overview

I’ve been playing recently with ReactJS a bit, and was pleasantly surprised when seeing great changes, the JavaScript language has undergone, over the last c.a. 2 years.

This made me realize, that i need to study those changes in more detail, which is how this blog entry came to existence ūüôā

According to Wikipedia, “ECMAScript (or ES) is a scripting-language specification, standardized by the European Computer Manufacturers Association. (‚Ķ) JavaScript is the best-known implementation of ECMAScript since the standard was first published, with other well-known implementations including JScript and ActionScript” (anyone remembering the Flash platform authored by Macromedia?).

In June 2015, sixth edition of ECMAScript (ES6) was introduced, which later changed its name to ECMAScript 2015 (ES2015).

Among the design objectives, that the TC39 (Ecma Technical Committee 39) team defined for the new version of the language, were:

  • Goal 1: Be a better language (for writing: complex applications, libraries (possibly including the DOM) shared by those applications, code generators)
  • Goal 2: Improve interoperation (i.e. adopt de facto standards where possible)
  • Goal 3: Versioning (keep versioning as simple and linear as possible)

Some of the new constructs, that caught my attention:

 

1. let/const vs. var

In ES5, you declare variables via var. Such variables are function-scoped, their scopes are the innermost enclosing functions

In ES6, you can additionally declare variables via let and const. Such variables are block-scoped, their scopes are the innermost enclosing blocks.

let is roughly a block-scoped version of var.

const works like let, but creates variables whose values can’t be changed.

var num = 0;

if (num === 0) {
  let localSpeed = 100;
  var globalSpeed = 200;

  for (let i = 0; i < 0; i++){
    num += (localSpeed + globalSpeed) * 1;
  }

  console.log(typeof i);  // undefined
}

console.log(typeof localSpeed);  // undefined
console.log(typeof num);  // number
console.log(typeof globalSpeed);  // number

General advice by Dr. Axel Rauschmayer (author of Exploring ES6):

  • Prefer const. You can use it for all variables whose values never change.
  • Otherwise, use let ‚Äď for variables whose values do change.
  • Avoid var.

 

2. IIFEs vs. blocks

In ES5, you had to use a pattern called IIFE (Immediately-Invoked Function Expression) if you wanted to restrict the scope of a variable tmp to a block:

(function () {  // open IIFE
  var tmp = ···;
  ···
}());  // close IIFE

console.log(tmp);  // ReferenceError

In ECMAScript 6, you can simply use a block and a let declaration (or a const declaration):

{  // open block
  let tmp = ···;
  ···
}  // close block

console.log(tmp);  // ReferenceError

 

3. concatenating strings vs. template literals

In ES5, you put values into strings by concatenating those values and string fragments:

function printCoord(x, y) {
  console.log('('+x+', '+y+')');
}

In ES6 you can use string interpolation via template literals:

function printCoord(x, y) {
  console.log(`(${x}, ${y})`);
}

Template literals also help with representing multi-line strings.

 

4. function expressions vs. arrow functions

In ES5, such callbacks are relatively verbose:

var arr = [1, 2, 3];
var squares = arr.map(function (x) { return x * x });

In ES6, arrow functions are much more concise:

const arr = [1, 2, 3];
const squares = arr.map(x => x * x);

 

5. for vs. forEach() vs. for-of

Prior to ES5, you iterated over Arrays as follows:

var arr = ['a', 'b', 'c'];
for (var i=0; i<arr.length; i++) {
  var elem = arr[i];
  console.log(elem);
}

In ES5, you have the option of using the Array method forEach():

arr.forEach(function (elem) {
  console.log(elem);
});

A for loop has the advantage that you can break from it, forEach() has the advantage of conciseness.

In ES6, the for-of loop combines both advantages:

const arr = ['a', 'b', 'c'];
for (const elem of arr) {
  console.log(elem);
}

If you want both index and value of each array element, for-of has got you covered, too, via the new Array method entries() and destructuring:

for (const [index, elem] of arr.entries()) {
  console.log(index+'. '+elem);
}

 

6. Handling multiple return values

A. via arrays

In ES5, you need an intermediate variable (matchObj in the example below), even if you are only interested in the groups:

var matchObj = /^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec('2999-12-31');
var year = matchObj[1];
var month = matchObj[2];
var day = matchObj[3];

In ES6, destructuring makes this code simpler:

const [, year, month, day] = /^(\d\d\d\d)-(\d\d)-(\d\d)$/.exec('2999-12-31');

(The empty slot at the beginning of the Array pattern skips the Array element at index zero.)

B. via objects

In ES5, even if you are only interested in the properties of an object, you still need an intermediate variable (propDesc in the example below):

var obj = { foo: 123 };
var propDesc = Object.getOwnPropertyDescriptor(obj, 'foo');
var writable = propDesc.writable;
var configurable = propDesc.configurable;

console.log(writable, configurable);  // true true

In ES6, you can use destructuring:

const obj = { foo: 123 };
const {writable, configurable} = Object.getOwnPropertyDescriptor(obj, 'foo');
console.log(writable, configurable);  // true true

 

7. Handling parameter default values

In ES5, you specify default values for parameters like this:

function foo(x, y) {
  x = x || 0;
  y = y || 0;
  ···
}

ES6 has nicer syntax:

function foo(x=0, y=0) {
  ···
}

 

8. Handling named parameters

A common way of naming parameters in JavaScript is via object literals (the so-called options object pattern):

selectEntries({ start: 0, end: -1 });

Two advantages of this approach are: Code becomes more self-descriptive and it is easier to omit arbitrary parameters.

In ES5, you can implement selectEntries() as follows:

function selectEntries(options) {
  var start = options.start || 0;
  var end = options.end || -1;
  var step = options.step || 1;
  ···
}

In ES6, you can use destructuring in parameter definitions and the code becomes simpler:

function selectEntries({ start=0, end=-1, step=1 }) {
  ···
}

 

9. arguments vs. rest parameters

In ES5, if you want a function (or method) to accept an arbitrary number of arguments, you must use the special variable arguments:

function logAllArguments() {
  for (var i=0; i<arguments.length; i++) {
    console.log(arguments[i]);
  }
}

In ES6, you can declare a rest parameter (args in the example below) via the …operator:

function logAllArguments(...args) {
  for (const arg of args) {
    console.log(arg);
  }
}

Rest parameters are even nicer if you are only interested in trailing parameters:

function format(pattern, ...args) {
  ···
}

Handling this case in ES5 is clumsy:

function format(pattern) {
  var args = [].slice.call(arguments, 1);
  ···
}

 

10.¬†apply() vs. the spread operator (…)

In ES5, you turn arrays into parameters via apply().

ES6 has the spread operator for this purpose.

A. Math.max() example

ES5 ‚Äď apply():

Math.max.apply(Math, [-1, 5, 11, 3])

ES6 ‚Äď spread operator:

Math.max(...[-1, 5, 11, 3])

B. Array.prototype.push() example

ES5 ‚Äď apply():

var arr1 = ['a', 'b'];
var arr2 = ['c', 'd'];

arr1.push.apply(arr1, arr2); // arr1 is now ['a', 'b', 'c', 'd']

ES6 ‚Äď spread operator:

const arr1 = ['a', 'b'];
const arr2 = ['c', 'd'];

arr1.push(...arr2); // arr1 is now ['a', 'b', 'c', 'd']

 

11.¬†concat() vs. the spread operator (…)

The spread operator can also (non-destructively) turn the contents of its operand into Array elements. That means that it becomes an alternative to the Array method concat().

ES5 ‚Äď concat():

var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];

console.log(arr1.concat(arr2, arr3)); // [ 'a', 'b', 'c', 'd', 'e' ]

ES6 ‚Äď spread operator:

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

console.log([...arr1, ...arr2, ...arr3]); // [ 'a', 'b', 'c', 'd', 'e' ]

 

12. function expressions in object literals vs. method definitions

In JavaScript, methods are properties whose values are functions.

In ES5 object literals, methods are created like other properties. The property values are provided via function expressions.

var obj = {
  foo: function () {
    ···
  },
  bar: function () {
    this.foo();
  }, // trailing comma is legal in ES5
}

ES6 has method definitions, special syntax for creating methods:

const obj = {
  foo() {
    ···
  },
  bar() {
    this.foo();
  },
}

 

13. constructors vs. classes

ES6 classes are mostly just more convenient syntax for constructor functions.

A. Base classes

In ES5, you implement constructor functions directly:

function Person(name) {
  this.name = name;
}
Person.prototype.describe = function () {
  return 'Person called '+this.name;
};

Note the compact syntax for method definitions ‚Äď no keyword function needed.

Also note that there are no commas between the parts of a class

B. Derived classes

Subclassing is complicated in ES5, especially referring to super-constructors and super-properties.

This is the canonical way of creating a sub-constructor Employee of Person:

function Employee(name, title) {
  Person.call(this, name); // super(name)
  this.title = title;
}

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.describe = function () {
  return Person.prototype.describe.call(this) // super.describe()
    + ' (' + this.title + ')';
};

ES6 has built-in support for subclassing, via the extends clause:

class Employee extends Person {
  constructor(name, title) {
    super(name);
    this.title = title;
  }
  describe() {
    return super.describe() + ' (' + this.title + ')';
  }
}

 

14. custom error constructors vs. subclasses of Error

In ES5, it is impossible to subclass the built-in constructor for exceptions, Error.

The following code shows a work-around that gives the constructor MyError important features such as a stack trace:

function MyError() {
  var superInstance = Error.apply(null, arguments); // Use Error as a function
  copyOwnPropertiesFrom(this, superInstance);
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;

function copyOwnPropertiesFrom(target, source) {
  Object.getOwnPropertyNames(source).forEach(function(propKey) {
    var desc = Object.getOwnPropertyDescriptor(source, propKey);
    Object.defineProperty(target, propKey, desc);
  });
return target;
};

In ES6, all built-in constructors can be subclassed, which is why the following code achieves what the ES5 code can only simulate:

class MyError extends Error {
}

 

15. objects vs. Maps

Using the language construct object as a map from strings to arbitrary values (a data structure) has always been a makeshift solution in JavaScript. The safest way to do so is by creating an object whose prototype is null. Then you still have to ensure that no key is ever the string ‘__proto__’, because that property key triggers special functionality in many JavaScript engines.

The following ES5 code contains the function countWords that uses the object dictas a map:

var dict = Object.create(null);

function countWords(word) {
  var escapedWord = escapeKey(word);
  if (escapedWord in dict) {
    dict[escapedWord]++;
  } else {
    dict[escapedWord] = 1;
  }
}

function escapeKey(key) {
if (key.indexOf('__proto__') === 0) {
    return key+'%';
  } else {
    return key;
  }
}

In ES6, you can use the built-in data structure Map and don’t have to escape keys. As a downside, incrementing values inside Maps is less convenient.

const map = new Map();
function countWords(word) {
  const count = map.get(word) || 0;
  map.set(word, count + 1);
}

Another benefit of Maps is that you can use arbitrary values as keys, not just strings.

 

16. New string methods

A. indexOf vs. startsWith

if (str.indexOf('x') === 0) {} // ES5
if (str.startsWith('x')) {} // ES6

B. indexOf vs. endsWith

function endsWith(str, suffix) { // ES5
  var index = str.indexOf(suffix);
  return index >= 0 && index === str.length-suffix.length;
}
str.endsWith(suffix); // ES6

C. indexOf vs. includes

if (str.indexOf('x') >= 0) {} // ES5
if (str.includes('x')) {} // ES6

D. join vs. repeat (the ES5 way of repeating a string is more of a hack):

new Array(3+1).join('#') // ES5
'#'.repeat(3) // ES6

 

17. New Array methods

A. Array.prototype.indexOf vs. Array.prototype.findIndex

The latter can be used to find NaN, which the former can’t detect:

const arr = ['a', NaN];
arr.indexOf(NaN); // -1
arr.findIndex(x => Number.isNaN(x)); // 1

As an aside, the new Number.isNaN() provides a safe way to detect NaN (because it doesn’t coerce non-numbers to numbers):

isNaN('abc') // true
Number.isNaN('abc') // false

B. Array.prototype.slice() vs. Array.from() (or the spread operator)

In ES5, Array.prototype.slice() was used to convert Array-like objects to Arrays. In ES6, you have Array.from():

var arr1 = Array.prototype.slice.call(arguments); // ES5
const arr2 = Array.from(arguments); // ES6

If a value is iterable (as all Array-like DOM data structure are by now), you can also use the spread operator (…) to convert it to an Array:

const arr1 = [...'abc']; // ['a', 'b', 'c']
const arr2 = [...new Set().add('a').add('b')]; // ['a', 'b']

C. apply() vs. Array.prototype.fill()

In ES5, you can use apply(), as a hack, to create in Array of arbitrary length that is filled with undefined:

// Same as Array(undefined, undefined)
var arr1 = Array.apply(null, new Array(2)); // [undefined, undefined]

In ES6, fill() is a simpler alternative:

const arr2 = new Array(2).fill(undefined); // [undefined, undefined]

fill() is even more convenient if you want to create an Array that is filled with an arbitrary value:

// ES5
var arr3 = Array.apply(null, new Array(2)).map(function (x) { return 'x' }); // ['x', 'x']

// ES6
const arr4 = new Array(2).fill(‚Äėx‚Äô); // ['x', 'x']

fill() replaces all Array elements with the given value. Holes are treated as if they were elements.

 

18. CommonJS modules vs. ES6 modules

Even in ES5, module systems based on either AMD syntax or CommonJS syntax have mostly replaced hand-written solutions such as the revealing module pattern.

ES6 has built-in support for modules. Alas, no JavaScript engine supports them natively, yet. But tools such as browserify, webpack or jspm let you use ES6 syntax to create modules, making the code you write future-proof.

A. Multiple exports in CommonJS

//------ lib.js ------
var sqrt = Math.sqrt;
function square(x) {
  return x * x;
}
function diag(x, y) {
  return sqrt(square(x) + square(y));
}
module.exports = {
  sqrt: sqrt,
  square: square,
  diag: diag,
};

//------ main1.js ------
var square = require('lib').square;
var diag = require('lib').diag;

console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

Alternatively, you can import the whole module as an object and access square and diag via it:

//------ main2.js ------
var lib = require('lib');

console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

B. Multiple exports in ES6

In ES6, multiple exports are called named exports and handled like this:

//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
  return x * x;
}
export function diag(x, y) {
  return sqrt(square(x) + square(y));
}

//------ main1.js ------
import { square, diag } from 'lib';

console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

The syntax for importing modules as objects looks as follows (line A):

//------ main2.js ------
import * as lib from 'lib'; // (A)

console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

C. Single exports in CommonJS

Node.js extends CommonJS and lets you export single values from modules, via module.exports:

//------ myFunc.js ------
module.exports = function () { ··· };

//------ main1.js ------
var myFunc = require('myFunc');
myFunc();

D. Single exports in ES6

In ES6, the same thing is done via a so-called default export (declared via export default):

//------ myFunc.js ------
export default function () { ··· } // no semicolon!

//------ main1.js ------
import myFunc from 'myFunc';
myFunc();

 

 

That would be it,

Cheers!

 

Resources:

Web Storage – client-side data storage

While investigating the best solution for client-side data storage i came across W3C Web Storage specification, which may be of interest to you as well.

 

The specification “…defines an API for persistent data storage of key-value pair data in Web clients“. It mentions two different types of storage:

  • Session storage – purpose of which is to¬†remember all data in the current session, but¬†forget it as soon as the browser¬†tab¬†or¬†window¬†gets closed
  • Local storage – which stores the data across multiple browser sessions (persistent storage)¬†and as a result makes it possible to close the page (or window) and still preserve the¬†data within the browser

 

Both mechanisms use the same Storage interface:

interface Storage {
  readonly attribute unsigned long length;
  DOMString? key(unsigned long index);
  getter DOMString getItem(DOMString key);
  setter creator void setItem(DOMString key, DOMString value);
  deleter void removeItem(DOMString key);
  void clear();
};

 

The storage facility is similar to traditional HTTP cookie storage but offers some benefits commonly understood as:

  • Storage capacity: Browsers have enabled a minimum of 5Mb of storage inside a web storage object (IE has allowed 10Mb but it varies by storage type and browser).
  • Data transmission: Objects are not sent automatically with each request but must be requested.
  • Client side access: Servers cannot directly write to web storage which provides some additional controls from client-side scripting.
  • Data storage: Array level name/value pairs provides a more flexible data model

 

Basic operations on both Web Storage mechanisms, look like this:

// session storage
  sessionStorage.setItem('key', 'value');         // set
  var item = sessionStorage.getItem('key');       // retrieve
  var item = sessionStorage.removeItem('key');    // remove
  sessionStorage.clear();                         // clear all
  var no_of_items = sessionStorage.length;        // no. of current items

// local storage
  localStorage.setItem('key', 'value');           // set
  var item = localStorage.getItem('key');         // retrieve
  var item = localStorage.removeItem('key');      // remove
  localStorage.clear();                           // clear all
  var no_of_items = localStorage.length;          // no. of current items

 

The specification also provides a StorageEvent interface to be fired whenever the storage area changes. It exposes following attributes:

  • storageArea¬†-that tells the¬†type¬†of storage used¬†(Session or Local)
  • key¬†–¬†key which is being changed.
  • oldValue¬†– the¬†old value of the key.
  • newValue – the new value of the key.
  • url¬†– the¬†URL of the page whose key is changed.

 

Privacy Implications:

  • As has been discussed in the W3C spec and other forums, there are some considerations for privacy in place both within the spec design and implemented in the variable user agent controls present today in common web browsers. Within the spec, there are options for user agents to:
  • Restrict access to local storage to ‚Äúthird party domains‚ÄĚ or those domains that do not match the top-level domain (e.g., that sit within i-frames). Sub-domains are considered separate domains unlike cookies.
  • Session and time-based expirations can be set to make data finite vs. permanent.
  • Whitelist and blacklisting features can be used for access controls.

 

Key facts:

  • Storage per origin: All storage from the same origin will share the same storage space. An origin is a tuple of scheme/host/port (or a globally unique identifier). For example, http://www.example.org and http://abc.example.org are two separate origins, as are http://example.org and https://example.org as well as http://example.org:80 and http://example.org:8000
  • Storage limit: As of now, most browsers that have implemented Web Storage, have placed the storage limit at 5 Mb per domain. You should be able to¬†change this storage limit on a per-domain basis in the browser settings:
    • Chrome:¬†Advanced>Privacy> Content>Cookies
    • Safari:¬†Privacy>Cookies and Other Website Data; ‚ÄúDetails‚ÄĚ
    • Firefox:¬†Tools> Clear Recent History > Cookies
    • IE:¬†Internet Options> General> Browsing History>Delete> Cookies and Website Data
  • Security considerations: Storage is assigned on a per-origin basis. Someone might use DNS Spoofing to make themselves look like a particular domain when in fact they aren‚Äôt, thereby gaining access to the storage area of that domain on a user‚Äôs computer. SSL can be used in order to prevent this from happening, so users can be absolutely sure that the site they are viewing is from the same domain name.
  • Where not to use it: If two different users are using different pathnames on a single domain, they can access the storage area of the whole origin and therefore each other‚Äôs data. Hence, it is advisable for people on free hosts who have their sites on different directories of the same domain (for example, freehostingspace.org/user1/ and freehostingspace.org/user2/), to not use Web Storage on their pages for the time being.
  • Web Storage is not part of the HTML5 spec: It is a whole specification in itself.

 

Cookies:

Cookies and Web¬†Storage really serve different purposes. Cookies are primarily for reading server-side, whereas Web Storage can only be read client-side. So the question is, in your app, who needs the¬†data ‚ÄĒ the client or the server?

  • If it’s your client (your JavaScript), then by all means use Web Storage. You’re wasting bandwidth by sending all the data in the HTTP header each time.
  • If it’s your server, Web Storage isn’t so useful because you’d have to forward the data along somehow (with Ajax or hidden form fields or something). This might be okay if the server only needs a small subset of the total data for each request.

 

Web Storage vs. Cookies:

  • Web Storage:
    • Pros
      • Support by most modern browsers
      • Stored directly in the browser
      • Same-origin rules apply to local storage data
      • Is not sent with every HTTP request
      • ~5MB storage per domain (that’s 5120KB)
    • Cons
      • Not supported by anything before:
        • IE 8
        • Firefox 3.5
        • Safari 4
        • Chrome 4
        • Opera 10.5
        • iOS 2.0
        • Android 2.0
      • If the server needs stored client information you purposefully have to send it.
  • Cookies:
    • Pros
      • Legacy support (it’s been around forever)
      • Persistent data
      • Expiration dates
    • Cons
      • Each domain stores all its cookies in a single string, which can make parsing data difficult
      • Data is not¬†encrypted
      • Cookies are sent with every HTTP request Limited size (4KB)
      • SQL injection can be performed from a cookie

 

If you’re interested in Cookies,¬†you can read more here.

 

Finally, if you’re looking for a client-side data storage solution for AngularJS, you may want to take a look at angular-cache.

 

 

 

Take care!

 

 

 

Resources:

JSON Activity Streams 1.0

In this post i’d like to address the subject of Activity Streams spec., something I’ve been working with recently in one of the projects.

 

Let’s start with a definition of an activity stream (Wikipedia):

  • An activity stream is a list of recent activities performed by an individual, typically on a single website. For example, Facebook’s News Feed is an activity stream.¬†Since the introduction of the News Feed on September 6, 2006, other major websites have introduced similar implementations for their own users. Since the proliferation of activity streams on websites, there have been calls to standardize the format so that websites could interact with a stream provided by another website. The Activity Streams project, for example, is an effort to develop an activity stream protocol to syndicate activities across social Web applications. Several major websites with activity stream implementations have already opened up their activity streams to developers to use, including Facebook and MySpace.¬†Though activity stream arises from social networking, nowadays it has become an essential part of business software. Enterprise social software is used in different types of companies to organize their internal communication and acts as an important addition to traditional corporate intranet.”

 

Activity Streams is an open format specification for activity stream protocols, which are used to syndicate activities taken in social web applications and services.

 

JSON Activity Streams 1.0 is the name of the specification published on May 2011 by the working group consisting of: J. Snell (IBM), M. Atkins (SAY Media), W. Norris (Google), C. Messina (Citizen Agency, Google), M. Wilkinson (MySpace, Facebook, VMware), R. Dolin (Microsoft).

 

On the homepage of the specification activitystrea.ms you’ll find more details including a list of early adopters¬†(BBC,¬†Gnip,¬†Google,¬†Buzz,¬†Gowalla,¬†IBM,¬†MySpace,¬†Opera,¬†Socialcast,¬†Superfeedr,
TypePad, Windows Live, YIID, and many others).

 

Introduction:

  • In its simplest form, an¬†activity¬†consists of an¬†actor, a¬†verb, an an¬†object, and a¬†target.
  • It tells the story of a person performing an action on or with an object — “Geraldine posted a photo to her album” or “John shared a video”. In most cases these components will be explicit, but they may also be implied.
  • Goal of the specification is to provide sufficient metadata about an activity such that a consumer of the data can present it to a user in a rich human-friendly format. (this may include constructing readable sentences about the activity that occurred, visual representations of the activity, or combining similar activities for display).
  • The basic properties that comprise the description of an¬†activity¬†are defined in the appropriate sections of the specification.
  • Within the specification, an¬†object¬†is a thing, real or imaginary, which participates in an activity. It may be the entity performing the activity, or the entity on which the activity was performed.
  • An¬†object¬†consists of properties defined in appropriate sections of the specification. Certain object types may further refine the meaning of these properties, or they may define additional properties.
  • Some types of objects may have an alternative visual representation in the form of an image, video or embedded HTML fragments. A¬†Media Link¬†represents a hyperlink to such resources.
  • An¬†Activity Stream¬†is a collection one or more individual activities. The relationship between the activities within the collection is undefined by this specification.

 

Following is a simple, minimal example of a JSON serialized activity:

{
    "published": "2011-02-10T15:04:55Z",
    "actor": {
        "url": "http://example.org/martin",
        "objectType" : "person",
        "id": "tag:example.org,2011:martin",
        "image": {
            "url": "http://example.org/martin/image",
            "width": 250,
            "height": 250
        },
        "displayName": "Martin Smith"
    },
    "verb": "post",
    "object" : {
        "url": "http://example.org/blog/2011/02/entry",
        "id": "tag:example.org,2011:abc123/xyz"
    },
    "target" : {
        "url": "http://example.org/blog/",
        "objectType": "blog",
        "id": "tag:example.org,2011:abc123",
        "displayName": "Martin's Blog"
    }
}

 

To give you an idea on the “breadth” of the spec., and how many various activities¬†got its individual verb, take a look at the following complete list of “verbs”:

  • accept – Indicates that that the actor has accepted the object. For instance, a person accepting an award, or accepting an assignment.
  • access – Indicates that the actor has accessed the object. For instance, a person accessing a room, or accessing a file.
  • acknowledge – Indicates that the actor has acknowledged the object. This effectively signals that the actor is aware of the object’s existence.
  • add – Indicates that the actor has added the object to the target. For instance, adding a photo to an album.
  • agree – Indicates that the actor agrees with the object. For example, a person agreeing with an argument, or expressing agreement with a particular issue.
  • append – Indicates that the actor has appended the object to the target. For instance, a person appending a new record to a database.
  • approve – Indicates that the actor has approved the object. For instance, a manager might approve a travel request.
  • archive – Indicates that the actor has archived the object.
  • assign – Indicates that the actor has assigned the object to the target.
  • at – Indicates that the actor is currently located at the object. For instance, a person being at a specific physical location.
  • attach – Indicates that the actor has attached the object to the target.For instance, a person attaching a file to a wiki page or an email.
  • attend – Indicates that the actor has attended the object. For instance, a person attending a meeting.
  • author – Indicates that the actor has authored the object. Note that this is a more specific form of the verb “create”.
  • authorize – Indicates that the actor has authorized the object. If a target is specified, it means that the authorization is specifically in regards to the target. For instance, a service can authorize a person to access a given application; in which case the actor is the service, the object is the person, and the target is the application. In contrast, a person can authorize a request; in which case the actor is the person and the object is the request and there might be no explicit target.
  • borrow – Indicates that the actor has borrowed the object. If a target is specified, it identifies the entity from which the object was borrowed. For instance, if a person borrows a book from a library, the person is the actor, the book is the object and the library is the target.
  • build – Indicates that the actor has built the object. For example, if a person builds a model or compiles code.
  • cancel – Indicates that the actor has canceled the object. For instance, canceling a calendar event.
  • close – Indicates that the actor has closed the object. For instance, the object could represent a ticket being tracked in an issue management system.
  • complete – Indicates that the actor has completed the object.
  • confirm – Indicates that the actor has confirmed or agrees with the object. For instance, a software developer might confirm an issue reported against a product.
  • consume – Indicates that the actor has consumed the object. The specific meaning is dependent largely on the object’s type. For instance, an actor may “consume” an audio object, indicating that the actor has listened to it; or an actor may “consume” a book, indicating that the book has been read. As such, the “consume” verb is a more generic form of other more specific verbs such as “read” and “play”.
  • checkin – Indicates that the actor has checked-in to the object. For instance, a person checking-in to a Place.
  • create – Indicates that the actor has created the object.
  • delete – Indicates that the actor has deleted the object. This implies, but does not require, the permanent destruction of the object.
  • deliver – Indicates that the actor has delivered the object. For example, delivering a package.
  • deny – Indicates that the actor has denied the object. For example, a manager may deny a travel request.
  • disagree – Indicates that the actor disagrees with the object.
  • dislike – Indicates that the actor dislikes the object. Note that the “dislike” verb is distinct from the “unlike” verb which assumes that the object had been previously “liked”.
  • experience – Indicates that the actor has experienced the object in some manner. Note that, depending on the specific object types used for both the actor and object, the meaning of this verb can overlap that of the “consume” and “play” verbs. For instance, a person might “experience” a movie; or “play” the movie; or “consume” the movie. The “experience” verb can be considered a more generic form of other more specific verbs as “consume”, “play”, “watch”, “listen”, and “read”
  • favorite – Indicates that the actor marked the object as an item of special interest.
  • find – Indicates that the actor has found the object.
  • flag-as-inappropriate – Indicates that the actor has flagged the object as being inappropriate for some reason. When using this verb, thecontext¬†property can be used to provide additional detail about why the object has been flagged.
  • follow – Indicates that the actor began following the activity of the object. In most cases, the objectType will be a “person”, but it can potentially be of any type that can sensibly generate activity. Processors MAY ignore (silently drop) successive identical “follow” activities.
  • give – Indicates that the actor is giving an object to the target. Examples include one person giving abadge¬†object to another person. Theobject¬†identifies the object being given. Thetarget¬†identifies the receiver.
  • host – Indicates that the actor is hosting the object. As in hosting an event, or hosting a service.
  • ignore – Indicates that the actor has ignored the object. For instance, this verb may be used when an actor has ignored a friend request, in which case the object may be the¬†request-friend¬†activity.
  • insert – Indicates that the actor has inserted the object into the target.
  • install – Indicates that the actor has installed the object, as in installing an application.
  • interact – Indicates that the actor has interacted with the object. For instance, when one person interacts with another.
  • invite – Indicates that the actor has invited the object, typically a person object, to join or participate in the object described by the¬†target. The target could, for instance, be an event, group or a service.
  • join – Indicates that the actor has become a member of the object. This specification only defines the meaning of this verb when theobject¬†of the Activity has an¬†objectTypeof¬†group, though implementors need to be prepared to handle other types of objects.
  • leave – Indicates that the actor has left the object. For instance, a Person leaving a Group or checking-out of a Place.
  • like – Indicates that the actor marked the object as an item of special interest. The “like” verb is considered to be an alias of “favorite”. The two verb are semantically identical.
  • listen – Indicates that the actor has listened to the object. This is typically only applicable for objects representing audio content, such as music, an audio-book, or a radio broadcast. The “listen” verb is a more specific form of the “consume”, “experience” and “play” verbs.
  • lose – Indicates that the actor has lost the object. For instance, if a person loses a game.
  • make-friend – Indicates the creation of a friendship that is reciprocated by the object. Since this verb implies an activity on the part of its object, processors MUST NOT accept activities with this verb unless they are able to verify through some external means that there is in fact a reciprocated connection. For example, a processor may have received a guarantee from a particular publisher that the publisher will only use this Verb in cases where a reciprocal relationship exists.
  • open – Indicates that the actor has opened the object. For instance, the object could represent a ticket being tracked in an issue management system.
  • play – Indicates that the actor spent some time enjoying the object. For example, if the object is a video this indicates that the subject watched all or part of the video. The “play” verb is a more specific form of the “consume” verb.
  • present – Indicates that the actor has presented the object. For instance, when a person gives a presentation at a conference.
  • purchase – Indicates that the actor has purchased the object. If a target is specified, in indicates the entity from which the object was purchased.
  • qualify – Indicates that the actor has qualified for the object. If a target is specified, it indicates the context within which the qualification applies.
  • read – Indicates that the actor read the object. This is typically only applicable for objects representing printed or written content, such as a book, a message or a comment. The “read” verb is a more specific form of the “consume”, “experience” and “play” verbs.
  • receive – Indicates that the actor is receiving an object. Examples include a person receiving abadge¬†object. Theobject¬†identifies the object being received.
  • reject – Indicates that the actor has rejected the object.
  • remove – Indicates that the actor has removed the object from the target.
  • remove-friend – Indicates that the actor has removed the object from the collection of friends.
  • replace – Indicates that the actor has replaced the target with the object.
  • request – Indicates that the actor has requested the object. If a target is specified, it indicates the entity from which the object is being requested.
  • request-friend – Indicates the creation of a friendship that has not yet been reciprocated by the object.
  • resolve – Indicates that the actor has resolved the object. For instance, the object could represent a ticket being tracked in an issue management system.
  • return – Indicates that the actor has returned the object. If a target is specified, it indicates the entity to which the object was returned.
  • retract – Indicates that the actor has retracted the object. For instance, if an actor wishes to retract a previously published activity, the object would be the previously published activity that is being retracted.
  • rsvp-maybe – The “possible RSVP” verb indicates that the actor has made a possible RSVP for the object. This specification only defines the meaning of this verb when its object is an¬†event, though implementors need to be prepared to handle other object types. The use of this verb is only appropriate when the RSVP was created by an explicit action by the actor. It is not appropriate to use this verb when a user has been added as an attendee by an event organiser or administrator.
  • rsvp-no – The “negative RSVP” verb indicates that the actor has made a negative RSVP for the object. This specification only defines the meaning of this verb when its object is an¬†event, though implementors need to be prepared to handle other object types. The use of this verb is only appropriate when the RSVP was created by an explicit action by the actor. It is not appropriate to use this verb when a user has been added as an attendee by an event organiser or administrator.
  • rsvp-yes – The “positive RSVP” verb indicates that the actor has made a positive RSVP for an object. This specification only defines the meaning of this verb when its object is an¬†event, though implementors need to be prepared to handle other object types. The use of this verb is only appropriate when the RSVP was created by an explicit action by the actor. It is not appropriate to use this verb when a user has been added as an attendee by an event organiser or administrator.
  • satisfy – Indicates that the actor has satisfied the object. If a target is specified, it indicate the context within which the object was satisfied. For instance, if a person satisfies the requirements for a particular challenge, the person is the actor; the requirement is the object; and the challenge is the target.
  • save – Indicates that the actor has called out the object as being of interest primarily to him- or herself. Though this action MAY be shared publicly, the implication is that the object has been saved primarily for the actor’s own benefit rather than to show it to others as would be indicated by the “share” verb.
  • schedule – Indicates that the actor has scheduled the object. For instance, scheduling a meeting.
  • search – Indicates that the actor is or has searched for the object. If a target is specified, it indicates the context within which the search is or has been conducted.
  • sell – Indicates that the actor has sold the object. If a target is specified, it indicates the entity to which the object was sold.
  • send – Indicates that the actor has sent the object. If a target is specified, it indicates the entity to which the object was sent.
  • share – Indicates that the actor has called out the object to readers. In most cases, the actor did not create the object being shared, but is instead drawing attention to it.
  • sponsor – Indicates that the actor has sponsored the object. If a target is specified, it indicates the context within which the sponsorship is offered. For instance, a company can sponsor an event; or an individual can sponsor a project; etc.
  • start – Indicates that the actor has started the object. For instance, when a person starts a project.
  • stop-following – Indicates that the actor has stopped following the object.
  • submit – Indicates that the actor has submitted the object. If a target is specified, it indicates the entity to which the object was submitted.
  • tag – Indicates that the actor has associated the object with the target. For example, if the actor specifies that a particular user appears in a photo. the object is the user and the target is the photo.
  • terminate – Indicates that the actor has terminated the object.
  • tie – Indicates that the actor has neither won or lost the object. This verb is generally only applicable when the object represents some form of competition, such as a game.
  • unfavorite – Indicates that the actor has removed the object from the collection of favorited items.
  • unlike – Indicates that the actor has removed the object from the collection of liked items.
  • unsatisfy – Indicates that the actor has not satisfied the object. If a target is specified, it indicates the context within which the object was not satisfied. For instance, if a person fails to satisfy the requirements of some particular challenge, the person is the actor; the requirement is the object and the challenge is the target.
  • unsave – Indicates that the actor has removed the object from the collection of saved items.
  • unshare – Indicates that the actor is no longer sharing the object. If a target is specified, it indicates the entity with whom the object is no longer being shared.
  • update – The “update” verb indicates that the actor has modified the object. Use of the “update” verb is generally reserved to indicate modifications to existing objects or data such as changing an existing user’s profile information.
  • use – Indicates that the actor has used the object in some manner.
  • watch – Indicates that the actor has watched the object. This verb is typically applicable only when the object represents dynamic, visible content such as a movie, a television show or a public performance. This verb is a more specific form of the verbs “experience”, “play” and “consume”.
  • win – Indicates that the actor has won the object. This verb is typically applicable only when the object represents some form of competition, such as a game.

 

The complete schema can be found on the Github page of the project, here.

 

Take care!

 

 

Resources:

Producing JWT tokens

To produce the JWT token i’ll be using the Nimbus JOSE+JWT Java library, which implements the Javascript Object Signing and Encryption (JOSE)¬†suite of specifications as well as the closely related JSON Web Token (JWT) specification.

Technologies used:

  • Apache Maven 3.0.5
  • Nimbus JOSE+JWT 2.16
  • Java 7

 

First, let’s add maven dependency for¬†Nimbus JOSE+JWT lib:

<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>2.16</version>
</dependency>

 

…and start composing the JWT reserved claims right away:

JWTClaimsSet jwtClaims = new JWTClaimsSet();
jwtClaims.setIssuer("https://my-auth-server.com");
jwtClaims.setSubject("Mariusz");
List aud = new ArrayList<>();
aud.add("https://my-web-app.com");
aud.add("https://your-web-app.com");
jwtClaims.setAudience(aud);
jwtClaims.setExpirationTime(new Date(new Date().getTime() + 1000*60*10));
jwtClaims.setNotBeforeTime(new Date());
jwtClaims.setIssueTime(new Date());
jwtClaims.setJWTID(UUID.randomUUID().toString());

as you can see, we’re setting up all of the Reserved Claim Names mentioned in my earlier post on JWT (ie. Issuer, Subject, Audience, Expiration Time (to 10 minutes), Not Before Time, Issued At Time and the JWT¬†ID) and using random UUID as the identifier of the token.

 

When printed out the above, you should see something similar to this:

{
    "exp":1373625160,
    "sub":"Mariusz";,
    "nbf":1373624561,
    "aud":[
        "https:\/\/my-web-app.com",
        "https:\/\/your-web-app.com"
    ],
    "iss":"https:\/\/my-auth-server.com";,
    "jti":"c79772ea-8777-44dc-a0fe-9001aeee9d02",
    "iat":1373624561
}

 

now, let’s create the JWT header and specify RSA-OAEP as the encryption algorithm and 128-bit AES/GCM as the encryption method that will be used to protect the JWT token:

JWEHeader header = new JWEHeader(
    JWEAlgorithm.RSA_OAEP,
    EncryptionMethod.A128GCM
);

 

next create the EncryptedJWT object that will be later used to perform the RSA encryption:

EncryptedJWT jwt = new EncryptedJWT(header, jwtClaims);

 

…create an RSA encrypter with the specified public RSA key:

RSAEncrypter encrypter = new RSAEncrypter(publicRsaKey);

(for details on how to generate RSA keys, please read my post on “RSA Keys Generation”)

 

and do the actual encryption:

jwt.encrypt(encrypter);

 

finally, we can serialize to JWT compact form in order to print it out to the screen nicely:

String jwtString = jwt.serialize();

 

what you should see after performing the steps above, is something similar to this:

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.ZyVpnDsmei
R_krnjTvMkB7a-DJrgdvwzXsMImIUS6x7B3yLEH5igpfiGfMD79SqYW5P
Fd7PrXVvNhq4Gs0YSg8qPPlPCjmaW7OnR9Oi891PRL1PyF0HqGzJJacZI
uu_jbeY0MQ9Z3hzNcuivhak60YFWLlGQWA7l4e7tkX4Hs4.fKF7TxNXc_
TmDl_P.AEPF230Ib8AeioJ6A4Kg0YXbYjaO4O4LVBu6qHQN1BP7ri_jc5
uCcIe02oFNEXoJZnSlaZP84LOZcnloNX6JBrLQnDr90jxkeDcoyiiLoxC
nebYJIksqyvxsGOvsAMS7MUt1Ms3Ua7tBv5pft0YVvIY9CK0oPdEyCAiu
vBp6KOR4Y9xkTy1xev5SUcWQjmskUlqtLnsO7mXpsMI09xTq13FgM2fTS
C5MIXFx2un8n8esh_rFMIfTlqLky1oa7dvb28ICjbYZPEq4CpCOeeMcQC
KliSy6A.zUGNd9GHWAY0m_m7xrQOOg

 

Now, if you’d like to read the data back from the token using your private RSA key, you’d have to do the following:

parse the above JWT string using EncryptedJWT object:

EncryptedJWT jwt = EncryptedJWT.parse(jwtString);

 

create a decrypter with the specified private RSA key:

RSADecrypter decrypter = new RSADecrypter(privateRsaKey);

 

do the decryption:

jwt.decrypt(decrypter);

 

and print out the claims:

System.out.println("iss: " + jwt.getJWTClaimsSet().getIssuer());
System.out.println("sub: " + jwt.getJWTClaimsSet().getSubject());
System.out.println("aud: " + jwt.getJWTClaimsSet().getAudience().size());
System.out.println("exp: " + jwt.getJWTClaimsSet().getExpirationTime());
System.out.println("nbf: " + jwt.getJWTClaimsSet().getNotBeforeTime());
System.out.println("iat: " + jwt.getJWTClaimsSet().getIssueTime());
System.out.println("jti: " + jwt.getJWTClaimsSet().getJWTID());

 

resulting with the following output:

iss: https://my-auth-server.com
sub: Mariusz
aud: 2
exp: Fri Jul 12 12:32:40 CEST 2013
nbf: Fri Jul 12 12:22:41 CEST 2013
iat: Fri Jul 12 12:22:41 CEST 2013
jti: c79772ea-8777-44dc-a0fe-9001aeee9d02

 

 

If you’re interested in a complete source code of this example, please clone the following Gist available on my GitHub account.

 

 

 

Sources:

JWT (JSON Web Tokens)

While working on one of the security-related aspects of the platform i’m building, i came across JWT specification which i find very interesting and thought will share with you the notes i made while reading:

 

  1. JWT acronym stands for¬†“JSON Web Tokens”.
  2. Definition of a security token:
    • encrypted data structure (in this case of JSON format) which contains:
      • information about the issuer and subject (claims)
      • proof of authenticity (digital signature)
      • expiration (validity) time
  1. Suggested pronunciation of JWT is the same as the English word “jot”.
  2. Basic facts:
  1. Why JSON-based standard?
    • XML-based SAML data format, exchanged over SOAP protocol offered a ton of encryption and signature options¬†but was percieved as a “heavy” technology and of not much use by mobile appliance (initially not that strong¬†in terms of computing power). JSON messages on the other hand don’t require a fairly advanced technology¬†stack (like SAX, StAX, etc.) to produce and parse data structures and can be exchanged over HTTP (also, each¬†browser nowadays is supporting JavaScript).
  1. Characteristics:
    • Plaintext JWTs: support use cases where the JWT content is secured by means other than a signature and/or encryption contained within the JWT. A plaintext JWT has the header “alg” parameter value set to “none”.
    • Encrypted JWTs: use JSON Web Signature (JWS) and JSON Web Encryption (JWE) to sign and/or encrypt the contents of the JWT using JSON Web Algorithms (JWA)
    • symmetric (HMACSHA256-384) and asymmetric (ECDSA, RSA) signatures
    • symmetric and asymmetric encryption (RSA, AES/CGM)
  1. Structure:
    • JWT Header
      • metadata
      • algorithms & keys used
    • JWT Claims
      • Reserved Claim Names:
        • “iss” (Issuer)
        • “sub” (Subject)
        • “aud” (Audience)
        • “exp” (Expiration)
        • “nbf” (Not Before)
        • “iat” (Issued At)
        • “jti” (JWT ID)
        • “typ” (Type)
      • Public Claim Names
      • Private Claim Names
  1. Example:
// header object
{
    "alg":"none"
}

// claims object
{
    "exp":1373625160,
    "sub":"Mariusz",
    "nbf":1373624561,
    "aud":[
        "https:\/\/my-web-app.com",
        "https:\/\/your-web-app.com"
    ],
    "iss":"https:\/\/my-auth-server.com",
    "jti":"c79772ea-8777-44dc-a0fe-9001aeee9d02",
    "iat":1373624561,

    // additional public claims
    "scope":["read", "search"],
    "client":"system A"

In the example above, the JWT Header implies that the encoded object is a Plaintext JWT. Additional public claims, may be useful for example in oAuth protocol (to know which system (A in this case) requested the token and what operations (read, search) will it be authorized to perform using this token).

  1. Sample encoding:
    • Base64url encoded representation of the JWT Header:
      • eyJhbGciOiJub25lIn0
    • Base64url encoded representation of the JWT Claims Set:
      • eyJleHAiOjEzNzM2NDI3NzYsInN1YiI6Ik1hcml1c3oiLCJuYmYiOjEzNzM2NDIxNzYsI
        mF1ZCI6WyJodHRwczpcL1wvbXktd2ViLWFwcC5jb20iLCJodHRwczpcL1wveW9
        1ci13ZWItYXBwLmNvbSJdLCJpc3MiOiJodHRwczpcL1wvbXktYXV0aC1zZXJ2ZXIu
        Y29tIiwianRpIjoiMWI2YjMxMTItMzkyZi00MzIxLTk2YjktNzkyYjhhMjcxOTliIiwiaWF
        0IjoxMzczNjQyMTc2fSwiY2xpZW50Ijoic3lzdGVtIEEiLCJzY29wZSI6WyJyZWFkIi
        wgInNlYXJjaCJd

 

Complete JWT is a result of concatenating encoded representations of the header and the claims set with a period (‘.’) character between the parts:

  • eyJhbGciOiJub25lIn0.eyJleHAiOjEzNzM2NDI3NzYsInN1YiI6Ik1hcml1c3oiLCJuYm
    YiOjEzNzM2NDIxNzYsImF1ZCI6WyJodHRwczpcL1wvbXktd2ViLWFwcC5jb20iLCJ
    odHRwczpcL1wveW91ci13ZWItYXBwLmNvbSJdLCJpc3MiOiJodHRwczpcL1wvb
    XktYXV0aC1zZXJ2ZXIuY29tIiwianRpIjoiMWI2YjMxMTItMzkyZi00MzIxLTk2YjktNzk
    yYjhhMjcxOTliIiwiaWF0IjoxMzczNjQyMTc2fSwiY2xpZW50Ijoic3lzdGVtIEEiLCJzY
    29wZSI6WyJyZWFkIiwgInNlYXJjaCJd

 

Finally, the above string representation of a JWT security token is what gets transmitted over the wire as a message header or url query parameter.

 

 

Sources: