OpenPlatform / 02. How does it work?
Updated: 05. April 2019
Author: Peter Širka

02. How does it work?

Professional Support Chat with contributors

OpenPlatform has a simple logic. It's a container for users and third-party applications. Each application needs own domain name and it needs to contain a file openplatform.json with application's meta data.

For example: https://127.0.0.1:8001/openplatform.json

{

    // required, application's name
    "name": "TestApp",

    // optional, application's title in OpenPlatform
    "name": "Test application",

    // required, application's description
    "description": "Some text for the super user.",

    // required, application's version
    "version": "1.0.0",

    // required, application's icon
    "icon": "http://127.0.0.1:8001/icon.png",

    // required, application's URL address which is open in iFrame
    "url": "http://127.0.0.1:8001",

    // required, author of the application
    "author": "Peter Širka",

    // required, email to support
    "email": "petersirka@gmail.com",

    // optional, custom roles (String Array)
    "roles": ["create", "read", "update"],

    // optional, your custom server-side IP addresses for remote access e.g. for sending notifications (String Array)
    "origin": ['IP_address'],

    // optional, a custom app type, we use files, contacts, orders, invoices, users
    "type": "files",

    // Allows to read OpenPlatform's meta information
    "allowreadmeta": true,

    // Allows to read user profile
    // 0 - disabled
    // 1 - basic information without contact details
    // 2 - all information
    "allowreadprofile": 1,

    // Allows to read users
    // 0 - disabled
    // 1 - basic information without contact details of all users
    // 3 - basic information without contact details of all users which use this app
    // 2 - all information of all users
    // 4 - all information of all users which use this app
    "allowreadusers": 1,

    // Allows to read apps
    // 0 - disabled
    // 1 - basic information
    // 2 - all information (email, roles, origin, custom config, url)
    "allowreadapps": 1,

    // Enables server-side verification only by default
    "serververify": true,

    // Shows mobile menu in process title bar for mobile devices
    "mobilemenu": true,

    // Enables application in mobile devices
    "responsive": true
}

Authorization

OpenPlatform has a very simple authorization mechanism. The whole authorization is executed on the client-side over iFrame messaging if the server-side verification is disabled.

Authorization processing

  • user launches some app in OpenPlatform main window
  • app is open in iframe container
  • then app needs to init OpenPlatform client-side library
  • main window OpenPlatform checks the app and roles on the server-side
  • then iframe obtains meta-data described below

Client-side library

OpenPlatform offers a small client-side library called openplatform.js. The application can obtain user/meta-data from OpenPlatform and it supports another features for OpenPlatform manipulation.

App meta-data

Your application needs to use this code below:

<script src="https://cdn.totaljs.com/openplatform.min@3.js"></script>
<script>
    OP.init(function(err, response) {

        if (err) {
            // some error
            document.body.innerHTML = '401: Unauthorized';
            return;
        }

        // response === meta-data

        if (response.serverside) {
            // 1. you don't have all data because of security context
            // 2. you need to send a verification URL to your backend
            // 3. and your backend needs to create a request to verification URL
        } else {
            // you have all meta-data from OpenPlatform
        }
    });
</script>
  • if err contain a value then app can't continue (otherwise: null)
  • response contains all meta data
  • reidrectTimeout contains an ID of timeout if the redirect will be executed

Sample of meta data

The content depends on application's privileges.

