notifications: make update alerts non-persistent
once acked, they remain acked. no need to keep nagging the user about them.
This commit is contained in:
@@ -2556,7 +2556,7 @@ async function autoupdateApps(updateInfo, auditSource) { // updateInfo is { appI
|
|||||||
|
|
||||||
if (!canAutoupdateApp(app, updateInfo[appId])) {
|
if (!canAutoupdateApp(app, updateInfo[appId])) {
|
||||||
debug(`app ${app.fqdn} requires manual update`);
|
debug(`app ${app.fqdn} requires manual update`);
|
||||||
notifications.alert(notifications.ALERT_MANUAL_APP_UPDATE, `${app.manifest.title} at ${app.fqdn} requires manual update to version ${updateInfo[appId].manifest.version}`, `Changelog:\n${updateInfo[appId].manifest.changelog}\n`);
|
notifications.alert(notifications.ALERT_MANUAL_APP_UPDATE, `${app.manifest.title} at ${app.fqdn} requires manual update to version ${updateInfo[appId].manifest.version}`, `Changelog:\n${updateInfo[appId].manifest.changelog}\n`, { persist: false });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,13 +193,13 @@ async function runSystemChecks() {
|
|||||||
|
|
||||||
async function checkMailStatus() {
|
async function checkMailStatus() {
|
||||||
const message = await mail.checkConfiguration();
|
const message = await mail.checkConfiguration();
|
||||||
await notifications.alert(notifications.ALERT_MAIL_STATUS, 'Email is not configured properly', message);
|
await notifications.alert(notifications.ALERT_MAIL_STATUS, 'Email is not configured properly', message, { persist: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkRebootRequired() {
|
async function checkRebootRequired() {
|
||||||
const rebootRequired = await isRebootRequired();
|
const rebootRequired = await isRebootRequired();
|
||||||
if (rebootRequired) {
|
if (rebootRequired) {
|
||||||
await notifications.alert(notifications.ALERT_REBOOT, 'Reboot Required', 'To finish ubuntu security updates, a reboot is necessary.');
|
await notifications.alert(notifications.ALERT_REBOOT, 'Reboot Required', 'To finish ubuntu security updates, a reboot is necessary.', { persist: true });
|
||||||
} else {
|
} else {
|
||||||
await notifications.clearAlert(notifications.ALERT_REBOOT, 'Reboot Required');
|
await notifications.clearAlert(notifications.ALERT_REBOOT, 'Reboot Required');
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ async function checkUbuntuVersion() {
|
|||||||
const isXenial = fs.readFileSync('/etc/lsb-release', 'utf-8').includes('16.04');
|
const isXenial = fs.readFileSync('/etc/lsb-release', 'utf-8').includes('16.04');
|
||||||
if (!isXenial) return;
|
if (!isXenial) return;
|
||||||
|
|
||||||
await notifications.alert(notifications.ALERT_UPDATE_UBUNTU, 'Ubuntu upgrade required', 'Ubuntu 16.04 has reached end of life and will not receive security and maintenance updates. Please follow https://docs.cloudron.io/guides/upgrade-ubuntu-18/ to upgrade to Ubuntu 18 at the earliest.');
|
await notifications.alert(notifications.ALERT_UPDATE_UBUNTU, 'Ubuntu upgrade required', 'Ubuntu 16.04 has reached end of life and will not receive security and maintenance updates. Please follow https://docs.cloudron.io/guides/upgrade-ubuntu-18/ to upgrade to Ubuntu 18 at the earliest.', { persist: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getLogs(unit, options) {
|
async function getLogs(unit, options) {
|
||||||
|
|||||||
@@ -225,17 +225,19 @@ async function backupFailed(eventId, taskId, errorMessage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// id is unused but nice to search code
|
// id is unused but nice to search code
|
||||||
async function alert(id, title, message) {
|
async function alert(id, title, message, options) {
|
||||||
assert.strictEqual(typeof id, 'string');
|
assert.strictEqual(typeof id, 'string');
|
||||||
assert.strictEqual(typeof title, 'string');
|
assert.strictEqual(typeof title, 'string');
|
||||||
assert.strictEqual(typeof message, 'string');
|
assert.strictEqual(typeof message, 'string');
|
||||||
|
assert.strictEqual(typeof options, 'object');
|
||||||
|
|
||||||
const result = await getByTitle(title);
|
const result = await getByTitle(title);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) return await add(title, message, { eventId: null });
|
||||||
return await add(title, message, { eventId: null });
|
if (!options.persist) return result.id;
|
||||||
} else {
|
|
||||||
await update(result, {
|
await update(result, {
|
||||||
|
id: result.id,
|
||||||
eventId: null,
|
eventId: null,
|
||||||
title,
|
title,
|
||||||
message,
|
message,
|
||||||
@@ -243,7 +245,6 @@ async function alert(id, title, message) {
|
|||||||
creationTime: new Date()
|
creationTime: new Date()
|
||||||
});
|
});
|
||||||
return result.id;
|
return result.id;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// id is unused but nice to search code
|
// id is unused but nice to search code
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ describe('Notifications API', function () {
|
|||||||
|
|
||||||
it('can add notifications', async function () {
|
it('can add notifications', async function () {
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const id = await notifications._add(null, `title ${i}`, `message ${i}`);
|
const id = await notifications._add(`title ${i}`, `message ${i}`, { eventId: null });
|
||||||
notificationIds.push(id);
|
notificationIds.push(id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ async function checkDiskSpace() {
|
|||||||
|
|
||||||
if (markdownMessage) markdownMessage = `One or more file systems are running out of space. Please increase the disk size at the earliest.\n\n${markdownMessage}`;
|
if (markdownMessage) markdownMessage = `One or more file systems are running out of space. Please increase the disk size at the earliest.\n\n${markdownMessage}`;
|
||||||
|
|
||||||
await notifications.alert(notifications.ALERT_DISK_SPACE, 'Server is running out of disk space', markdownMessage);
|
await notifications.alert(notifications.ALERT_DISK_SPACE, 'Server is running out of disk space', markdownMessage, { persist: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSwapSize() {
|
async function getSwapSize() {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ describe('Eventlog', function () {
|
|||||||
for (const e of [ eventlog.ACTION_USER_LOGIN, eventlog.ACTION_USER_LOGIN_GHOST, eventlog.ACTION_USER_LOGOUT, eventlog.ACTION_USER_LOGIN ]) {
|
for (const e of [ eventlog.ACTION_USER_LOGIN, eventlog.ACTION_USER_LOGIN_GHOST, eventlog.ACTION_USER_LOGOUT, eventlog.ACTION_USER_LOGIN ]) {
|
||||||
const eventId = await eventlog.add(e, { ip: '1.2.3.4' }, { appId: 'thatapp' });
|
const eventId = await eventlog.add(e, { ip: '1.2.3.4' }, { appId: 'thatapp' });
|
||||||
|
|
||||||
await notifications._add(eventId, 'title', 'some message');
|
await notifications._add('title', 'some message', { eventId });
|
||||||
}
|
}
|
||||||
|
|
||||||
await delay(3000);
|
await delay(3000);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ describe('Notifications', function () {
|
|||||||
|
|
||||||
it('can add notifications', async function () {
|
it('can add notifications', async function () {
|
||||||
for (let i = 0; i < 3; i++) {
|
for (let i = 0; i < 3; i++) {
|
||||||
const [error, id] = await safe(notifications._add(EVENT_0.id, `title ${i}`, `message ${i}`));
|
const [error, id] = await safe(notifications._add(`title ${i}`, `message ${i}`, { eventId: EVENT_0.id }));
|
||||||
expect(error).to.equal(null);
|
expect(error).to.equal(null);
|
||||||
expect(id).to.be.a('string');
|
expect(id).to.be.a('string');
|
||||||
notificationIds.push(id);
|
notificationIds.push(id);
|
||||||
@@ -85,7 +85,7 @@ describe('Notifications', function () {
|
|||||||
|
|
||||||
let alertId;
|
let alertId;
|
||||||
it('can add alert', async function () {
|
it('can add alert', async function () {
|
||||||
alertId = await notifications.alert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available', 'Awesome changelog');
|
alertId = await notifications.alert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available', 'Awesome changelog', { persist: true });
|
||||||
|
|
||||||
const result = await notifications.get(alertId);
|
const result = await notifications.get(alertId);
|
||||||
expect(result.title).to.be('Cloudron xx is available');
|
expect(result.title).to.be('Cloudron xx is available');
|
||||||
@@ -93,10 +93,10 @@ describe('Notifications', function () {
|
|||||||
expect(result.acknowledged).to.be(false);
|
expect(result.acknowledged).to.be(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can update the alert', async function () {
|
it('can update the alert (persist)', async function () {
|
||||||
await notifications.update({ id: alertId }, { acknowledged: true }); // ack the alert
|
await notifications.update({ id: alertId }, { acknowledged: true }); // ack the alert
|
||||||
|
|
||||||
const id = await notifications.alert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available', 'Awesome new changelog');
|
const id = await notifications.alert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available', 'Awesome new changelog', { persist: true });
|
||||||
expect(id).to.be(alertId);
|
expect(id).to.be(alertId);
|
||||||
|
|
||||||
const result = await notifications.get(alertId);
|
const result = await notifications.get(alertId);
|
||||||
@@ -105,6 +105,18 @@ describe('Notifications', function () {
|
|||||||
expect(result.acknowledged).to.be(false); // notification resurfaces
|
expect(result.acknowledged).to.be(false); // notification resurfaces
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can update the alert (non-persist)', async function () {
|
||||||
|
await notifications.update({ id: alertId }, { acknowledged: true }); // ack the alert
|
||||||
|
|
||||||
|
const id = await notifications.alert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available', 'Awesome new changelog', { persist: false });
|
||||||
|
expect(id).to.be(alertId);
|
||||||
|
|
||||||
|
const result = await notifications.get(alertId);
|
||||||
|
expect(result.title).to.be('Cloudron xx is available');
|
||||||
|
expect(result.message).to.be('Awesome new changelog');
|
||||||
|
expect(result.acknowledged).to.be(true); // notification does not resurface
|
||||||
|
});
|
||||||
|
|
||||||
it('can clear the alert', async function () {
|
it('can clear the alert', async function () {
|
||||||
const id = await notifications.clearAlert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available');
|
const id = await notifications.clearAlert(notifications.ALERT_BOX_UPDATE, 'Cloudron xx is available');
|
||||||
expect(id).to.be(null);
|
expect(id).to.be(null);
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ async function checkBoxUpdates(options) {
|
|||||||
const changelog = updateInfo.changelog.map((m) => `* ${m}\n`).join('');
|
const changelog = updateInfo.changelog.map((m) => `* ${m}\n`).join('');
|
||||||
const message = `Changelog:\n${changelog}\n\nGo to the settings view to update.\n\n`;
|
const message = `Changelog:\n${changelog}\n\nGo to the settings view to update.\n\n`;
|
||||||
|
|
||||||
await notifications.alert(notifications.ALERT_BOX_UPDATE, `Cloudron v${updateInfo.version} is available`, message);
|
await notifications.alert(notifications.ALERT_BOX_UPDATE, `Cloudron v${updateInfo.version} is available`, message, { persist: false });
|
||||||
|
|
||||||
state.box = updateInfo;
|
state.box = updateInfo;
|
||||||
setUpdateInfo(state);
|
setUpdateInfo(state);
|
||||||
|
|||||||
Reference in New Issue
Block a user