@qikdev/sdk 1.0.2 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{docs/access.html → access.html} +353 -20
- package/dist/api.html +444 -0
- package/dist/{docs/auth.html → auth.html} +14 -14
- package/dist/cache.html +351 -0
- package/dist/{docs/content.html → content.html} +46 -21
- package/dist/{docs/files.html → files.html} +147 -6
- package/dist/{docs/filter.html → filter.html} +9 -9
- package/dist/geo.html +1029 -0
- package/dist/global.html +240 -0
- package/dist/index.html +96 -0
- package/dist/main.js +2 -3
- package/dist/module-QikStorage-CookieStorageAdapter.html +407 -0
- package/dist/module-QikStorage-LocalStorageAdapter.html +193 -0
- package/dist/module-QikStorage-StorageAdapter.html +977 -0
- package/dist/module-QikStorage.html +433 -0
- package/dist/qik.access.js.html +904 -0
- package/dist/qik.api.js.html +409 -0
- package/dist/{docs/qik.auth.js.html → qik.auth.js.html} +142 -104
- package/dist/qik.cache.js.html +125 -0
- package/dist/qik.content.js.html +967 -0
- package/dist/qik.core.js.html +322 -0
- package/dist/qik.files.js.html +249 -0
- package/dist/{docs/qik.filter.js.html → qik.filter.js.html} +3 -3
- package/dist/qik.geo.js.html +963 -0
- package/dist/{docs/qik.socket.js.html → qik.socket.js.html} +53 -12
- package/dist/qik.storage.js.html +375 -0
- package/dist/qik.system.js.html +117 -0
- package/dist/qik.utils.js.html +1548 -0
- package/dist/{docs/socket.html → socket.html} +7 -7
- package/dist/{docs/styles → styles}/jsdoc.css +2 -2
- package/dist/system.html +197 -0
- package/dist/utils.html +4422 -0
- package/package.json +2 -2
- package/src/api/qik.filter.js +1 -1
- package/src/api/qik.geo.js +1 -1
- package/src/api/qik.socket.js +18 -12
- package/src/api/qik.utils.js +6 -0
- package/src/version.js +1 -1
- package/dist/docs/api.html +0 -1356
- package/dist/docs/cache.html +0 -351
- package/dist/docs/index.html +0 -96
- package/dist/docs/qik.access.js.html +0 -790
- package/dist/docs/qik.api.js.html +0 -511
- package/dist/docs/qik.cache.js.html +0 -131
- package/dist/docs/qik.content.js.html +0 -918
- package/dist/docs/qik.core.js.html +0 -301
- package/dist/docs/qik.files.js.html +0 -219
- package/dist/docs/qik.system.js.html +0 -117
- package/dist/docs/qik.utils.js.html +0 -1467
- package/dist/docs/system.html +0 -197
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.woff2 +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.woff2 +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- /package/dist/{docs/scripts → scripts}/collapse.js +0 -0
- /package/dist/{docs/scripts → scripts}/linenumber.js +0 -0
- /package/dist/{docs/scripts → scripts}/nav.js +0 -0
- /package/dist/{docs/scripts → scripts}/polyfill.js +0 -0
- /package/dist/{docs/scripts → scripts}/prettify/Apache-License-2.0.txt +0 -0
- /package/dist/{docs/scripts → scripts}/prettify/lang-css.js +0 -0
- /package/dist/{docs/scripts → scripts}/prettify/prettify.js +0 -0
- /package/dist/{docs/scripts → scripts}/search.js +0 -0
- /package/dist/{docs/styles → styles}/prettify.css +0 -0
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
<nav >
|
|
29
29
|
|
|
30
|
-
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="access.html">access</a><ul class='methods'><li data-type='method'><a href="access.html#.actionableScopes">actionableScopes</a></li><li data-type='method'><a href="access.html#.allPermissions">allPermissions</a></li><li data-type='method'><a href="access.html#.allPermissionTypes">allPermissionTypes</a></li><li data-type='method'><a href="access.html#.allUserScopes">allUserScopes</a></li><li data-type='method'><a href="access.html#.canCreate">canCreate</a></li><li data-type='method'><a href="access.html#.canDeleteItem">canDeleteItem</a></li><li data-type='method'><a href="access.html#.canEditItem">canEditItem</a></li><li data-type='method'><a href="access.html#.canEraseItem">canEraseItem</a></li><li data-type='method'><a href="access.html#.canKnowOf">canKnowOf</a></li><li data-type='method'><a href="access.html#.canListItem">canListItem</a></li><li data-type='method'><a href="access.html#.canRestoreItem">canRestoreItem</a></li><li data-type='method'><a href="access.html#.canViewItem">canViewItem</a></li><li data-type='method'><a href="access.html#.checkActionAccess">checkActionAccess</a></li><li data-type='method'><a href="access.html#.getAllDescendants">getAllDescendants</a></li><li data-type='method'><a href="access.html#.has">has</a></li><li data-type='method'><a href="access.html#.
|
|
30
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="access.html">access</a><ul class='methods'><li data-type='method'><a href="access.html#.actionableScopes">actionableScopes</a></li><li data-type='method'><a href="access.html#.allPermissions">allPermissions</a></li><li data-type='method'><a href="access.html#.allPermissionTypes">allPermissionTypes</a></li><li data-type='method'><a href="access.html#.allUserScopes">allUserScopes</a></li><li data-type='method'><a href="access.html#.canCreate">canCreate</a></li><li data-type='method'><a href="access.html#.canDeleteItem">canDeleteItem</a></li><li data-type='method'><a href="access.html#.canEditItem">canEditItem</a></li><li data-type='method'><a href="access.html#.canEraseItem">canEraseItem</a></li><li data-type='method'><a href="access.html#.canKnowOf">canKnowOf</a></li><li data-type='method'><a href="access.html#.canListItem">canListItem</a></li><li data-type='method'><a href="access.html#.canRestoreItem">canRestoreItem</a></li><li data-type='method'><a href="access.html#.canViewItem">canViewItem</a></li><li data-type='method'><a href="access.html#.checkActionAccess">checkActionAccess</a></li><li data-type='method'><a href="access.html#.getAllDescendants">getAllDescendants</a></li><li data-type='method'><a href="access.html#.has">has</a></li><li data-type='method'><a href="access.html#.hasFeature">hasFeature</a></li><li data-type='method'><a href="access.html#.hashPermissions">hashPermissions</a></li><li data-type='method'><a href="access.html#.isAdministrator">isAdministrator</a></li><li data-type='method'><a href="access.html#.isAssignee">isAssignee</a></li><li data-type='method'><a href="access.html#.isOwner">isOwner</a></li></ul></li><li><a href="api.html">api</a><ul class='methods'><li data-type='method'><a href="api.html#.generateEndpointURL">generateEndpointURL</a></li></ul></li><li><a href="auth.html">auth</a><ul class='methods'><li data-type='method'><a href="auth.html#.changeOrganisation">changeOrganisation</a></li><li data-type='method'><a href="auth.html#.ensureValidToken">ensureValidToken</a></li><li data-type='method'><a href="auth.html#.getCurrentToken">getCurrentToken</a></li><li data-type='method'><a href="auth.html#.getCurrentUser">getCurrentUser</a></li><li data-type='method'><a href="auth.html#.impersonate">impersonate</a></li><li data-type='method'><a href="auth.html#.login">login</a></li><li data-type='method'><a href="auth.html#.logout">logout</a></li><li data-type='method'><a href="auth.html#.retrieveUserFromResetToken">retrieveUserFromResetToken</a></li><li data-type='method'><a href="auth.html#.sendResetPasswordRequest">sendResetPasswordRequest</a></li><li data-type='method'><a href="auth.html#.set">set</a></li><li data-type='method'><a href="auth.html#.sync">sync</a></li><li data-type='method'><a href="auth.html#.updateUserWithToken">updateUserWithToken</a></li></ul></li><li><a href="cache.html">cache</a><ul class='methods'><li data-type='method'><a href="cache.html#.get">get</a></li><li data-type='method'><a href="cache.html#.reset">reset</a></li></ul></li><li><a href="content.html">content</a><ul class='methods'><li data-type='method'><a href="content.html#.create">create</a></li><li data-type='method'><a href="content.html#.delete">delete</a></li><li data-type='method'><a href="content.html#.get">get</a></li><li data-type='method'><a href="content.html#.getFromSlug">getFromSlug</a></li><li data-type='method'><a href="content.html#.glossary">glossary</a></li><li data-type='method'><a href="content.html#.list">list</a></li><li data-type='method'><a href="content.html#.patch">patch</a></li><li data-type='method'><a href="content.html#.restore">restore</a></li><li data-type='method'><a href="content.html#.scopeGlossary">scopeGlossary</a></li><li data-type='method'><a href="content.html#.update">update</a></li><li data-type='method'><a href="content.html#.validateField">validateField</a></li><li data-type='method'><a href="content.html#.variables">variables</a></li></ul></li><li><a href="files.html">files</a><ul class='methods'><li data-type='method'><a href="files.html#.downloadUrl">downloadUrl</a></li><li data-type='method'><a href="files.html#.duration">duration</a></li><li data-type='method'><a href="files.html#.filesize">filesize</a></li><li data-type='method'><a href="files.html#.getBinaryTypeFromMime">getBinaryTypeFromMime</a></li><li data-type='method'><a href="files.html#.mediaUrl">mediaUrl</a></li></ul></li><li><a href="filter.html">filter</a><ul class='methods'><li data-type='method'><a href="filter.html#.activeFilterComparators">activeFilterComparators</a></li><li data-type='method'><a href="filter.html#.activeFilterKeys">activeFilterKeys</a></li><li data-type='method'><a href="filter.html#.activeFilterOperators">activeFilterOperators</a></li><li data-type='method'><a href="filter.html#.activeFilters">activeFilters</a></li><li data-type='method'><a href="filter.html#.activeFilterValues">activeFilterValues</a></li><li data-type='method'><a href="filter.html#.filterChangeString">filterChangeString</a></li><li data-type='method'><a href="filter.html#.isValidFilter">isValidFilter</a></li></ul></li><li><a href="geo.html">geo</a><ul class='methods'><li data-type='method'><a href="geo.html#.distance">distance</a></li><li data-type='method'><a href="geo.html#.getDefaultCountry">getDefaultCountry</a></li><li data-type='method'><a href="geo.html#.getDefaultTimezone">getDefaultTimezone</a></li><li data-type='method'><a href="geo.html#.getPosition">getPosition</a></li><li data-type='method'><a href="geo.html#.stopWatchPosition">stopWatchPosition</a></li><li data-type='method'><a href="geo.html#.watchPosition">watchPosition</a></li></ul></li><li><a href="module-QikStorage-CookieStorageAdapter.html">CookieStorageAdapter</a><ul class='methods'><li data-type='method'><a href="module-QikStorage-CookieStorageAdapter.html#getCookieOptions">getCookieOptions</a></li><li data-type='method'><a href="module-QikStorage-CookieStorageAdapter.html#isCookieMode">isCookieMode</a></li></ul></li><li><a href="module-QikStorage-LocalStorageAdapter.html">LocalStorageAdapter</a></li><li><a href="module-QikStorage-StorageAdapter.html">StorageAdapter</a><ul class='methods'><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#clearUser">clearUser</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getAccessToken">getAccessToken</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getRefreshToken">getRefreshToken</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getTokenExpiry">getTokenExpiry</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getUser">getUser</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#isAvailable">isAvailable</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#setUser">setUser</a></li></ul></li><li><a href="socket.html">socket</a><ul class='methods'><li data-type='method'><a href="socket.html#.channel">channel</a></li><li data-type='method'><a href="socket.html#.close">close</a></li><li data-type='method'><a href="socket.html#.connect">connect</a></li><li data-type='method'><a href="socket.html#.reconnect">reconnect</a></li><li data-type='method'><a href="socket.html#.subscribe">subscribe</a></li><li data-type='method'><a href="socket.html#.unsubscribe">unsubscribe</a></li></ul></li><li><a href="system.html">system</a><ul class='methods'><li data-type='method'><a href="system.html#.countries">countries</a></li></ul></li><li><a href="utils.html">utils</a><ul class='methods'><li data-type='method'><a href="utils.html#.cleanValue">cleanValue</a></li><li data-type='method'><a href="utils.html#.comma">comma</a></li><li data-type='method'><a href="utils.html#.errorMessage">errorMessage</a></li><li data-type='method'><a href="utils.html#.exists">exists</a></li><li data-type='method'><a href="utils.html#.extractFromArray">extractFromArray</a></li><li data-type='method'><a href="utils.html#.formatCurrency">formatCurrency</a></li><li data-type='method'><a href="utils.html#.getTypeFromID">getTypeFromID</a></li><li data-type='method'><a href="utils.html#.guid">guid</a></li><li data-type='method'><a href="utils.html#.hash">hash</a></li><li data-type='method'><a href="utils.html#.id">id</a></li><li data-type='method'><a href="utils.html#.ids">ids</a></li><li data-type='method'><a href="utils.html#.isValidEmailAddress">isValidEmailAddress</a></li><li data-type='method'><a href="utils.html#.loadExternalScript">loadExternalScript</a></li><li data-type='method'><a href="utils.html#.loadExternalStyle">loadExternalStyle</a></li><li data-type='method'><a href="utils.html#.machineName">machineName</a></li><li data-type='method'><a href="utils.html#.mapParameters">mapParameters</a></li><li data-type='method'><a href="utils.html#.matchInArray">matchInArray</a></li><li data-type='method'><a href="utils.html#.parseBoolean">parseBoolean</a></li><li data-type='method'><a href="utils.html#.parseDate">parseDate</a></li><li data-type='method'><a href="utils.html#.parseEmail">parseEmail</a></li><li data-type='method'><a href="utils.html#.parseInt">parseInt</a></li><li data-type='method'><a href="utils.html#.parseNumber">parseNumber</a></li><li data-type='method'><a href="utils.html#.parseURL">parseURL</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-QikStorage.html">QikStorage</a><ul class='methods'><li data-type='method'><a href="module-QikStorage.html#.createStorageAdapter">createStorageAdapter</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#EventDispatcher">EventDispatcher</a></li></ul>
|
|
31
31
|
</nav>
|
|
32
32
|
|
|
33
33
|
<div id="main">
|
|
@@ -117,6 +117,26 @@ const QikSocket = function(qik, mode) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
const bucket = new EventDispatcher();
|
|
120
|
+
|
|
121
|
+
function dispatchMessage(message) {
|
|
122
|
+
bucket.dispatch('message', message);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Destroy this channel - stop receiving its events and tell the
|
|
126
|
+
// server to unsubscribe. Only touches this channel's own listeners,
|
|
127
|
+
// leaving every other channel (and connection-level listeners) intact.
|
|
128
|
+
bucket.destroy = function() {
|
|
129
|
+
service.removeEventListener(key, dispatchMessage);
|
|
130
|
+
service.unsubscribe(key);
|
|
131
|
+
bucket.removeAllListeners();
|
|
132
|
+
delete buckets[key];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Cache the fully-formed bucket (with destroy attached) BEFORE the
|
|
136
|
+
// connect() await below. A concurrent channel(key) call can hit the
|
|
137
|
+
// early return above while we're suspended awaiting connect(); if we
|
|
138
|
+
// registered the bucket before assigning destroy, that caller would
|
|
139
|
+
// receive a bucket whose destroy() is missing and throw on teardown.
|
|
120
140
|
buckets[key] = bucket;
|
|
121
141
|
|
|
122
142
|
if (!service.connected) {
|
|
@@ -130,16 +150,6 @@ const QikSocket = function(qik, mode) {
|
|
|
130
150
|
// Listen for all relevant events
|
|
131
151
|
service.addEventListener(key, dispatchMessage);
|
|
132
152
|
|
|
133
|
-
function dispatchMessage(message) {
|
|
134
|
-
bucket.dispatch('message', message);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Destroy the service
|
|
138
|
-
bucket.destroy = function() {
|
|
139
|
-
service.removeAllListeners();
|
|
140
|
-
buckets[key] = null;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
153
|
return buckets[key];
|
|
144
154
|
}
|
|
145
155
|
|
|
@@ -384,6 +394,37 @@ const QikSocket = function(qik, mode) {
|
|
|
384
394
|
|
|
385
395
|
///////////////////////////////////////////////////
|
|
386
396
|
|
|
397
|
+
// Reconnect the socket whenever the authenticated organisation changes.
|
|
398
|
+
// The WebSocket authenticates with an access token at connect time, so the
|
|
399
|
+
// connection stays bound to whichever organisation was active when it
|
|
400
|
+
// opened. Switching organisations issues a new token but leaves the socket
|
|
401
|
+
// untouched, so without this it keeps streaming the previous
|
|
402
|
+
// organisation's events. Reconnecting re-authenticates with the new token.
|
|
403
|
+
let currentOrganisationID = qik.utils.id(qik.auth.getCurrentUser()?.organisation);
|
|
404
|
+
|
|
405
|
+
qik.auth.addEventListener('change', async function(user) {
|
|
406
|
+
const organisationID = qik.utils.id(user?.organisation);
|
|
407
|
+
|
|
408
|
+
// Ignore auth changes that don't change the organisation (e.g. routine
|
|
409
|
+
// access token refreshes) so we don't churn the connection needlessly.
|
|
410
|
+
if (organisationID === currentOrganisationID) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
currentOrganisationID = organisationID;
|
|
415
|
+
|
|
416
|
+
// Nothing to reconnect if the socket was never opened.
|
|
417
|
+
if (!socket) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
service.debug ? console.log('[socket] - organisation changed, reconnecting') : null;
|
|
422
|
+
await service.close();
|
|
423
|
+
await service.reconnect();
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
///////////////////////////////////////////////////
|
|
427
|
+
|
|
387
428
|
return service;
|
|
388
429
|
|
|
389
430
|
}
|
|
@@ -403,7 +444,7 @@ export default QikSocket;</code></pre>
|
|
|
403
444
|
<br class="clear">
|
|
404
445
|
|
|
405
446
|
<footer>
|
|
406
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.11</a> on
|
|
447
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.11</a> on Mon Jul 13 2026 18:47:22 GMT+1000 (Australian Eastern Standard Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
407
448
|
</footer>
|
|
408
449
|
|
|
409
450
|
<script>prettyPrint();</script>
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>qik.storage.js - Documentation</title>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<script src="scripts/prettify/prettify.js"></script>
|
|
10
|
+
<script src="scripts/prettify/lang-css.js"></script>
|
|
11
|
+
<!--[if lt IE 9]>
|
|
12
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
13
|
+
<![endif]-->
|
|
14
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
15
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
16
|
+
<script src="scripts/nav.js" defer></script>
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
|
|
21
|
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
22
|
+
<label for="nav-trigger" class="navicon-button x">
|
|
23
|
+
<div class="navicon"></div>
|
|
24
|
+
</label>
|
|
25
|
+
|
|
26
|
+
<label for="nav-trigger" class="overlay"></label>
|
|
27
|
+
|
|
28
|
+
<nav >
|
|
29
|
+
|
|
30
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="access.html">access</a><ul class='methods'><li data-type='method'><a href="access.html#.actionableScopes">actionableScopes</a></li><li data-type='method'><a href="access.html#.allPermissions">allPermissions</a></li><li data-type='method'><a href="access.html#.allPermissionTypes">allPermissionTypes</a></li><li data-type='method'><a href="access.html#.allUserScopes">allUserScopes</a></li><li data-type='method'><a href="access.html#.canCreate">canCreate</a></li><li data-type='method'><a href="access.html#.canDeleteItem">canDeleteItem</a></li><li data-type='method'><a href="access.html#.canEditItem">canEditItem</a></li><li data-type='method'><a href="access.html#.canEraseItem">canEraseItem</a></li><li data-type='method'><a href="access.html#.canKnowOf">canKnowOf</a></li><li data-type='method'><a href="access.html#.canListItem">canListItem</a></li><li data-type='method'><a href="access.html#.canRestoreItem">canRestoreItem</a></li><li data-type='method'><a href="access.html#.canViewItem">canViewItem</a></li><li data-type='method'><a href="access.html#.checkActionAccess">checkActionAccess</a></li><li data-type='method'><a href="access.html#.getAllDescendants">getAllDescendants</a></li><li data-type='method'><a href="access.html#.has">has</a></li><li data-type='method'><a href="access.html#.hasFeature">hasFeature</a></li><li data-type='method'><a href="access.html#.hashPermissions">hashPermissions</a></li><li data-type='method'><a href="access.html#.isAdministrator">isAdministrator</a></li><li data-type='method'><a href="access.html#.isAssignee">isAssignee</a></li><li data-type='method'><a href="access.html#.isOwner">isOwner</a></li></ul></li><li><a href="api.html">api</a><ul class='methods'><li data-type='method'><a href="api.html#.generateEndpointURL">generateEndpointURL</a></li></ul></li><li><a href="auth.html">auth</a><ul class='methods'><li data-type='method'><a href="auth.html#.changeOrganisation">changeOrganisation</a></li><li data-type='method'><a href="auth.html#.ensureValidToken">ensureValidToken</a></li><li data-type='method'><a href="auth.html#.getCurrentToken">getCurrentToken</a></li><li data-type='method'><a href="auth.html#.getCurrentUser">getCurrentUser</a></li><li data-type='method'><a href="auth.html#.impersonate">impersonate</a></li><li data-type='method'><a href="auth.html#.login">login</a></li><li data-type='method'><a href="auth.html#.logout">logout</a></li><li data-type='method'><a href="auth.html#.retrieveUserFromResetToken">retrieveUserFromResetToken</a></li><li data-type='method'><a href="auth.html#.sendResetPasswordRequest">sendResetPasswordRequest</a></li><li data-type='method'><a href="auth.html#.set">set</a></li><li data-type='method'><a href="auth.html#.sync">sync</a></li><li data-type='method'><a href="auth.html#.updateUserWithToken">updateUserWithToken</a></li></ul></li><li><a href="cache.html">cache</a><ul class='methods'><li data-type='method'><a href="cache.html#.get">get</a></li><li data-type='method'><a href="cache.html#.reset">reset</a></li></ul></li><li><a href="content.html">content</a><ul class='methods'><li data-type='method'><a href="content.html#.create">create</a></li><li data-type='method'><a href="content.html#.delete">delete</a></li><li data-type='method'><a href="content.html#.get">get</a></li><li data-type='method'><a href="content.html#.getFromSlug">getFromSlug</a></li><li data-type='method'><a href="content.html#.glossary">glossary</a></li><li data-type='method'><a href="content.html#.list">list</a></li><li data-type='method'><a href="content.html#.patch">patch</a></li><li data-type='method'><a href="content.html#.restore">restore</a></li><li data-type='method'><a href="content.html#.scopeGlossary">scopeGlossary</a></li><li data-type='method'><a href="content.html#.update">update</a></li><li data-type='method'><a href="content.html#.validateField">validateField</a></li><li data-type='method'><a href="content.html#.variables">variables</a></li></ul></li><li><a href="files.html">files</a><ul class='methods'><li data-type='method'><a href="files.html#.downloadUrl">downloadUrl</a></li><li data-type='method'><a href="files.html#.duration">duration</a></li><li data-type='method'><a href="files.html#.filesize">filesize</a></li><li data-type='method'><a href="files.html#.getBinaryTypeFromMime">getBinaryTypeFromMime</a></li><li data-type='method'><a href="files.html#.mediaUrl">mediaUrl</a></li></ul></li><li><a href="filter.html">filter</a><ul class='methods'><li data-type='method'><a href="filter.html#.activeFilterComparators">activeFilterComparators</a></li><li data-type='method'><a href="filter.html#.activeFilterKeys">activeFilterKeys</a></li><li data-type='method'><a href="filter.html#.activeFilterOperators">activeFilterOperators</a></li><li data-type='method'><a href="filter.html#.activeFilters">activeFilters</a></li><li data-type='method'><a href="filter.html#.activeFilterValues">activeFilterValues</a></li><li data-type='method'><a href="filter.html#.filterChangeString">filterChangeString</a></li><li data-type='method'><a href="filter.html#.isValidFilter">isValidFilter</a></li></ul></li><li><a href="geo.html">geo</a><ul class='methods'><li data-type='method'><a href="geo.html#.distance">distance</a></li><li data-type='method'><a href="geo.html#.getDefaultCountry">getDefaultCountry</a></li><li data-type='method'><a href="geo.html#.getDefaultTimezone">getDefaultTimezone</a></li><li data-type='method'><a href="geo.html#.getPosition">getPosition</a></li><li data-type='method'><a href="geo.html#.stopWatchPosition">stopWatchPosition</a></li><li data-type='method'><a href="geo.html#.watchPosition">watchPosition</a></li></ul></li><li><a href="module-QikStorage-CookieStorageAdapter.html">CookieStorageAdapter</a><ul class='methods'><li data-type='method'><a href="module-QikStorage-CookieStorageAdapter.html#getCookieOptions">getCookieOptions</a></li><li data-type='method'><a href="module-QikStorage-CookieStorageAdapter.html#isCookieMode">isCookieMode</a></li></ul></li><li><a href="module-QikStorage-LocalStorageAdapter.html">LocalStorageAdapter</a></li><li><a href="module-QikStorage-StorageAdapter.html">StorageAdapter</a><ul class='methods'><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#clearUser">clearUser</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getAccessToken">getAccessToken</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getRefreshToken">getRefreshToken</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getTokenExpiry">getTokenExpiry</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getUser">getUser</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#isAvailable">isAvailable</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#setUser">setUser</a></li></ul></li><li><a href="socket.html">socket</a><ul class='methods'><li data-type='method'><a href="socket.html#.channel">channel</a></li><li data-type='method'><a href="socket.html#.close">close</a></li><li data-type='method'><a href="socket.html#.connect">connect</a></li><li data-type='method'><a href="socket.html#.reconnect">reconnect</a></li><li data-type='method'><a href="socket.html#.subscribe">subscribe</a></li><li data-type='method'><a href="socket.html#.unsubscribe">unsubscribe</a></li></ul></li><li><a href="system.html">system</a><ul class='methods'><li data-type='method'><a href="system.html#.countries">countries</a></li></ul></li><li><a href="utils.html">utils</a><ul class='methods'><li data-type='method'><a href="utils.html#.cleanValue">cleanValue</a></li><li data-type='method'><a href="utils.html#.comma">comma</a></li><li data-type='method'><a href="utils.html#.errorMessage">errorMessage</a></li><li data-type='method'><a href="utils.html#.exists">exists</a></li><li data-type='method'><a href="utils.html#.extractFromArray">extractFromArray</a></li><li data-type='method'><a href="utils.html#.formatCurrency">formatCurrency</a></li><li data-type='method'><a href="utils.html#.getTypeFromID">getTypeFromID</a></li><li data-type='method'><a href="utils.html#.guid">guid</a></li><li data-type='method'><a href="utils.html#.hash">hash</a></li><li data-type='method'><a href="utils.html#.id">id</a></li><li data-type='method'><a href="utils.html#.ids">ids</a></li><li data-type='method'><a href="utils.html#.isValidEmailAddress">isValidEmailAddress</a></li><li data-type='method'><a href="utils.html#.loadExternalScript">loadExternalScript</a></li><li data-type='method'><a href="utils.html#.loadExternalStyle">loadExternalStyle</a></li><li data-type='method'><a href="utils.html#.machineName">machineName</a></li><li data-type='method'><a href="utils.html#.mapParameters">mapParameters</a></li><li data-type='method'><a href="utils.html#.matchInArray">matchInArray</a></li><li data-type='method'><a href="utils.html#.parseBoolean">parseBoolean</a></li><li data-type='method'><a href="utils.html#.parseDate">parseDate</a></li><li data-type='method'><a href="utils.html#.parseEmail">parseEmail</a></li><li data-type='method'><a href="utils.html#.parseInt">parseInt</a></li><li data-type='method'><a href="utils.html#.parseNumber">parseNumber</a></li><li data-type='method'><a href="utils.html#.parseURL">parseURL</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-QikStorage.html">QikStorage</a><ul class='methods'><li data-type='method'><a href="module-QikStorage.html#.createStorageAdapter">createStorageAdapter</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#EventDispatcher">EventDispatcher</a></li></ul>
|
|
31
|
+
</nav>
|
|
32
|
+
|
|
33
|
+
<div id="main">
|
|
34
|
+
|
|
35
|
+
<h1 class="page-title">qik.storage.js</h1>
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
<section>
|
|
44
|
+
<article>
|
|
45
|
+
<pre class="prettyprint source linenums"><code>/**
|
|
46
|
+
* Storage abstraction layer for handling both localStorage and httpOnly cookie storage
|
|
47
|
+
* @module QikStorage
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Base storage interface
|
|
52
|
+
*/
|
|
53
|
+
class StorageAdapter {
|
|
54
|
+
constructor() {
|
|
55
|
+
if (this.constructor === StorageAdapter) {
|
|
56
|
+
throw new Error("StorageAdapter is an abstract class and cannot be instantiated directly");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get user session data
|
|
62
|
+
* @returns {Object|null} User session object
|
|
63
|
+
*/
|
|
64
|
+
getUser() {
|
|
65
|
+
throw new Error("getUser method must be implemented");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Set user session data
|
|
70
|
+
* @param {Object} user User session object
|
|
71
|
+
*/
|
|
72
|
+
setUser(user) {
|
|
73
|
+
throw new Error("setUser method must be implemented");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Clear user session data
|
|
78
|
+
*/
|
|
79
|
+
clearUser() {
|
|
80
|
+
throw new Error("clearUser method must be implemented");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get current access token
|
|
85
|
+
* @returns {String|null} Access token
|
|
86
|
+
*/
|
|
87
|
+
getAccessToken() {
|
|
88
|
+
throw new Error("getAccessToken method must be implemented");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get current refresh token
|
|
93
|
+
* @returns {String|null} Refresh token
|
|
94
|
+
*/
|
|
95
|
+
getRefreshToken() {
|
|
96
|
+
throw new Error("getRefreshToken method must be implemented");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get token expiry date
|
|
101
|
+
* @returns {String|null} Token expiry date
|
|
102
|
+
*/
|
|
103
|
+
getTokenExpiry() {
|
|
104
|
+
throw new Error("getTokenExpiry method must be implemented");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Check if storage is available
|
|
109
|
+
* @returns {Boolean} Whether storage is available
|
|
110
|
+
*/
|
|
111
|
+
isAvailable() {
|
|
112
|
+
throw new Error("isAvailable method must be implemented");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* localStorage-based storage adapter (current behavior)
|
|
118
|
+
*/
|
|
119
|
+
class LocalStorageAdapter extends StorageAdapter {
|
|
120
|
+
constructor() {
|
|
121
|
+
super();
|
|
122
|
+
this.storage = {};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getUser() {
|
|
126
|
+
return this.storage.user || null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
setUser(user) {
|
|
130
|
+
this.storage.user = user;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
clearUser() {
|
|
134
|
+
delete this.storage.user;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
getAccessToken() {
|
|
138
|
+
const user = this.getUser();
|
|
139
|
+
return user?.token?.accessToken || null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
getRefreshToken() {
|
|
143
|
+
const user = this.getUser();
|
|
144
|
+
return user?.token?.refreshToken || null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
getTokenExpiry() {
|
|
148
|
+
const user = this.getUser();
|
|
149
|
+
return user?.token?.expires || null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
isAvailable() {
|
|
153
|
+
return true; // Always available as it uses in-memory storage
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Cookie-based storage adapter for httpOnly cookies
|
|
159
|
+
*/
|
|
160
|
+
class CookieStorageAdapter extends StorageAdapter {
|
|
161
|
+
constructor(options = {}) {
|
|
162
|
+
super();
|
|
163
|
+
this.options = {
|
|
164
|
+
domain: options.domain || this._detectDomain(),
|
|
165
|
+
secure: options.secure !== false, // Default to true
|
|
166
|
+
sameSite: options.sameSite || 'lax',
|
|
167
|
+
...options
|
|
168
|
+
};
|
|
169
|
+
this.sessionStorage = {}; // In-memory storage for session data
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Auto-detect appropriate cookie domain
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
_detectDomain() {
|
|
177
|
+
if (typeof window === 'undefined') return null;
|
|
178
|
+
|
|
179
|
+
const hostname = window.location.hostname;
|
|
180
|
+
|
|
181
|
+
// For localhost, don't set domain
|
|
182
|
+
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// For IP addresses, don't set domain
|
|
187
|
+
if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// For subdomains, use parent domain (e.g., .example.com)
|
|
192
|
+
const parts = hostname.split('.');
|
|
193
|
+
if (parts.length > 2) {
|
|
194
|
+
return '.' + parts.slice(-2).join('.');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return null; // Let browser handle single domain
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Read a cookie value
|
|
202
|
+
* @private
|
|
203
|
+
*/
|
|
204
|
+
_getCookie(name) {
|
|
205
|
+
if (typeof document === 'undefined') return null;
|
|
206
|
+
|
|
207
|
+
const value = `; ${document.cookie}`;
|
|
208
|
+
const parts = value.split(`; ${name}=`);
|
|
209
|
+
if (parts.length === 2) {
|
|
210
|
+
return parts.pop().split(';').shift();
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Set a cookie value (for non-httpOnly cookies only)
|
|
217
|
+
* @private
|
|
218
|
+
*/
|
|
219
|
+
_setCookie(name, value, options = {}) {
|
|
220
|
+
if (typeof document === 'undefined') return;
|
|
221
|
+
|
|
222
|
+
const opts = { ...this.options, ...options };
|
|
223
|
+
let cookieString = `${name}=${value}`;
|
|
224
|
+
|
|
225
|
+
if (opts.domain) {
|
|
226
|
+
cookieString += `; Domain=${opts.domain}`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (opts.secure) {
|
|
230
|
+
cookieString += '; Secure';
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (opts.sameSite) {
|
|
234
|
+
cookieString += `; SameSite=${opts.sameSite}`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (opts.maxAge) {
|
|
238
|
+
cookieString += `; Max-Age=${opts.maxAge}`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
document.cookie = cookieString;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Delete a cookie
|
|
246
|
+
* @private
|
|
247
|
+
*/
|
|
248
|
+
_deleteCookie(name) {
|
|
249
|
+
this._setCookie(name, '', { maxAge: 0 });
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
getUser() {
|
|
253
|
+
return this.sessionStorage.user || null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
setUser(user) {
|
|
257
|
+
if (user) {
|
|
258
|
+
// Store session data in memory (accessible to JavaScript)
|
|
259
|
+
const { token, ...sessionData } = user;
|
|
260
|
+
this.sessionStorage.user = sessionData;
|
|
261
|
+
|
|
262
|
+
// Tokens are handled by httpOnly cookies set by the server
|
|
263
|
+
// We don't store them in JavaScript for security
|
|
264
|
+
} else {
|
|
265
|
+
this.sessionStorage.user = null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
clearUser() {
|
|
270
|
+
delete this.sessionStorage.user;
|
|
271
|
+
// Note: httpOnly cookies will be cleared by server response
|
|
272
|
+
// But we can clear any non-httpOnly cookies we might have set
|
|
273
|
+
this._deleteCookie('qik_session_id');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
getAccessToken() {
|
|
277
|
+
// In cookie mode, we can't access httpOnly cookies from JavaScript
|
|
278
|
+
// The browser will automatically include them in requests
|
|
279
|
+
// Return null to indicate tokens are handled by cookies
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
getRefreshToken() {
|
|
284
|
+
// Same as access token - handled by httpOnly cookies
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
getTokenExpiry() {
|
|
289
|
+
// We can't read httpOnly cookie expiry from JavaScript
|
|
290
|
+
// The server will handle token expiry validation
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
isAvailable() {
|
|
295
|
+
// Check if we're in a browser environment and cookies are enabled
|
|
296
|
+
if (typeof document === 'undefined') return false;
|
|
297
|
+
|
|
298
|
+
try {
|
|
299
|
+
// Test if we can set/read cookies
|
|
300
|
+
const testCookie = 'qik_test_cookie';
|
|
301
|
+
this._setCookie(testCookie, 'test');
|
|
302
|
+
const canRead = this._getCookie(testCookie) === 'test';
|
|
303
|
+
this._deleteCookie(testCookie);
|
|
304
|
+
return canRead;
|
|
305
|
+
} catch (e) {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Check if we're in cookie mode
|
|
312
|
+
* @returns {Boolean}
|
|
313
|
+
*/
|
|
314
|
+
isCookieMode() {
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get cookie configuration options
|
|
320
|
+
* @returns {Object}
|
|
321
|
+
*/
|
|
322
|
+
getCookieOptions() {
|
|
323
|
+
return { ...this.options };
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Factory function to create appropriate storage adapter
|
|
329
|
+
* @param {Object} options Configuration options
|
|
330
|
+
* @param {Boolean} options.useHttpOnlyCookies Whether to use cookie storage
|
|
331
|
+
* @param {Object} options.cookieConfig Cookie configuration options
|
|
332
|
+
* @returns {StorageAdapter} Storage adapter instance
|
|
333
|
+
*/
|
|
334
|
+
export function createStorageAdapter(options = {}) {
|
|
335
|
+
if (options.useHttpOnlyCookies) {
|
|
336
|
+
const cookieAdapter = new CookieStorageAdapter(options.cookieConfig);
|
|
337
|
+
|
|
338
|
+
// Fallback to localStorage if cookies aren't available
|
|
339
|
+
if (!cookieAdapter.isAvailable()) {
|
|
340
|
+
console.warn('Qik SDK: Cookies not available, falling back to localStorage mode');
|
|
341
|
+
return new LocalStorageAdapter();
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return cookieAdapter;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return new LocalStorageAdapter();
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export { StorageAdapter, LocalStorageAdapter, CookieStorageAdapter };
|
|
351
|
+
</code></pre>
|
|
352
|
+
</article>
|
|
353
|
+
</section>
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
</div>
|
|
361
|
+
|
|
362
|
+
<br class="clear">
|
|
363
|
+
|
|
364
|
+
<footer>
|
|
365
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.11</a> on Mon Jul 13 2026 18:47:22 GMT+1000 (Australian Eastern Standard Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
366
|
+
</footer>
|
|
367
|
+
|
|
368
|
+
<script>prettyPrint();</script>
|
|
369
|
+
<script src="scripts/polyfill.js"></script>
|
|
370
|
+
<script src="scripts/linenumber.js"></script>
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
</body>
|
|
375
|
+
</html>
|