Manage using API

Prerequisite to test following examples is to have an API key with permissions:

Path Methods ACL
/users/core\.user POST off
/users/core\.user GET on
/users/core\.user/([0-9a-fA-F]{24}|me) GET, PATCH, DELETE on
/users/core\.user\.token POST off
/users/core\.user\.token/([0-9a-fA-F]{24}|me) DELETE on

Test API key is client-oriented, meaning ACL is turned on. Therefore, the client can manage only its user/token. One can create API key with ACL turned off when for example trusted services needs to manage all users.

Create

Creating a user is available on /users/core.user endpoint. Document core.user requires following attributes:

  • username - should have at least 3 characters where letters, numbers and characters _ (underscore), - (minus), . (dot) and @ (at sign) are allowed
  • password - should have at least 6 characters

Additional attributes are allowed (e.g. e-mail). Further validation can be added using a custom schema which targets core.user documents.

ACL must be turned off in order to be able to create a user. ACL cannot be turned on since user (token) does not yet exist. The system does not provide user validation like sending invitation links via e-mail or sending invitation codes via text message. When such logic is required external proxy (like a stateless function) can be used. In such cases, client API key should not have rights to create a user. Instead, the client should send user creation requests to a proxy which has an API key with the rights to create a user and which enforces user validation based on application requirements.

API request creating a user with username john-smith and password snowIsFalling:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
  "data": {
    "type": "core.user",
    "attributes": {
      "username": "john-smith",
      "password": "snowIsFalling"
    }
  }
}' \
-X POST https://api.jazer.io/users/core.user

The response contains a created core.user document with an encrypted password:

{
  "data": {
    "type": "core.user",
    "id": "5a2b245dac61054ef7fd469c",
    "attributes": {
      "username": "john-smith",
      "password": "$2a$11$beg4atTQblEkPzTkDO87AOmwxC3AqeaHmxQeKwCkeONrH9YUZRQt."
    },
    "links": {
      "self": "https://api.jazer.io/users/core.user/5a2b245dac61054ef7fd469c"
    }
  }
}

User document ACL record will by default reference itself. Meaning, a user has all rights to his user document.

Login

Login is performed by creating a token on /users/core.user.token endpoint. A request needs to send Authorization header where value starts with Basic and ends with base64 encoded value of <USERNAME>:<PASSWORD>. Base64 encoded john-smith:snowIsFalling is am9obi1zbWl0aDpzbm93SXNGYWxsaW5n. Complete API request is:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Basic am9obi1zbWl0aDpzbm93SXNGYWxsaW5n' \
-X POST https://api.jazer.io/users/core.user.token

The response contains a created core.user.token document. Attribute token contains a token value:

{
  "data": {
    "type": "core.user.token",
    "id": "5a2b268dac61054ef7fd471c",
    "attributes": {
      "token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6eyJ0eXBlIjoiY29yZS51c2VyLnRva2VuIiwiaWQiOiI1YTJiMjY4ZGFjNjEwNTRlZjdmZDQ3MWMifSwidXNlciI6eyJ0eXBlIjoiY29yZS51c2VyIiwiaWQiOiI1YTJiMjQ1ZGFjNjEwNTRlZjdmZDQ2OWMifSwiaXNzIjoiamF6ZXIiLCJpYXQiOjE1MTI3NzczNTcsImV4cCI6MTUxNTM2OTM1N30.MEUCIQDlkUesVzjbtcEbLXluCwzvPGkDnVsdvV8RWcxuSROdjQIgP7r70JljyrUfB7no_DJwo9f4x1Hau69QfIS_A_3Jpn4",
      "created": "2017-12-08T13:55:57.459Z"
    },
    "relationships": {
      "user": {
        "data": {
          "type": "core.user",
          "id": "5a2b245dac61054ef7fd469c"
        }
      }
    },
    "links": {
      "self": "https://api.jazer.io/users/core.user.token/5a2b268dac61054ef7fd471c"
    }
  }
}

A token is valid for 30 days. Logout and password change will expire token immediately. The client can be authenticated as a user using Authorization header with a value Token <TOKEN>, where <TOKEN> is token value.

Logout

Logout is performed by deleting a token document on /users/core.user.token/<TOKEN_ID> endpoint. Alias me can be used instead of a token ID on the endpoint path. Alias will be resolved using a token sent in the header. Complete API request is:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <YOUR_TOKEN>' \
-X DELETE https://api.jazer.io/users/core.user.token/me

Read

Fetching a user by ID is available on the API endpoint /users/core.user/<USER_ID>. When a token is sent in the header, alias me can be used instead of a user ID in the endpoint path. Complete API request is:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <YOUR_TOKEN>' \
-X GET https://api.jazer.io/users/core.user/me

The response contains a core.user document:

{
  "data": {
    "type": "core.user",
    "id": "5a2b245dac61054ef7fd469c",
    "attributes": {
      "username": "john-smith",
      "password": "$2a$11$beg4atTQblEkPzTkDO87AOmwxC3AqeaHmxQeKwCkeONrH9YUZRQt."
    },
    "links": {
      "self": "https://api.jazer.io/users/core.user/5a2b245dac61054ef7fd469c"
    }
  }
}

Note

An API key with permission path /users/core\.user/me is not enough. Alias is resolved to an ID and it undergoes same security checks. Meaning permission path which allowes fetching by ID like /users/core\.user/[0-9a-fA-F]{24} is also needed. These two paths can be merged into one like /users/core\.user\.token/([0-9a-fA-F]{24}|me).

Update

Updating a user is available on the API endpoint /users/core.user/<USER_ID>. When a token is sent in the header, alias me can be used instead of a user ID in the endpoint path. Complete API request which changes a password is:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <YOUR_TOKEN>' \
-d '
{
  "data": {
    "type": "core.user",
    "id": "5a2b245dac61054ef7fd469c",
    "attributes": {
      "password": "santaExists"
    }
  }
}' \
-X PATCH https://api.jazer.io/users/core.user/me

Tokens for an updated user are invalidated.

Delete

Deleting a user is available on the API endpoint /users/core.user/<USER_ID>. When a token is sent in the header, alias me can be used instead of a user ID in the endpoint path. Complete API request is:

curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'Authorization: Token <YOUR_TOKEN>' \
-X DELETE https://api.jazer.io/users/core.user/me