From b5ef5126c6d0bf6e8909b767b45399c2113a9371 Mon Sep 17 00:00:00 2001 From: nathangray Date: Tue, 22 Sep 2020 13:53:08 -0600 Subject: [PATCH] - Send push messages for account delete - Send actual push type for contact changes - Handle push deletes for admin --- admin/js/app.js | 29 +++++++++++++++++++++++++++++ admin/js/app.ts | 35 ++++++++++++++++++++++++++++++++++- api/src/Accounts.php | 7 +++++++ api/src/Contacts.php | 11 ++++++++--- 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/admin/js/app.js b/admin/js/app.js index 3f39b6e2c3..83771601b5 100644 --- a/admin/js/app.js +++ b/admin/js/app.js @@ -296,6 +296,35 @@ var AdminApp = /** @class */ (function (_super) { } } }; + /** + * Handle a push notification about entry changes from the websocket + * + * Get's called for data of all apps, but should only handle data of apps it displays, + * which is by default only it's own, but can be for multiple apps eg. for calendar. + * + * @param pushData + * @param {string} pushData.app application name + * @param {(string|number)} pushData.id id of entry to refresh or null + * @param {string} pushData.type either 'update', 'edit', 'delete', 'add' or null + * - update: request just modified data from given rows. Sorting is not considered, + * so if the sort field is changed, the row will not be moved. + * - edit: rows changed, but sorting may be affected. Requires full reload. + * - delete: just delete the given rows clientside (no server interaction neccessary) + * - add: requires full reload for proper sorting + * @param {object|null} pushData.acl Extra data for determining relevance. eg: owner or responsible to decide if update is necessary + * @param {number} pushData.account_id User that caused the notification + */ + AdminApp.prototype.push = function (pushData) { + // We'll listen to addressbook, but only if it has an account ID + if (pushData.app != this.appname) + return; + if (pushData.id > 0) { + this.nm.refresh(pushData.id, pushData.type); + } + else if (pushData.id < 0) { + this.groups.refresh(pushData.id, pushData.type); + } + }; /** * Hide navbar for idots template * diff --git a/admin/js/app.ts b/admin/js/app.ts index f968e5b11d..faebfc1659 100644 --- a/admin/js/app.ts +++ b/admin/js/app.ts @@ -17,7 +17,7 @@ import 'jqueryui'; import '../jsapi/egw_global'; import '../etemplate/et2_types'; -import {EgwApp} from '../../api/js/jsapi/egw_app'; +import {EgwApp, PushData} from '../../api/js/jsapi/egw_app'; /** * UI for Admin @@ -315,6 +315,39 @@ class AdminApp extends EgwApp } } + /** + * Handle a push notification about entry changes from the websocket + * + * Get's called for data of all apps, but should only handle data of apps it displays, + * which is by default only it's own, but can be for multiple apps eg. for calendar. + * + * @param pushData + * @param {string} pushData.app application name + * @param {(string|number)} pushData.id id of entry to refresh or null + * @param {string} pushData.type either 'update', 'edit', 'delete', 'add' or null + * - update: request just modified data from given rows. Sorting is not considered, + * so if the sort field is changed, the row will not be moved. + * - edit: rows changed, but sorting may be affected. Requires full reload. + * - delete: just delete the given rows clientside (no server interaction neccessary) + * - add: requires full reload for proper sorting + * @param {object|null} pushData.acl Extra data for determining relevance. eg: owner or responsible to decide if update is necessary + * @param {number} pushData.account_id User that caused the notification + */ + push(pushData : PushData) + { + // We'll listen to addressbook, but only if it has an account ID + if (pushData.app != this.appname) return; + + if(pushData.id > 0) + { + this.nm.refresh(pushData.id, pushData.type); + } + else if (pushData.id < 0) + { + this.groups.refresh(pushData.id, pushData.type); + } + } + /** * Hide navbar for idots template * diff --git a/api/src/Accounts.php b/api/src/Accounts.php index 1bc98ea34a..faeb84e2f0 100644 --- a/api/src/Accounts.php +++ b/api/src/Accounts.php @@ -653,6 +653,7 @@ class Accounts } } } + $update_type = "update"; // add default description for Admins and Default group if ($data['account_type'] === 'g' && empty($data['account_description'])) { @@ -696,6 +697,9 @@ class Accounts $invalidate[] = $data['account_id']; self::cache_invalidate($invalidate); + // Notify linked apps about changes in the account data + Link::notify_update('admin', $id, $data, $update_type); + return $id; } @@ -733,6 +737,9 @@ class Accounts // delete all categories belonging to that user or group Categories::delete_account($id); + // Notify linked apps about changes in the account data + Link::notify_update('admin', $id, null, 'delete'); + return true; } diff --git a/api/src/Contacts.php b/api/src/Contacts.php index 7918e1a8c0..6b47c60c62 100755 --- a/api/src/Contacts.php +++ b/api/src/Contacts.php @@ -864,6 +864,8 @@ class Contacts extends Contacts\Storage */ function save(&$contact, $ignore_acl=false, $touch_modified=true) { + $update_type = "update"; + // Make sure photo remains unchanged unless its purposely set to be false // which means photo has changed. if (!array_key_exists('photo_unchanged',$contact)) $contact['photo_unchanged'] = true; @@ -887,6 +889,7 @@ class Contacts extends Contacts\Storage else // entry not found --> create a new one { $isUpdate = $contact['id'] = null; + $update_type = "add"; } } } @@ -905,6 +908,7 @@ class Contacts extends Contacts\Storage if (!$contact['created'] || !$ignore_acl && !$this->is_admin($contact)) $contact['created'] = $this->now_su; if (!$contact['tid']) $contact['tid'] = 'n'; + $update_type = "add"; } // ensure accounts and group addressbooks are never private! if ($contact['owner'] <= 0) @@ -1032,8 +1036,6 @@ class Contacts extends Contacts\Storage $to_write['location'] = 'editaccountcontact'; Hooks::process($to_write,False,True); // called for every app now, not only enabled ones)); } - // Notify linked apps about changes in the contact data - Link::notify_update('addressbook', $contact['id'], $contact); // Check for restore of deleted contact, restore held links if($old && $old['tid'] == self::DELETED_TYPE && $contact['tid'] != self::DELETED_TYPE) @@ -1042,13 +1044,16 @@ class Contacts extends Contacts\Storage } // Record change history for sql - doesn't work for LDAP accounts + $deleted = ($old['tid'] == self::DELETED_TYPE || $contact['tid'] == self::DELETED_TYPE); if(!$contact['account_id'] || $contact['account_id'] && $this->account_repository == 'sql') { - $deleted = ($old['tid'] == self::DELETED_TYPE || $contact['tid'] == self::DELETED_TYPE); if (!isset($this->tracking)) $this->tracking = new Contacts\Tracking($this); $this->tracking->track($to_write, $old ? $old : null, null, $deleted); } + // Notify linked apps about changes in the contact data + Link::notify_update('addressbook', $contact['id'], $contact, $deleted ? 'delete' : $update_type); + // Expire birthday cache for this year and next if birthday changed if($isUpdate && $old['bday'] !== $to_write['bday'] || !$isUpdate && $to_write['bday']) {