From e0e91b75d6be3e2399e72ae2ee41f9bb7b47876b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 07:16:18 +0000 Subject: [PATCH 1/2] Fix dependabot security alerts: update handlebars, flatted, minimatch, lodash, picomatch, cross-spawn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update handlebars devDependency from ^4.7.7 to ^4.7.9 (fixes 5 CVEs) - Run npm audit fix: flatted 3.3.3→3.4.2, minimatch 3.1.2→3.1.5, lodash 4.17.21→4.17.23, picomatch 2.3.1→2.3.2, and others - Add overrides.cross-spawn >=7.0.6 to fix pre-commit vulnerability All 76 tests pass, lint clean, npm audit reports 0 vulnerabilities. Co-authored-by: GitHub Copilot Agent-Logs-Url: https://github.com/Staffbase/plugins-sdk-nodejs/sessions/8211c93b-6881-49da-8e5a-efa8ac6e3a76 Co-authored-by: maximizeIT <8626039+maximizeIT@users.noreply.github.com> --- README.MD | 202 ++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 120 +++++++-------------------- package.json | 5 +- 3 files changed, 236 insertions(+), 91 deletions(-) create mode 100644 README.MD diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..c7c6027 --- /dev/null +++ b/README.MD @@ -0,0 +1,202 @@ +[![Build Status](https://github.com/Staffbase/plugins-sdk-nodejs/workflows/Node.js%20CI/badge.svg)](https://github.com/Staffbase/plugins-sdk-nodejs/actions) + +# Staffbase Plugins SDK for Node.js. + +If you are developing your own plugin for your Staffbase app we describe the authentication flow of a plugin at https://developers.staffbase.com/guide/customplugin-overview/. While this documentation just covers the conceptual ideas of the interface of plugins though – the so called Plugin SSO – we want to provide a library to help you develop your first plugin for Staffbase even faster. This SDK provides the basic functionality to parse and verify a provided token for Node.js. + + +## Installation + +The plugin SDK can be fetched from the npm registry (https://www.npmjs.com/package/@staffbase/staffbase-plugin-sdk). You can use npm command line tool to install it locally. + + npm install (@staffbase/staffbase-plugin-sdk) + +You can also save the module as a local dependency in your project package.json file with the following command: + + npm install --save (@staffbase/staffbase-plugin-sdk) + + +## API Reference + +For the API reference of this SDK please consult the [docs](docs/API.MD). + +## Usage + +After installation you just need to include the module in your own Javascript Program. +The module can be included using the following syntax: + +```javascript +const StaffBaseSSO = require('@staffbase/staffbase-plugin-sdk').sso; +``` +## About secret token +Staffbase backend support only RS256 algorithm of JWT which means that the secret +you should provide must be the content of public key in the `PKCS8` format. +This means your public key should start and end with tags: + +``` +-----BEGIN PUBLIC KEY----- +BASE64 ENCODED DATA +-----END PUBLIC KEY----- +``` + +You can use the helper function to read and verify if your public key is in the supported format. +```javascript +const helpers = require(`@staffbase/staffbase-plugin-sdk`).helpers; +const publicKeyPath = '[[Your File Path]]'; +let keySecret; +try { + keySecret = helpers.readKeyFile(publicKeyPath); +} catch (err) { + console.log('Error Reading Key file', err); +} +``` + +You can then use keySecret to get an instance of StaffBaseSSO class. + +## Getting the SSOTokenData instance +You should have got your plugin id and Public Key file from Staffbase. After receiving the jwt token +from the Staffbase backend, you can use the module to get the contents of the token. + +```javascript +const pluginId = '[As received from Staffbase]'; +const publicKey = '[As received from Staffbase]'; +const jwtToken = '[As received in current request via jwt query parameter]'; +let tokenData = null; +try { + let SSOContents = new StaffBaseSSO(pluginId, publicKey, jwtToken); + tokenData = SSOContents.getTokenData(); + console.log('Received token data:', tokenData); +} catch(tokenErr) { + console.error('Error decoding token:', tokenErr); +} +``` + +If no exception is thrown, you would get a SSOTokenData instance in the tokenData +variable which you can use to get contents of the SSO Token. + +The following data can be retrieved from the token: + +|Helper Name|Token Key| Fetch Function| Description| +| --- | --- | --- | --- | +|CLAIM_BRANCH_ID|branch_id|getBranchId()|Get the branch ID for which the token was issued.| +|CLAIM_BRANCH_SLUG|branch_slug|getBranchSlug()|Get the branch slug for which the token was issued.| +|CLAIM_AUDIENCE|aud|getAudience()|Get targeted audience of the token.| +|CLAIM_EXPIRE_AT|exp|getExpireAtTime()|Get the time when the token expires.| +|CLAIM_NOT_BEFORE|nbf|getNotBeforeTime()|Get the time when the token starts to be valid.| +|CLAIM_ISSUED_AT|iat|getIssuedAtTime()|Get the time when the token was issued.| +|CLAIM_ISSUER|iss|getIssuer()|Get issuer of the token.| +|CLAIM_INSTANCE_ID|instance_id|getInstanceId()|Get the (plugin) instance id for which the token was issued.| +|CLAIM_INSTANCE_NAME|instance_name|getInstanceName()|Get the (plugin) instance name for which the token was issued.| +|CLAIM_USER_ID|sub|getUserId()|Get the id of the authenticated user.| +|CLAIM_USER_EXTERNAL_ID|external_id|getUserExternalId()|Get the id of the user in an external system.| +|CLAIM_USER_USERNAME|username|getUserUsername()|Get the username of the user accessing.| +|CLAIM_USER_PRIMARY_EMAIL_ADDRESS|primary_email_address|getUserPrimaryEmailAddress()|Get the primary email address of the user accessing.| +|CLAIM_USER_FULL_NAME|name|getFullName()|Get either the combined name of the user or the name of the token.| +|CLAIM_USER_FIRST_NAME|given_name|getFirstName()|Get the first name of the user accessing.| +|CLAIM_USER_LAST_NAME|family_name|getLastName()|Get the last name of the user accessing.| +|CLAIM_USER_ROLE|role|getRole()|Get the role of the accessing user.| +|CLAIM_ENTITY_TYPE|type|getType()|Get the type of the token.| +|CLAIM_THEME_TEXT_COLOR|theming_text|getThemeTextColor()|Get text color used in the overall theme for this audience.| +|CLAIM_THEME_BACKGROUND_COLOR|theming_bg|getThemeBackgroundColor()|Get background color used in the overall theme for this audience.| +|CLAIM_USER_LOCALE|locale|getLocale()|Get the locale of the requesting user in the format of language tags.| + +It is not guaranteed that the token would contain information of all the keys. +If there is no value for the corresponding field, the SDK would return a `null` value. + +## Using with Express +You can use the provided helper middleware to simply mount it to your express +server and get an instance of SSOTokenData class in your Express request object. + +You need to provide your *Secret Key* and *Plugin ID* to the middleware so it can decode the data. +The key can be provided in the constructor or by setting an Environment variables `STAFFBASE_SSO_SECRET` and `STAFFBASE_SSO_AUDIENCE` respectively. + +To provide the key using constructor: +```javascript +const ssoSecret = [[YOUR_PUBLIC_KEY_HERE]]; +const SSOMiddleware = require('@staffbase/staffbase-plugin-sdk').middleware; +let ssoMiddleWare = ssoMiddleWare(ssoSecret); +``` + +After getting an instance of the middleware function, you can simply mount it to your +SSO URL of the plugin. If the secret is fine and the middleware is able to decode the token, +an instance of `SSOTokenData` can be used in `req.sbSSO`. + +```javascript +const ssoSecret = [[YOUR_PUBLIC_KEY_HERE]]; +const SSOMiddleware = require('@staffbase/staffbase-plugin-sdk').middleware; +let ssoMiddleWare = SSOMiddleware(ssoSecret); + +const redirectURL = '/staffbase/sso/backoffice'; +let express = require('express'); +let app = express(); + +// Request Handler for client side of plugin +app.use('/frontEnd', ssoMiddleWare); +app.get('/frontEnd', function(req, res) { + if (req.sbSSO) { + // Render the decoded object using Express templating engine + return res.render('plugin', req.sbSSO); + } + return res.end("Unable to decode token data"); +}); + +// Apply middleware on the SSO URL +app.use(redirectURL, ssoMiddleWare); +// Your request handler for admin side of plugin below +app.get(redirectURL, function(req, res) { + // Middleware was able to decode the token + // console.log('Got SSO Request from backend', req.query); + if (req.sbSSO) { + let ssoTokenData = req.sbSSO; + // Send back the token data back. + res.json(ssoTokenData); + return res.end(); + } + res.json({ + error: { + msg: "Unable to get token information." + } + }); + return res.end(); +}); +``` + +### Generating Express Template +You can also use the `create-staffbase-plugin` CLI tool to start a template for a basic +express server configured with the SDK. For more detail please check out the +[Project Repo](https://github.com/Staffbase/create-staffbase-plugin-nodejs). + + +## Contribution + +- Fork it +- Create a branch `git checkout -b feature-description` +- Put your name into authors.txt +- Commit your changes `git commit -am "Added ...."` +- Push to the branch `git push origin feature-description` +- Open a Pull Request + +## Running Tests + +To run the tests a simple `# npm test` command in the root directory will suffice. The tests are run using the Jest framework. Please consult [jest](https://facebook.github.io/jest/) to learn more about writing unit tests for the plugin. + +## License + +Copyright 2017-2023 Staffbase GmbH. + +Licensed under the Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0 + + + + + + + +
+ Staffbase GmbH + + Staffbase GmbH +
Staffbase is an internal communications platform built to revolutionize the way you work and unite your company. Staffbase is hiring: jobs.staffbase.com +
GitHub | Website | Jobs +
+ diff --git a/package-lock.json b/package-lock.json index 290845a..c784936 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@staffbase/staffbase-plugin-sdk", - "version": "1.3.6", + "version": "1.3.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@staffbase/staffbase-plugin-sdk", - "version": "1.3.6", + "version": "1.3.7", "license": "ISC", "dependencies": { "jsonwebtoken": "^9.0.0", @@ -21,7 +21,7 @@ "eslint": "^8.32.0", "eslint-config-google": "^0.14.0", "eslint-plugin-node": "11.1.0", - "handlebars": "^4.7.7", + "handlebars": "^4.7.9", "jest": "^29.3.1", "jsdoc-to-markdown": "^8.0.1", "pre-commit": "^1.2.2" @@ -2648,9 +2648,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -2952,9 +2952,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -4235,9 +4235,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -4394,9 +4394,9 @@ "license": "MIT" }, "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5756,9 +5756,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, @@ -5885,9 +5885,9 @@ } }, "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "dev": true, "license": "MIT", "dependencies": { @@ -5972,9 +5972,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -6282,9 +6282,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true, "license": "MIT", "engines": { @@ -6340,52 +6340,6 @@ "which": "1.2.x" } }, - "node_modules/pre-commit/node_modules/cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "node_modules/pre-commit/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "license": "ISC", - "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/pre-commit/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pre-commit/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pre-commit/node_modules/which": { "version": "1.2.14", "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", @@ -6399,13 +6353,6 @@ "which": "bin/which" } }, - "node_modules/pre-commit/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true, - "license": "ISC" - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6465,13 +6412,6 @@ "node": ">= 6" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true, - "license": "ISC" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -7355,9 +7295,9 @@ } }, "node_modules/underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", "dev": true, "license": "MIT" }, diff --git a/package.json b/package.json index 8b8ad02..ca94f88 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "eslint": "^8.32.0", "eslint-config-google": "^0.14.0", "eslint-plugin-node": "11.1.0", - "handlebars": "^4.7.7", + "handlebars": "^4.7.9", "jest": "^29.3.1", "jsdoc-to-markdown": "^8.0.1", "pre-commit": "^1.2.2" @@ -50,5 +50,8 @@ "dependencies": { "jsonwebtoken": "^9.0.0", "node-rsa": "^1.1.1" + }, + "overrides": { + "cross-spawn": ">=7.0.6" } } From d25ed2c14022cf5861ad27750f1735086bff65a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 29 Mar 2026 07:27:15 +0000 Subject: [PATCH 2/2] Remove accidentally created README.MD duplicate Co-authored-by: GitHub Copilot Agent-Logs-Url: https://github.com/Staffbase/plugins-sdk-nodejs/sessions/41724268-372f-49f5-b9db-0e1e7ab51ce2 Co-authored-by: maximizeIT <8626039+maximizeIT@users.noreply.github.com> --- README.MD | 202 ------------------------------------------------------ 1 file changed, 202 deletions(-) delete mode 100644 README.MD diff --git a/README.MD b/README.MD deleted file mode 100644 index c7c6027..0000000 --- a/README.MD +++ /dev/null @@ -1,202 +0,0 @@ -[![Build Status](https://github.com/Staffbase/plugins-sdk-nodejs/workflows/Node.js%20CI/badge.svg)](https://github.com/Staffbase/plugins-sdk-nodejs/actions) - -# Staffbase Plugins SDK for Node.js. - -If you are developing your own plugin for your Staffbase app we describe the authentication flow of a plugin at https://developers.staffbase.com/guide/customplugin-overview/. While this documentation just covers the conceptual ideas of the interface of plugins though – the so called Plugin SSO – we want to provide a library to help you develop your first plugin for Staffbase even faster. This SDK provides the basic functionality to parse and verify a provided token for Node.js. - - -## Installation - -The plugin SDK can be fetched from the npm registry (https://www.npmjs.com/package/@staffbase/staffbase-plugin-sdk). You can use npm command line tool to install it locally. - - npm install (@staffbase/staffbase-plugin-sdk) - -You can also save the module as a local dependency in your project package.json file with the following command: - - npm install --save (@staffbase/staffbase-plugin-sdk) - - -## API Reference - -For the API reference of this SDK please consult the [docs](docs/API.MD). - -## Usage - -After installation you just need to include the module in your own Javascript Program. -The module can be included using the following syntax: - -```javascript -const StaffBaseSSO = require('@staffbase/staffbase-plugin-sdk').sso; -``` -## About secret token -Staffbase backend support only RS256 algorithm of JWT which means that the secret -you should provide must be the content of public key in the `PKCS8` format. -This means your public key should start and end with tags: - -``` ------BEGIN PUBLIC KEY----- -BASE64 ENCODED DATA ------END PUBLIC KEY----- -``` - -You can use the helper function to read and verify if your public key is in the supported format. -```javascript -const helpers = require(`@staffbase/staffbase-plugin-sdk`).helpers; -const publicKeyPath = '[[Your File Path]]'; -let keySecret; -try { - keySecret = helpers.readKeyFile(publicKeyPath); -} catch (err) { - console.log('Error Reading Key file', err); -} -``` - -You can then use keySecret to get an instance of StaffBaseSSO class. - -## Getting the SSOTokenData instance -You should have got your plugin id and Public Key file from Staffbase. After receiving the jwt token -from the Staffbase backend, you can use the module to get the contents of the token. - -```javascript -const pluginId = '[As received from Staffbase]'; -const publicKey = '[As received from Staffbase]'; -const jwtToken = '[As received in current request via jwt query parameter]'; -let tokenData = null; -try { - let SSOContents = new StaffBaseSSO(pluginId, publicKey, jwtToken); - tokenData = SSOContents.getTokenData(); - console.log('Received token data:', tokenData); -} catch(tokenErr) { - console.error('Error decoding token:', tokenErr); -} -``` - -If no exception is thrown, you would get a SSOTokenData instance in the tokenData -variable which you can use to get contents of the SSO Token. - -The following data can be retrieved from the token: - -|Helper Name|Token Key| Fetch Function| Description| -| --- | --- | --- | --- | -|CLAIM_BRANCH_ID|branch_id|getBranchId()|Get the branch ID for which the token was issued.| -|CLAIM_BRANCH_SLUG|branch_slug|getBranchSlug()|Get the branch slug for which the token was issued.| -|CLAIM_AUDIENCE|aud|getAudience()|Get targeted audience of the token.| -|CLAIM_EXPIRE_AT|exp|getExpireAtTime()|Get the time when the token expires.| -|CLAIM_NOT_BEFORE|nbf|getNotBeforeTime()|Get the time when the token starts to be valid.| -|CLAIM_ISSUED_AT|iat|getIssuedAtTime()|Get the time when the token was issued.| -|CLAIM_ISSUER|iss|getIssuer()|Get issuer of the token.| -|CLAIM_INSTANCE_ID|instance_id|getInstanceId()|Get the (plugin) instance id for which the token was issued.| -|CLAIM_INSTANCE_NAME|instance_name|getInstanceName()|Get the (plugin) instance name for which the token was issued.| -|CLAIM_USER_ID|sub|getUserId()|Get the id of the authenticated user.| -|CLAIM_USER_EXTERNAL_ID|external_id|getUserExternalId()|Get the id of the user in an external system.| -|CLAIM_USER_USERNAME|username|getUserUsername()|Get the username of the user accessing.| -|CLAIM_USER_PRIMARY_EMAIL_ADDRESS|primary_email_address|getUserPrimaryEmailAddress()|Get the primary email address of the user accessing.| -|CLAIM_USER_FULL_NAME|name|getFullName()|Get either the combined name of the user or the name of the token.| -|CLAIM_USER_FIRST_NAME|given_name|getFirstName()|Get the first name of the user accessing.| -|CLAIM_USER_LAST_NAME|family_name|getLastName()|Get the last name of the user accessing.| -|CLAIM_USER_ROLE|role|getRole()|Get the role of the accessing user.| -|CLAIM_ENTITY_TYPE|type|getType()|Get the type of the token.| -|CLAIM_THEME_TEXT_COLOR|theming_text|getThemeTextColor()|Get text color used in the overall theme for this audience.| -|CLAIM_THEME_BACKGROUND_COLOR|theming_bg|getThemeBackgroundColor()|Get background color used in the overall theme for this audience.| -|CLAIM_USER_LOCALE|locale|getLocale()|Get the locale of the requesting user in the format of language tags.| - -It is not guaranteed that the token would contain information of all the keys. -If there is no value for the corresponding field, the SDK would return a `null` value. - -## Using with Express -You can use the provided helper middleware to simply mount it to your express -server and get an instance of SSOTokenData class in your Express request object. - -You need to provide your *Secret Key* and *Plugin ID* to the middleware so it can decode the data. -The key can be provided in the constructor or by setting an Environment variables `STAFFBASE_SSO_SECRET` and `STAFFBASE_SSO_AUDIENCE` respectively. - -To provide the key using constructor: -```javascript -const ssoSecret = [[YOUR_PUBLIC_KEY_HERE]]; -const SSOMiddleware = require('@staffbase/staffbase-plugin-sdk').middleware; -let ssoMiddleWare = ssoMiddleWare(ssoSecret); -``` - -After getting an instance of the middleware function, you can simply mount it to your -SSO URL of the plugin. If the secret is fine and the middleware is able to decode the token, -an instance of `SSOTokenData` can be used in `req.sbSSO`. - -```javascript -const ssoSecret = [[YOUR_PUBLIC_KEY_HERE]]; -const SSOMiddleware = require('@staffbase/staffbase-plugin-sdk').middleware; -let ssoMiddleWare = SSOMiddleware(ssoSecret); - -const redirectURL = '/staffbase/sso/backoffice'; -let express = require('express'); -let app = express(); - -// Request Handler for client side of plugin -app.use('/frontEnd', ssoMiddleWare); -app.get('/frontEnd', function(req, res) { - if (req.sbSSO) { - // Render the decoded object using Express templating engine - return res.render('plugin', req.sbSSO); - } - return res.end("Unable to decode token data"); -}); - -// Apply middleware on the SSO URL -app.use(redirectURL, ssoMiddleWare); -// Your request handler for admin side of plugin below -app.get(redirectURL, function(req, res) { - // Middleware was able to decode the token - // console.log('Got SSO Request from backend', req.query); - if (req.sbSSO) { - let ssoTokenData = req.sbSSO; - // Send back the token data back. - res.json(ssoTokenData); - return res.end(); - } - res.json({ - error: { - msg: "Unable to get token information." - } - }); - return res.end(); -}); -``` - -### Generating Express Template -You can also use the `create-staffbase-plugin` CLI tool to start a template for a basic -express server configured with the SDK. For more detail please check out the -[Project Repo](https://github.com/Staffbase/create-staffbase-plugin-nodejs). - - -## Contribution - -- Fork it -- Create a branch `git checkout -b feature-description` -- Put your name into authors.txt -- Commit your changes `git commit -am "Added ...."` -- Push to the branch `git push origin feature-description` -- Open a Pull Request - -## Running Tests - -To run the tests a simple `# npm test` command in the root directory will suffice. The tests are run using the Jest framework. Please consult [jest](https://facebook.github.io/jest/) to learn more about writing unit tests for the plugin. - -## License - -Copyright 2017-2023 Staffbase GmbH. - -Licensed under the Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0 - - - - - - - -
- Staffbase GmbH - - Staffbase GmbH -
Staffbase is an internal communications platform built to revolutionize the way you work and unite your company. Staffbase is hiring: jobs.staffbase.com -
GitHub | Website | Jobs -
-