{
    // {Date} Current date/time
    "datetime":"2017-09-11T08:29:10.621Z",

    // {String} User access token
    "accesstoken": "TOKEN",

    // {String} Current user IP
    "ip": "78.98.35.929",

    // {String}
    "name": "Name of OpenPlatform",

    // {String} Custom settings (defined in application's section)
    "settings": ""

    // {String} ID of application
    "id": "se1hlb6qfbd852av4m2n",

    // {String} OpenPlatform URL address
    "openplatform": "https://openplatform.totaljs.com",

    // {Number} OpenPlatform ID
    "openplatformid": 30493403094

    // {String} Application's URL address
    "url": "http://127.0.0.1:8001/",       

    // {String/Object/Number/Boolean/Time} A data from another third-party application (optional)
    "data": null,

    // {Boolean} Inditicates a server-side verification of the user profile
    "serverside": false,

    // {String} URL address for verifying of the meta data on server-side (BTW: CORS enabled), response contains same result
    "verify": "URL address",

    // {Object} OpenPlatform meta data (code lists)
    "meta": "URL address",

    // {Object} User profile
    "profile": {
        
        // {String} ID user
        "id": "17082512500002gkj0",

        // {String} ID supervisor, can be empty (optional)
        "supervisorid": "17082512500002gkj0",

        // {String} A directory (optional)
        // This property determines independent group of users in OpenPlatform which doesn't have access to all users
        "directory": "customers",
        
        // {Number} A directory ID (default: 0)
        // Gengerated UID from "directory", it's targeted for storing data in DB
        "directoryid": 12030230,

        // {Number} A status ID
        // 0: available (default)
        // 1: busy
        // 2: do not disturb
        // 3: be right back
        // 4: off work
        "statusid": 0,

         // {String}, optional
        "status": "A custom user status filled via user",

        // {String}, optional, in most cases isn't exist
        "directory": "Customers",

        // {String}
        "firstname": "Peter",

        // {String}
        "lastname": "Širka",

        // {String}
        "name": "Peter Širka",

        // {String} Can be "male" or "female"
        "gender": "male",

        // {String} Languages can be defined in OpenPlatform "config"
        "language": "sk",

        // {String} Photo URL address (optional)
        "photo": "URL address",

        // {String} A custom reference (optional, can be defiend in "Users" section)
        "reference": "",

        // {String Array} User roles for this application + with global roles
        "roles": ["read"],

        // {Date} Date of birth
        "datebirth": "1984-11-05T23:00:00.000Z",

        // {Date} Creation date - profile
        "datecreated": "2017-08-25T10:50:38.648Z"

        // {Date} Update date - profile
        "dateupdated": "2017-08-25T10:50:38.648Z"

        // {Date} When did the user begin in your company? (optional)
        "datebeg": "2017-08-25T10:50:38.648Z"

        // {Date} When did the user end in your company? (optional)
        "dateend": "2017-08-25T10:50:38.648Z"

        // {String} + optional
        "company": "Company",

        // {String} + optional
        "locality": "Locality",

        // Groups
        // {Array String}
        "groups": ["developers"],

        // Organization unit
        // {String} + optional
        "ou": "Developers / Web",

        // {String Array}
        "ougroups": ["Developers", "Developers/Web"]

        // {Boolean} Is super-admin account?
        "sa": true,

        // {Boolean} Is the user online?
        "online": true,

        // {Boolean} Is the user blocked? (optional)
        "blocked": false,

        // {Boolean} Has the user enabled sounds?
        "sounds": true,
            
        // {Boolean} Determines that OP is in test mode (optional)
        "test": true,
            
        // {Number} Determines the volume in %
        "volume": 50,

        // {Boolean} Has the user enabled notifications?
        "notifications": true,

        // {String} Absolute URL address for sending of push notification
        "notify": "URL address",

        // {String} Absolute URL address for calling a badge
        "badge": "URL address",

        // {Boolean} Determines "darkmode"
        "darkmode": true

        // {String} HEX color for e.g. buttons
        "colorscheme": "#4285f4"

        // {String} absolute URL address to background (optional)
        "background": "https://.....bg.jpg",

        // {Number} How many badges has this user?
        "countbadges": 0,

        // {Number} How many unread notifications has this user?
        "countnotifications": 0,
        
        // {Number} How many sessions has open this user?
        "countsessions": 0
    },

    // Returns {Object Array} with users
    // Query arguments:
    // id=USER_ID1,USER_ID2
    // appid=APP_ID
    // role=ROLE        
    // group=GROUP
    // q=SEARCH
    // ou=OU
    // locality=LOCALITY
    // company=COMPANY
    // directory=DIRECTORY (name or ID)
    // statusid=STATUS_ID
    // customer=true
    // all=true (only for administrators and with filled "Directory" field, it returns all users from DB)
    // reference=REFERENCE
    // page=NUMBER
    // online=true (returns only online users)
    // modified=1 day or 5 minutes or 1 week
    // logged=1 day or 5 minutes or 1 week
    // limit=NUMBER (defaut 1000)
    "users": "URL address",

    // Returns {Object Array} with apps
    // Query arguments:
    // userid=USER_ID
    // id=APP_ID1,APP_ID2
    // page=NUMBER
    // limit=NUMBER (defaut 1000)
    "apps": "URL address"
}

Response: meta

{
    "companies":   [{ count: 1, name: "Name", id: String }],
    "customers":   [{ count: 1, name: "Name", id: String }],
    "oa":          [{ count: 1, name: "Name", id: String }],
    "groups":      [{ count: 1, name: "Name", id: String }],
    "languages":   [{ count: 1, name: "Name", id: String }],
    "roles":       [{ count: 1, name: "Name", id: String }],
    "localities":  [{ count: 1, name: "Name", id: String }],
    "directories": [{ count: 1, name: "name", id: Number }]
}

Response: users

// coming soon

Response: apps

// coming soon

Limitations

Modern browsers block third-party cookies in iFrames (Safari). In other words: your application can't use cookies. This behaviour can be disabled in web browser's settings.

Good to know

OpenPlatform changes verification token for each user if the user is logging. It's because of security reasons.