Source: service/storage/EnableNowStorage.js

(function() {
    /**
     * @augments Help4.service.StorageService.StorageInterface
     * @property {string} _storageScope
     * @property {string} _storageKey
     * @property {string} _xcsrfId
     * @property {string} _url
     */
    Help4.service.StorageService.EnableNowStorage = class extends Help4.service.StorageService.StorageInterface {
        /**
         * @override
         * @constructor
         */
        constructor() {
            const {STORAGE_LEVEL: {manual}} = Help4.service.StorageService;
            super({
                statics: {
                    _storageScope: {init: 'web_assistant', destroy: false},
                    _storageKey:   {init: 'storage', destroy: false},
                    _xcsrfId:      {init: Help4.createId(), destroy: false},
                    _url:          {init: null, destroy: false}
                }
            });
        }

        /**
         * @override
         * @param {Object} config
         * @param {string} config.serviceLayer
         * @param {string} config.serviceUrl
         * @param {string} config.serviceUrl2
         * @returns {Promise<void>}
         */
        async config({serviceLayer, serviceUrl, serviceUrl2}) {
            let url = {'wpb': serviceUrl, 'ext': serviceUrl2}[serviceLayer] || null;
            if (!url) {
                this._url = null;
                this._isReady = true;
                return;
            }

            const {_xcsrfId, _storageScope} = this;
            url = url.replace(/\/(wa|pub)\/.*$/, '') + '/self';
            Help4.ajax.Ajax.setXCSRF({id: _xcsrfId, url});
            this._url = `${url}/setting/${_storageScope}`;

            const available = await this._test();
            this.dataFunctions.set({available}, {allowReadonlyOverride: true});  // this.available is readonly; allow override
            this._isReady = true;
        }

        /**
         * @override
         * @param {?string} [key = null]
         * @returns {Promise<*>}
         */
        get(key = null) {
            return new Help4.Promise(resolve => {
                const {_url, _xcsrfId, _storageKey} = this;

                const success = data => {
                    data = data?.response?.setting || [];

                    for (const {label, value} of data) {
                        if (label === _storageKey) {
                            try {
                                const d = Help4.JSON.parse(value);
                                return resolve(key ? d[key] : d);
                            } catch(e) {
                            }
                        }
                    }

                    resolve();
                }

                Help4.ajax.Ajax({
                    headers: {'Cache-Control': 'no-cache, max-age=0'},
                    url: _url,
                    saml: true,
                    xcsrf: _xcsrfId,
                    success,
                    error: resolve
                });
            });
        }

        /**
         * @override
         * @param {string} key
         * @param {string} value
         * @returns {Promise<boolean>}
         */
        async set(key, value) {
            const payload = await this.get() || {};
            if (payload[key] !== value) {
                payload[key] = value;
                return await _saveNewPayload.call(this, payload);
            }
            return true;
        }

        /**
         * @override
         * @param {string} key
         * @returns {Promise<boolean>}
         */
        async del(key) {
            const payload = await this.get() || {};
            if (payload.hasOwnProperty(key)) {
                delete payload[key];
                return _saveNewPayload.call(this, payload);
            }
            return true;
        }
    }

    /**
     * @memberof Help4.service.StorageService.EnableNowStorage#
     * @private
     * @param {Object} payload
     * @returns {Promise<boolean>}
     */
    function _saveNewPayload(payload) {
        const {_url, _xcsrfId, _storageScope, _storageKey} = this;

        const data = {scope: _storageScope};
        data[_storageKey] = Help4.JSON.stringify(payload);

        return new Help4.Promise(resolve => {
            Help4.ajax.Ajax({
                method: 'POST',
                url: _url,
                data,
                saml: true,
                xcsrf: _xcsrfId,
                success: () => resolve(true),
                error: () => resolve(false)
            });
        });
    }
})();