# Services

# Users service

TIP

Available as a global service

# Data model

The data model of a user as used by the API is detailed here.

# Hooks

The following hooks are executed on the users service:

# Devices service

TIP

Available as a global service

WARNING

update and remove methods are the only ones allowed from the client side create method is only allowed from the server side

create (respectively remove) creates (respectively removes) the device to/from the notification system (APNS or Firebase). update updates the device registration ID or create it if not yet created.

# Data model

The data model of a device as used by the API is detailed here.

TIP

Devices are store in the devices property of the user they belong to.

# Hooks

The following hooks are executed on the devices service:

# Mailer service

TIP

Available as a global service

This service is powered by feathers-mailer (opens new window). It acts as a proxy to send emails through an SMTP server.

WARNING

Service methods are only allowed from the server side. create is the sole available method used to send an email.

DEPRECATION NOTICE

The email account can authorise connection by email/password on https://myaccount.google.com/lesssecureapps (opens new window). Before that the domain admin should allow him to manage this setting (Admin Console > Security > General > Less secure apps settings). To avoid changing it for all users first create a group, add the user to the group and let the group manage less secure apps setting.

On 15 february 2021 Gmail API requires OAuth2 authentication to send emails. The simplest solution is to create a service account (opens new window) and to delegate the domain-wide authority to the service account (opens new window) with scope https://mail.google.com.

# Hooks

The following hooks are executed on the databases service:

# Pusher service

TIP

Available as a global service

This service relies on sns-mobile (opens new window), which has a nice tutorial (opens new window), to manage the link between AWS SNS (opens new window) and internal resource objects in order to send push notifications to users.

To get an API access/secret key you need to create a new user in IAM with a role giving access to SNS like AmazonSNSFullAccess but in production you should control access more precisely (opens new window).

Since 2017 Google Cloud Messaging (GCM) has become Firebase Cloud Messaging (FCM), to generate an API key follow this issue (opens new window) and enter the server key when creating the SNS application on AWS. Although you use the Firebase console you should also see the created API through the Google Cloud console.

WARNING

create and remove methods are the only one allowed from the server side

# Data model

This service helps (un)registering devices to/from SNS and create/remove SNS topics. This service also helps associating a resource object (e.g. a group) with a SNS topic to provide push notifications to the users associated with the resource. SNS ARNs are directly stored on the target resource(s) in the topics property.

TIP

The service is designed to possibly manage a different topic per platform (e.g. ANDROID / IOS), although at the present time the same topic is used by all platforms because by default SNS topics are cross-platforms.

For instance the topics associated to a group will result in the following structure on the group object:

{
    _id: ObjectId('5f568ba1fc54a1002fe6fe37'),
    name: 'Centre de Castelnaudary',
    topics: {
        ANDROID: 'arn:aws:sns:eu-west-1:xxx',
        IOS: 'arn:aws:sns:eu-west-1:xxx'
    }
}

Last but not least, This service helps publishing messages to SNS devices or topics.

As a consequence, the create/remove operations have to be called with an action property indicating the target SNS operations among device, topic, subscriptions and message. The payload varies according to the selected target operation:

  • device:
    • device as data: device object with SNS ARN and/or registration ID (i.e. token) for APNS or Firebase
  • topic:
    • pushObject as params: target resource owing the topic
    • pushService as params: target resource service
    • topicField as data/query: target property to store the topic
  • subscriptions
    • pushObject as params: target resource owing the topic
    • users as params: target subject(s) to subscribe to topic
    • topicField as data/query: target property to store the topic
  • message
    • pushObject as params: target resource owing the topic if topic
    • pushService as params: target resource service
    • message as data: message payload

# Hooks

The following hooks are executed on the pusher service:

# Account service

TIP

Available as a global service

This service is powered by feathers-authentication-management (opens new window).

# Data model

This service consists in associating verification tokens to users so that they can safely reset their password or change their email, please refer to feathers-authentication-management docs (opens new window).

# Hooks

The following hooks are executed on the account service:

# Testing

To make test run we need two gmail accounts:

  • email-notifications@kalisio.com used as email sender
  • test@kalisio.com used as user test email

When testing identity change we also use the test@kalisio.xyz address as user test email. However to avoid creating a new account in Google you can simply add an alias for this address to the test@kalisio.com account.

The first email account is used by the mailer service to send email notifications. The second email account requires OAuth2 authentication to be able to read emails using the GMail API. The simplest way is by creating a service account for a JWT-based authentication. Interesting issue to make all the configuration work can be found here (opens new window), notably you have to delegate domain-wide authority to the service account in order to authorize your app to access user data on behalf of users and authorise the client ID of the service account with scopes https://mail.google.com/,https://www.googleapis.com/auth/gmail.readonly.

Standard OAuth2 with refresh token might also be used as detailed here (opens new window) and here (opens new window).

Details on how to use Google APIs from Node.js here (opens new window).

