New support: option to disable notifications and PIN

This commit is contained in:
yflory 2024-02-21 18:52:12 +01:00
parent 06d9201bbd
commit 643e859e7c
3 changed files with 92 additions and 11 deletions

View File

@ -7,12 +7,13 @@ define([
'/common/common-util.js',
'/common/common-hash.js',
'/common/common-realtime.js',
'/common/pinpad.js',
'/components/nthen/index.js',
'/components/chainpad-crypto/crypto.js',
'chainpad-listmap',
'/components/chainpad/chainpad.dist.js',
'chainpad-netflux'
], function (ApiConfig, Util, Hash, Realtime, nThen, Crypto, Listmap, ChainPad, CpNetflux) {
], function (ApiConfig, Util, Hash, Realtime, Pinpad, nThen, Crypto, Listmap, ChainPad, CpNetflux) {
var Support = {};
// UTILS
@ -396,6 +397,7 @@ define([
cb(false);
});
notifyClient(ctx, true, 'NEW_TICKET', data.channel);
if (ctx.adminRpc) { ctx.adminRpc.pin([data.channel], () => {}); }
});
});
};
@ -442,6 +444,43 @@ define([
// INITIALIZE ADMIN
var getPinList = function (ctx) {
if (!ctx.adminDoc || !ctx.adminRpc) { return; }
let adminChan = ctx.adminDoc.metadata && ctx.adminDoc.metadata.channel;
let doc = ctx.adminDoc.proxy;
let t = doc.tickets;
let list = [
adminChan,
...Object.keys(t.active),
...Object.keys(t.pending),
...Object.keys(t.closed)
];
return Util.deduplicateString(list).sort();
};
var initAdminRpc = function (ctx, _cb) {
let cb = Util.mkAsync(_cb);
let Nacl = Crypto.Nacl;
let proxy = ctx.store.proxy;
let curvePrivate = Util.find(proxy, ['mailboxes', 'support2', 'keys', 'curvePrivate']);
if (!curvePrivate) { return void cb('EFORBIDDEN'); }
let edPrivate, edPublic
try {
let pair = Nacl.sign.keyPair.fromSeed(Nacl.util.decodeBase64(curvePrivate));
edPrivate = Nacl.util.encodeBase64(pair.secretKey);
edPublic = Nacl.util.encodeBase64(pair.publicKey);
} catch (e) {
return void cb(e);
}
Pinpad.create(ctx.store.network, {
edPublic: edPublic,
edPrivate: edPrivate
}, (e, call) => {
if (e) { return void cb(e); }
console.log("Support RPC ready, public key is ", edPublic);
ctx.adminRpc = call;
cb();
});
};
var loadAdminDoc = function (ctx, hash, cb) {
var secret = Hash.getSecrets('support', hash);
var listmapConfig = {
@ -467,6 +506,19 @@ define([
doc.tickets.pending = doc.tickets.pending || {};
ctx.adminRdyEvt.fire();
cb();
if (!ctx.adminRpc) { return; }
// Check pin list
let list = getPinList(ctx);
let local = Hash.hashChannelList(list);
ctx.adminRpc.getServerHash(function (e, hash) {
if (e) { return void console.warn(e); }
if (hash !== local) {
ctx.adminRpc.reset(list, function (e, hash) {
if (e) { console.warn(e); }
});
}
});
});
};
@ -487,6 +539,10 @@ define([
return void waitFor.abort();
}
}));
}).nThen((waitFor) => {
initAdminRpc(ctx, waitFor((err) => {
if (err) { console.error('Support RPC not ready', err); }
}));
}).nThen((waitFor) => {
let seed = privateKey.slice(0,24); // XXX better way to get seed?
let hash = Hash.getEditHashFromKeys({

View File

@ -53,7 +53,10 @@ define([
Messages.support_pendingListHint = "List of tickets that may not be updated for a while but should not be closed";
Messages.support_privacyTitle = "Answer anonymously";
Messages.support_privacyHint = "Check this option to reply as 'The Support Team' instead of your own usenrame";
Messages.support_privacyHint = "Check this option to reply as 'The Support Team' instead of your own username";
Messages.support_notificationsTitle = "Disable notifications";
Messages.support_notificationsHint = "Check this option to disable notifications on new or updated ticket";
var andThen = function (common, $container, linkedTicket) {
const sidebar = Sidebar.create(common, 'support', $container);
@ -193,11 +196,13 @@ define([
let activeContainer, pendingContainer, closedContainer;
var refreshAll = function () {
console.error('refresh');
refresh($(activeContainer), 'active');
refresh($(pendingContainer), 'pending');
refresh($(closedContainer), 'closed');
};
let _refresh = Util.throttle(refreshAll, 500);
events.NEW_TICKET.reg(_refresh);
events.UPDATE_TICKET.reg(_refresh);
// Make sidebar layout
const categories = {
@ -215,9 +220,15 @@ define([
'closed-list'
]
},
'settings': {
icon: undefined,
content: [
'notifications'
]
},
'refresh': {
icon: undefined,
action: refreshAll
onClick: refreshAll
}
};
@ -242,13 +253,20 @@ define([
let div = closedContainer = h('div.cp-support-container'); // XXX block
cb(div);
}, { noTitle: true, noHint: true });
let _refresh = Util.throttle(refreshAll, 500);
events.NEW_TICKET.reg(_refresh);
events.UPDATE_TICKET.reg(_refresh);
refreshAll();
sidebar.addCheckboxItem({
key: 'notifications',
getState: () => APP.disableSupportNotif,
query: (val, setState) => {
common.setAttribute(['general', 'disableSupportNotif'], val, function (err) {
if (err) { val = APP.disableSupportNotif; }
APP.disableSupportNotif = val;
setState(val);
});
}
});
sidebar.makeLeftside(categories);
};
@ -273,6 +291,10 @@ define([
APP.$toolbar = $('#cp-toolbar');
sframeChan = common.getSframeChannel();
sframeChan.onReady(waitFor());
}).nThen(function (waitFor) {
common.getAttribute(['general', 'disableSupportNotif'], waitFor(function (err, value) {
APP.disableSupportNotif = !!value;
}));
}).nThen(function (/*waitFor*/) {
createToolbar();
var metadataMgr = common.getMetadataMgr();

View File

@ -171,7 +171,8 @@ define([
$(button).click(cb);
}
var cancel = title ? h('button.btn.btn-secondary', Messages.cancel) : undefined;
var cancel = title ? h('button.btn.btn-secondary.cp-support-reply-cancel', Messages.cancel)
: undefined;
var category = h('input.cp-support-form-category', {
type: 'hidden',
@ -318,6 +319,7 @@ define([
var adminActions;
var adminClasses = '';
var adminOpen;
var ticket;
if (ctx.isAdmin) {
// Admin custom style
adminClasses = `.cp-not-loaded`;
@ -345,6 +347,7 @@ define([
$ticket.toggleClass('cp-not-loaded', true);
return onHide(ticket, id, content, function () {
visible = false;
$(ticket).find('.cp-support-reply-cancel').click();
$show.text(Messages.admin_support_open);
$show.prop('disabled', '');
});
@ -362,7 +365,7 @@ define([
let isPremium = content.premium ? '.cp-support-ispremium' : '';
var name = Util.fixHTML(content.author) || Messages.anonymous;
var ticket = h(`div.cp-support-list-ticket${adminClasses}`, {
ticket = h(`div.cp-support-list-ticket${adminClasses}`, {
'data-id': id
}, [
h('div.cp-support-ticket-header', [