Some anti-virus or firewalls softwares intercept HTTPS traffic, decrypting it, and then encrypting it using a self-signed certificate causing a "Self-Signed Certificate in Certificate Chain" error. If so deactivate the SSL analysys in your software, this might help (opens new window).

# Authorisations service

TIP

Available as a global service

WARNING

create and remove methods are the only one allowed from the client/server side

# Data model

An authorisation consists in associating a resource object (e.g. a group) with a subject object (e.g. a user) according to a permission (i.e. a role or a right). The resource object information and the permission are directly stored on the target subject(s) in a property called the scope of the authorisation (e.g. groups to store all groups a user belongs to).

For instance the groups a user belongs to with different roles will result in the following structure on the user:

groups: [
  {
      _id: ObjectId('5f568ba1fc54a1002fe6fe37'),
      name: 'Centre de Castelnaudary',
      context: '5f55f4169f6d47002f05f4ac',
      permissions: 'owner'
      ...
  },
  {
      _id: ObjectId('5f64a3791a1714002f68437d'),
      name: 'Kalisio',
      context: '5f532d439f6d47002f04f07e',
      permissions: 'manager'
      ...
  },
  {
      _id: ObjectId('5f65e34a75b663003095f52e'),
      name: 'LTD',
      context: '5f65d98084f9d5003039b55b',
      permissions: 'member'
      ...
  }
]

# Hooks

The following hooks are executed on the authorisations service:

# Tags service

TIP

Available as a global and a contextual service

Tags can be created directly using this service or by "tagging" a target resource (e.g. a user). As a consequence, create/remove operations can include a target resource as input data/ID.

Due to this behaviour tags are created/removed by value, not by ID. To avoid duplication when tagging multiple resources with the same tag, the service manages a reference count on tag objects and they are automatically created/removed accordingly.

WARNING

remove method can be called with a resource ID

# Data model

The data model of a tag as used by the API is detailed here.

# Hooks

The following hooks are executed on the tags service:

# Storage service

TIP

Available as a global and a contextual service

WARNING

get, create and remove methods are the only one allowed from the client/server side

Blobs can be created directly using this service or through "attachment" to a target resource (e.g. a user).

This service heavily relies on feathers-blob (opens new window) and multer (opens new window) for handling multipart/form-data (opens new window).

# Data model

No data model, data are directly stored on target storage backend (i.e. AWS S3).

# Hooks

The following hooks are executed on the storage service:

# Databases service

TIP

Available as a global service

This service is powered by feathers-mongodb-management (opens new window). It acts as a proxy to perform MongoDB operations like creating databases, collections or users.

WARNING

Service methods are only allowed from the server side

# Hooks

The following hooks are executed on the databases service:

# Organisations service

TIP

Available as a global service

This service exhibits the following methods in addition to standard CRUD operations:

  • createOrganisationServices: creates all registered services for an organisation
  • removeOrganisationServices: removes registered services for an organisation
  • registerOrganisationServicesHook(hook): register a function to create additional services per organisation
  • unregisterOrganisationServicesHook(hook): unregister a previously registered function

A hook function has the following structure:

{
  createOrganisationServices: function(organisation, db)
  removeOrganisationServices: function(organisation, db)
}

TIP

By default the following services are created for an organisation: members, tags, groups, storage.

# Data model

The data model of an organisation as used by the API is detailed here.

# Hooks

No specific hooks are executed on the organisations service.

# Members service

TIP

Available as a contextual service

This service is a proxy to the users service available at the organisation level in order to filter users belonging to it.

# Data model

The data model of a member as used by the API is a the one of a user.

# Hooks

No specific hooks are executed on the members service.

# Groups service

TIP

Available as a contextual service

# Data model

The data model of a group as used by the API is detailed here.

# Hooks

The following hooks are executed on the groups service:

# Local settings service

This client-side service allows to restore/save persistent settings to/from the global store from/to local storage (opens new window).

WARNING

get and patch methods are the only one allowed, id parameter is ignored and methods will always target the whole settings object

WARNING

This service has to be instanciated at application level, none provided by default

To create your own service use the following code:

import { Store, LocalSettingsService } from '@kalisio/kdk/core.client'

// Setup defaults in global store
Store.set('app-settings', { x: y, ... })
// Create a service targeting only settings in store
const settingsService = api.createService('settings', {
  service: LocalSettingsService,
  propertyMapping: {
    x: 'app-settings.x',
    ...
  }
})
// Restore previous settings from local storage if any
settingsService.restoreSettings()

TIP

Because settings are available through a service interface you can edit it using the editor system. The propertyMapping will be used to match form field names and corresponding global store properties.

For instance the following schema can be used to edit the previous sample:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$id": "http://www.kalisio.xyz/schemas/settings.update.json#",
  "title": "schemas.UPDATE_SETTINGS_TITLE",
  "type": "object",
  "properties": {
    "x": {
      "type": "string", 
      "field": {
        "component": "form/KTextField",
        "helper": "schemas.X_FIELD_LABEL"
      }
    }
  },
  "required": ["x"]
}