mirror of
https://github.com/documize/community.git
synced 2025-07-19 13:19:43 +02:00
event logging
This commit is contained in:
parent
b6c676149a
commit
93ed361705
48 changed files with 861 additions and 853 deletions
|
@ -8,7 +8,7 @@ The mission is to bring software dev inspired features (refactoring, testing, li
|
||||||
|
|
||||||
## Latest version
|
## Latest version
|
||||||
|
|
||||||
v1.46.2
|
v1.47.0
|
||||||
|
|
||||||
## OS Support
|
## OS Support
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ module.exports = {
|
||||||
"stubUserNotification": true,
|
"stubUserNotification": true,
|
||||||
"userLogin": true,
|
"userLogin": true,
|
||||||
"Keycloak": true,
|
"Keycloak": true,
|
||||||
"Intercom": true,
|
|
||||||
"slug": true
|
"slug": true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -251,8 +251,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
meta: meta
|
meta: meta
|
||||||
};
|
};
|
||||||
|
|
||||||
this.audit.record("added-section-" + section.get('contentType'));
|
|
||||||
|
|
||||||
const promise = this.addSection(model);
|
const promise = this.addSection(model);
|
||||||
promise.then((id) => {
|
promise.then((id) => {
|
||||||
this.set('pageId', id);
|
this.set('pageId', id);
|
||||||
|
@ -297,8 +295,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
meta: meta
|
meta: meta
|
||||||
};
|
};
|
||||||
|
|
||||||
this.audit.record("added-content-block-" + block.get('contentType'));
|
|
||||||
|
|
||||||
const promise = this.addSection(model);
|
const promise = this.addSection(model);
|
||||||
promise.then((id) => {
|
promise.then((id) => {
|
||||||
this.set('pageId', id);
|
this.set('pageId', id);
|
||||||
|
|
|
@ -65,7 +65,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on("addedfile", function ( /*file*/ ) {
|
this.on("addedfile", function ( /*file*/ ) {
|
||||||
self.audit.record('attached-file');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -101,7 +101,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.attrs.onPageSequenceChange(pendingChanges);
|
this.attrs.onPageSequenceChange(pendingChanges);
|
||||||
|
|
||||||
this.send('onEntryClick', this.get('currentPageId'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
this.audit.record("moved-page-up");
|
|
||||||
this.showNotification("Moved up");
|
this.showNotification("Moved up");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -121,7 +120,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.attrs.onPageSequenceChange(pendingChanges);
|
this.attrs.onPageSequenceChange(pendingChanges);
|
||||||
|
|
||||||
this.send('onEntryClick', this.get('currentPageId'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
this.audit.record("moved-page-down");
|
|
||||||
this.showNotification("Moved down");
|
this.showNotification("Moved down");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -141,7 +139,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.attrs.onPageLevelChange(pendingChanges);
|
this.attrs.onPageLevelChange(pendingChanges);
|
||||||
|
|
||||||
this.showNotification("Indent");
|
this.showNotification("Indent");
|
||||||
this.audit.record("changed-page-sequence");
|
|
||||||
this.send('onEntryClick', this.get('currentPageId'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -161,7 +158,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.attrs.onPageLevelChange(pendingChanges);
|
this.attrs.onPageLevelChange(pendingChanges);
|
||||||
|
|
||||||
this.showNotification("Outdent");
|
this.showNotification("Outdent");
|
||||||
this.audit.record("changed-page-sequence");
|
|
||||||
this.send('onEntryClick', this.get('currentPageId'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -72,7 +72,6 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
onPrintDocument() {
|
onPrintDocument() {
|
||||||
this.audit.record('printed-document');
|
|
||||||
$("#sidebar-zone-more-button").click();
|
$("#sidebar-zone-more-button").click();
|
||||||
window.print();
|
window.print();
|
||||||
},
|
},
|
||||||
|
@ -90,8 +89,6 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnpin() {
|
onUnpin() {
|
||||||
this.audit.record('unpinned-document');
|
|
||||||
|
|
||||||
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
||||||
this.set('pinState.isPinned', false);
|
this.set('pinState.isPinned', false);
|
||||||
this.set('pinState.pinId', '');
|
this.set('pinState.pinId', '');
|
||||||
|
@ -111,8 +108,6 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.audit.record('pinned-document');
|
|
||||||
|
|
||||||
this.get('pinned').pinItem(pin).then((pin) => {
|
this.get('pinned').pinItem(pin).then((pin) => {
|
||||||
this.set('pinState.isPinned', true);
|
this.set('pinState.isPinned', true);
|
||||||
this.set('pinState.pinId', pin.get('id'));
|
this.set('pinState.pinId', pin.get('id'));
|
||||||
|
|
|
@ -84,8 +84,6 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
this.get('onChange')(save);
|
this.get('onChange')(save);
|
||||||
|
|
||||||
this.audit.record('added-tag');
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -106,7 +104,6 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
this.set('tagz', tags);
|
this.set('tagz', tags);
|
||||||
this.get('onChange')(save);
|
this.get('onChange')(save);
|
||||||
this.audit.record('removed tag');
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,7 +22,6 @@ export default Ember.Component.extend({
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.audit.record('viewed-space');
|
|
||||||
this.set('selectedDocuments', []);
|
this.set('selectedDocuments', []);
|
||||||
this.set('canCreate', this.get('folderService').get('canEditCurrentFolder'));
|
this.set('canCreate', this.get('folderService').get('canEditCurrentFolder'));
|
||||||
this.set('deleteTargets', this.get('folders').rejectBy('id', this.get('folder.id')));
|
this.set('deleteTargets', this.get('folders').rejectBy('id', this.get('folder.id')));
|
||||||
|
|
|
@ -70,8 +70,6 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnpin() {
|
onUnpin() {
|
||||||
this.audit.record('unpinned-space');
|
|
||||||
|
|
||||||
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
||||||
this.set('pinState.isPinned', false);
|
this.set('pinState.isPinned', false);
|
||||||
this.set('pinState.pinId', '');
|
this.set('pinState.pinId', '');
|
||||||
|
@ -91,8 +89,6 @@ export default Ember.Component.extend(TooltipMixin, NotifierMixin, AuthMixin, {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.audit.record('pinned-space');
|
|
||||||
|
|
||||||
this.get('pinned').pinItem(pin).then((pin) => {
|
this.get('pinned').pinItem(pin).then((pin) => {
|
||||||
this.set('pinState.isPinned', true);
|
this.set('pinState.isPinned', true);
|
||||||
this.set('pinState.pinId', pin.get('id'));
|
this.set('pinState.pinId', pin.get('id'));
|
||||||
|
|
|
@ -95,7 +95,6 @@ export default Ember.Component.extend(NotifierMixin, {
|
||||||
|
|
||||||
this.on("addedfile", function (file) {
|
this.on("addedfile", function (file) {
|
||||||
self.send('onDocumentImporting', file.name);
|
self.send('onDocumentImporting', file.name);
|
||||||
self.audit.record('converted-document');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -113,14 +112,12 @@ export default Ember.Component.extend(NotifierMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
editTemplate(template) {
|
editTemplate(template) {
|
||||||
this.audit.record('edited-saved-template');
|
|
||||||
this.get('router').transitionTo('document', this.get('folder.id'), this.get('folder.slug'), template.get('id'), template.get('slug'));
|
this.get('router').transitionTo('document', this.get('folder.id'), this.get('folder.slug'), template.get('id'), template.get('slug'));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
startDocument(template) {
|
startDocument(template) {
|
||||||
this.audit.record('used-saved-template');
|
|
||||||
this.send("showNotification", "Creating");
|
this.send("showNotification", "Creating");
|
||||||
|
|
||||||
this.get('templateService').importSavedTemplate(this.folder.get('id'), template.id, this.get('newDocumentName')).then((document) => {
|
this.get('templateService').importSavedTemplate(this.folder.get('id'), template.id, this.get('newDocumentName')).then((document) => {
|
||||||
|
|
|
@ -80,8 +80,6 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
var sortable = Sortable.create(document.getElementById('pinned-zone'), {
|
var sortable = Sortable.create(document.getElementById('pinned-zone'), {
|
||||||
animation: 150,
|
animation: 150,
|
||||||
onEnd: function () {
|
onEnd: function () {
|
||||||
self.audit.record('reorganized-pins');
|
|
||||||
|
|
||||||
self.get('pinned').updateSequence(this.toArray()).then((pins) => {
|
self.get('pinned').updateSequence(this.toArray()).then((pins) => {
|
||||||
self.set('pins', pins);
|
self.set('pins', pins);
|
||||||
});
|
});
|
||||||
|
@ -144,7 +142,6 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
switchAccount(domain) {
|
switchAccount(domain) {
|
||||||
this.audit.record('switched-account');
|
|
||||||
window.location.href = netUtil.getAppUrl(domain);
|
window.location.href = netUtil.getAppUrl(domain);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software (Documize Community Edition) is licensed under
|
|
||||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
|
||||||
//
|
|
||||||
// You can operate outside the AGPL restrictions by purchasing
|
|
||||||
// Documize Enterprise Edition and obtaining a commercial license
|
|
||||||
// by contacting <sales@documize.com>.
|
|
||||||
//
|
|
||||||
// https://documize.com
|
|
||||||
|
|
||||||
export function initialize(application) {
|
|
||||||
application.inject('route', 'audit', 'service:audit');
|
|
||||||
application.inject('controller', 'audit', 'service:audit');
|
|
||||||
application.inject('component', 'audit', 'service:audit');
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'audit',
|
|
||||||
after: 'session',
|
|
||||||
initialize: initialize
|
|
||||||
};
|
|
|
@ -19,6 +19,5 @@ export function initialize(application) {
|
||||||
export default {
|
export default {
|
||||||
name: 'session',
|
name: 'session',
|
||||||
after: 'application',
|
after: 'application',
|
||||||
before: 'audit',
|
|
||||||
initialize: initialize
|
initialize: initialize
|
||||||
};
|
};
|
|
@ -36,7 +36,6 @@ export default Ember.Route.extend({
|
||||||
let data = this.get('kcAuth').mapProfile(profile);
|
let data = this.get('kcAuth').mapProfile(profile);
|
||||||
|
|
||||||
this.get("session").authenticate('authenticator:keycloak', data).then(() => {
|
this.get("session").authenticate('authenticator:keycloak', data).then(() => {
|
||||||
this.get('audit').record("logged-in-keycloak");
|
|
||||||
this.transitionTo('folders');
|
this.transitionTo('folders');
|
||||||
}, (reject) => {
|
}, (reject) => {
|
||||||
this.set('message', reject.Error);
|
this.set('message', reject.Error);
|
||||||
|
|
|
@ -15,7 +15,6 @@ import AuthProvider from '../../../mixins/auth';
|
||||||
export default Ember.Controller.extend(AuthProvider, {
|
export default Ember.Controller.extend(AuthProvider, {
|
||||||
appMeta: Ember.inject.service('app-meta'),
|
appMeta: Ember.inject.service('app-meta'),
|
||||||
session: Ember.inject.service('session'),
|
session: Ember.inject.service('session'),
|
||||||
audit: Ember.inject.service('audit'),
|
|
||||||
invalidCredentials: false,
|
invalidCredentials: false,
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
|
@ -35,7 +34,6 @@ export default Ember.Controller.extend(AuthProvider, {
|
||||||
let creds = this.getProperties('email', 'password');
|
let creds = this.getProperties('email', 'password');
|
||||||
|
|
||||||
this.get('session').authenticate('authenticator:documize', creds).then((response) => {
|
this.get('session').authenticate('authenticator:documize', creds).then((response) => {
|
||||||
this.get('audit').record("logged-in");
|
|
||||||
this.transitionToRoute('folders');
|
this.transitionToRoute('folders');
|
||||||
return response;
|
return response;
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
|
|
|
@ -17,9 +17,6 @@ export default Ember.Route.extend({
|
||||||
appMeta: Ember.inject.service(),
|
appMeta: Ember.inject.service(),
|
||||||
|
|
||||||
activate: function () {
|
activate: function () {
|
||||||
this.audit.record("logged-out");
|
|
||||||
this.audit.stop();
|
|
||||||
|
|
||||||
this.get('session').invalidate().then(() => {
|
this.get('session').invalidate().then(() => {
|
||||||
if (config.environment === 'test') {
|
if (config.environment === 'test') {
|
||||||
this.transitionTo('auth.login');
|
this.transitionTo('auth.login');
|
||||||
|
|
|
@ -32,7 +32,6 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
|
|
||||||
this.get('folderService').save(folder).then(() => {
|
this.get('folderService').save(folder).then(() => {
|
||||||
this.showNotification("Changed");
|
this.showNotification("Changed");
|
||||||
this.audit.record('changed-folder-owner');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.send('onChangeOwner');
|
this.send('onChangeOwner');
|
||||||
|
|
|
@ -31,7 +31,6 @@ export default Ember.Controller.extend({
|
||||||
b.set('externalSource', meta.get('externalSource'));
|
b.set('externalSource', meta.get('externalSource'));
|
||||||
|
|
||||||
this.get('sectionService').updateBlock(b).then(function () {
|
this.get('sectionService').updateBlock(b).then(function () {
|
||||||
self.audit.record("edited-block");
|
|
||||||
self.transitionToRoute('document');
|
self.transitionToRoute('document');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,6 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
model(params) {
|
model(params) {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
this.audit.record("edited-block");
|
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folder: self.modelFor('document').folder,
|
folder: self.modelFor('document').folder,
|
||||||
document: self.modelFor('document').document,
|
document: self.modelFor('document').document,
|
||||||
|
|
|
@ -6,16 +6,12 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onFetchDiff(pageId, revisionId) {
|
onFetchDiff(pageId, revisionId) {
|
||||||
this.audit.record("compared-diff");
|
|
||||||
|
|
||||||
this.get('documentService').getPageRevisionDiff(this.get('model.document.id'), pageId, revisionId).then((revision) => {
|
this.get('documentService').getPageRevisionDiff(this.get('model.document.id'), pageId, revisionId).then((revision) => {
|
||||||
this.set('model.diff', revision);
|
this.set('model.diff', revision);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onRollback(pageId, revisionId) {
|
onRollback(pageId, revisionId) {
|
||||||
this.audit.record("restored-page");
|
|
||||||
|
|
||||||
this.get('documentService').rollbackPage(this.get('model.document.id'), pageId, revisionId).then(() => {
|
this.get('documentService').rollbackPage(this.get('model.document.id'), pageId, revisionId).then(() => {
|
||||||
this.transitionToRoute('document.index',
|
this.transitionToRoute('document.index',
|
||||||
this.get('model.folder.id'),
|
this.get('model.folder.id'),
|
||||||
|
|
|
@ -66,8 +66,6 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
page = up;
|
page = up;
|
||||||
this.set('pageId', page.get('id'));
|
this.set('pageId', page.get('id'));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.audit.record("edited-page");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onPageDeleted(deletePage) {
|
onPageDeleted(deletePage) {
|
||||||
|
@ -81,8 +79,6 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
let pageIndex = _.indexOf(pages, page, false);
|
let pageIndex = _.indexOf(pages, page, false);
|
||||||
let pendingChanges = [];
|
let pendingChanges = [];
|
||||||
|
|
||||||
this.audit.record("deleted-page");
|
|
||||||
|
|
||||||
// select affected pages
|
// select affected pages
|
||||||
for (var i = pageIndex + 1; i < pages.get('length'); i++) {
|
for (var i = pageIndex + 1; i < pages.get('length'); i++) {
|
||||||
if (pages[i].get('level') <= page.get('level')) {
|
if (pages[i].get('level') <= page.get('level')) {
|
||||||
|
@ -155,7 +151,6 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
onDeleteBlock(blockId) {
|
onDeleteBlock(blockId) {
|
||||||
return new Ember.RSVP.Promise((resolve) => {
|
return new Ember.RSVP.Promise((resolve) => {
|
||||||
this.get('sectionService').deleteBlock(blockId).then(() => {
|
this.get('sectionService').deleteBlock(blockId).then(() => {
|
||||||
this.audit.record("deleted-block");
|
|
||||||
this.send("showNotification", "Deleted");
|
this.send("showNotification", "Deleted");
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
@ -173,7 +168,6 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
|
|
||||||
onDocumentDelete() {
|
onDocumentDelete() {
|
||||||
this.get('documentService').deleteDocument(this.get('model.document.id')).then(() => {
|
this.get('documentService').deleteDocument(this.get('model.document.id')).then(() => {
|
||||||
this.audit.record("deleted-page");
|
|
||||||
this.send("showNotification", "Deleted");
|
this.send("showNotification", "Deleted");
|
||||||
this.transitionToRoute('folder', this.get('model.folder.id'), this.get('model.folder.slug'));
|
this.transitionToRoute('folder', this.get('model.folder.id'), this.get('model.folder.slug'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -44,8 +44,6 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
this.audit.record('viewed-document');
|
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folders: this.get('folders'),
|
folders: this.get('folders'),
|
||||||
folder: this.get('folder'),
|
folder: this.get('folder'),
|
||||||
|
|
|
@ -34,7 +34,6 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.get('documentService').updatePage(page.get('documentId'), page.get('id'), model).then((page) => {
|
this.get('documentService').updatePage(page.get('documentId'), page.get('id'), model).then((page) => {
|
||||||
this.audit.record("edited-page");
|
|
||||||
let data = this.get('store').normalize('page', page);
|
let data = this.get('store').normalize('page', page);
|
||||||
this.get('store').push(data);
|
this.get('store').push(data);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ export default Ember.Controller.extend({
|
||||||
}.observes('filter'),
|
}.observes('filter'),
|
||||||
|
|
||||||
fetch() {
|
fetch() {
|
||||||
this.audit.record('searched');
|
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
this.get('searchService').find(this.get('filter')).then(function (response) {
|
this.get('searchService').find(this.get('filter')).then(function (response) {
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software (Documize Community Edition) is licensed under
|
|
||||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
|
||||||
//
|
|
||||||
// You can operate outside the AGPL restrictions by purchasing
|
|
||||||
// Documize Enterprise Edition and obtaining a commercial license
|
|
||||||
// by contacting <sales@documize.com>.
|
|
||||||
//
|
|
||||||
// https://documize.com
|
|
||||||
|
|
||||||
import Ember from 'ember';
|
|
||||||
import netUtil from '../utils/net';
|
|
||||||
import config from '../config/environment';
|
|
||||||
|
|
||||||
const {
|
|
||||||
inject: { service }
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Ember.Service.extend({
|
|
||||||
session: service('session'),
|
|
||||||
appMeta: service(),
|
|
||||||
ready: false,
|
|
||||||
enabled: config.APP.auditEnabled,
|
|
||||||
appId: config.APP.intercomKey,
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.start();
|
|
||||||
},
|
|
||||||
|
|
||||||
record(id) {
|
|
||||||
if (!this.get('enabled') || this.get('appId').length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.get('ready')) {
|
|
||||||
this.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
Intercom('trackEvent', id); //jshint ignore: line
|
|
||||||
Intercom('update'); //jshint ignore: line
|
|
||||||
},
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
if (!this.get('enabled') || this.get('appId').length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Intercom('shutdown'); //jshint ignore: line
|
|
||||||
},
|
|
||||||
|
|
||||||
start() {
|
|
||||||
let self = this;
|
|
||||||
let user = this.get('session.user');
|
|
||||||
|
|
||||||
if (is.undefined(user) || this.get('appId') === "" || !this.get('enabled') || !this.get('session.authenticated') || this.get('ready')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.set('ready', true);
|
|
||||||
|
|
||||||
window.intercomSettings = {
|
|
||||||
app_id: this.get('appId'),
|
|
||||||
name: user.get('fullname'),
|
|
||||||
email: user.get('email'),
|
|
||||||
user_id: user.get('id'),
|
|
||||||
"administrator": user.get('admin'),
|
|
||||||
company: {
|
|
||||||
id: self.get('appMeta.orgId'),
|
|
||||||
name: self.get('appMeta.title'),
|
|
||||||
"domain": netUtil.getSubdomain(),
|
|
||||||
"version": self.get('appMeta.version')
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!this.get('session.isMobile')) {
|
|
||||||
// uncomment these lines if you want to use Intercom messenger within Documize
|
|
||||||
// window.intercomSettings.widget = {
|
|
||||||
// activator: "#IntercomDefaultWidget"
|
|
||||||
// };
|
|
||||||
}
|
|
||||||
|
|
||||||
window.Intercom('boot', window.intercomSettings);
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -18,7 +18,6 @@ const {
|
||||||
|
|
||||||
export default Ember.Service.extend({
|
export default Ember.Service.extend({
|
||||||
sessionService: service('session'),
|
sessionService: service('session'),
|
||||||
audit: service(),
|
|
||||||
ajax: service(),
|
ajax: service(),
|
||||||
appMeta: service(),
|
appMeta: service(),
|
||||||
keycloak: null,
|
keycloak: null,
|
||||||
|
@ -43,7 +42,6 @@ export default Ember.Service.extend({
|
||||||
// };
|
// };
|
||||||
|
|
||||||
this.get('keycloak').init().success(() => {
|
this.get('keycloak').init().success(() => {
|
||||||
this.get('audit').record("initialized-keycloak");
|
|
||||||
resolve(this.get('keycloak'));
|
resolve(this.get('keycloak'));
|
||||||
}).error((err) => {
|
}).error((err) => {
|
||||||
reject(err);
|
reject(err);
|
||||||
|
|
|
@ -36,9 +36,6 @@ module.exports = function (environment) {
|
||||||
routeIfAlreadyAuthenticated: 'folders'
|
routeIfAlreadyAuthenticated: 'folders'
|
||||||
},
|
},
|
||||||
APP: {
|
APP: {
|
||||||
// Allows to disable audit service in tests
|
|
||||||
auditEnabled: true,
|
|
||||||
intercomKey: ""
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,7 +66,6 @@ module.exports = function (environment) {
|
||||||
ENV['ember-cli-mirage'] = {
|
ENV['ember-cli-mirage'] = {
|
||||||
enabled: true
|
enabled: true
|
||||||
};
|
};
|
||||||
ENV.APP.auditEnabled = false;
|
|
||||||
|
|
||||||
ENV.apiHost = "https://localhost:5001";
|
ENV.apiHost = "https://localhost:5001";
|
||||||
}
|
}
|
||||||
|
@ -86,10 +82,6 @@ module.exports = function (environment) {
|
||||||
|
|
||||||
process.argv.forEach(function (element) {
|
process.argv.forEach(function (element) {
|
||||||
if (element !== undefined) {
|
if (element !== undefined) {
|
||||||
if (element.startsWith("intercom=")) {
|
|
||||||
element = element.replace("intercom=", "");
|
|
||||||
ENV.APP.intercomKey = element;
|
|
||||||
}
|
|
||||||
if (element.startsWith("apiHost=")) {
|
if (element.startsWith("apiHost=")) {
|
||||||
element = element.replace("apiHost=", "");
|
element = element.replace("apiHost=", "");
|
||||||
ENV.apiHost = element;
|
ENV.apiHost = element;
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software (Documize Community Edition) is licensed under
|
|
||||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
|
||||||
//
|
|
||||||
// You can operate outside the AGPL restrictions by purchasing
|
|
||||||
// Documize Enterprise Edition and obtaining a commercial license
|
|
||||||
// by contacting <sales@documize.com>.
|
|
||||||
//
|
|
||||||
// https://documize.com
|
|
||||||
|
|
||||||
/*jshint node:true*/
|
|
||||||
module.exports = {
|
|
||||||
name: 'intercom',
|
|
||||||
|
|
||||||
contentFor: function (type, config) {
|
|
||||||
// Not using Intercom for app activity logging?
|
|
||||||
if (!config.APP.auditEnabled) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
var appId = config.APP.intercomKey;
|
|
||||||
|
|
||||||
if ('head-footer' === type && appId.length > 0) {
|
|
||||||
return "<script type='text/javascript'> (function() { var w = window; var ic = w.Intercom; if (typeof ic === 'function') { ic('reattach_activator'); ic('update', intercomSettings); } else { var d = document; var i = function() { i.c(arguments) }; i.q = []; i.c = function(args) { i.q.push(args) }; w.Intercom = i; function l() { var s = d.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = 'https://widget.intercom.io/widget/${appId}'; var x = d.getElementsByTagName('script')[0]; x.parentNode.insertBefore(s, x); } if (w.attachEvent) { w.attachEvent('onload', l); } else { w.addEventListener('load', l, false); } } })() </script>";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isDevelopingAddon: function () {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name": "intercom",
|
|
||||||
"keywords": [
|
|
||||||
"ember-addon"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@ import Mirage from 'ember-cli-mirage';
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
|
|
||||||
this.passthrough('https://widget.intercom.io/widget/%7Bapp_id%7D');
|
|
||||||
this.urlPrefix = 'https://localhost:5001'; // make this `http://localhost:8080`, for example, if your API is on a different server
|
this.urlPrefix = 'https://localhost:5001'; // make this `http://localhost:8080`, for example, if your API is on a different server
|
||||||
this.namespace = 'api'; // make this `api`, for example, if your API is namespaced
|
this.namespace = 'api'; // make this `api`, for example, if your API is namespaced
|
||||||
// this.timing = 400; // delay for each request, automatically set to 0 during testing
|
// this.timing = 400; // delay for each request, automatically set to 0 during testing
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "documize",
|
"name": "documize",
|
||||||
"version": "1.46.2",
|
"version": "1.47.0",
|
||||||
"description": "The Document IDE",
|
"description": "The Document IDE",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": "",
|
"repository": "",
|
||||||
|
|
|
@ -3,13 +3,9 @@
|
||||||
NOW=$(date)
|
NOW=$(date)
|
||||||
echo "Build process started $NOW"
|
echo "Build process started $NOW"
|
||||||
|
|
||||||
# First parameter to this script is the Intercom.io key for audit logging.
|
|
||||||
# This is optional and we use Intercom to record user activity and provider in-app support via messaging.
|
|
||||||
intercomKey="$1"
|
|
||||||
|
|
||||||
echo "Building Ember assets..."
|
echo "Building Ember assets..."
|
||||||
cd app
|
cd app
|
||||||
ember b -o dist-prod/ --environment=production intercom=$intercomKey
|
ember b -o dist-prod/ --environment=production
|
||||||
|
|
||||||
echo "Copying Ember assets..."
|
echo "Copying Ember assets..."
|
||||||
cd ..
|
cd ..
|
||||||
|
|
|
@ -64,6 +64,8 @@ func AttachmentDownload(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
_, err = w.Write(attachment.Data)
|
_, err = w.Write(attachment.Data)
|
||||||
log.IfErr(err)
|
log.IfErr(err)
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeAttachmentDownload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAttachments is an end-point that returns all of the attachments of a particular documentID.
|
// GetAttachments is an end-point that returns all of the attachments of a particular documentID.
|
||||||
|
@ -125,7 +127,6 @@ func DeleteAttachment(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := request.Db.Beginx()
|
tx, err := request.Db.Beginx()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeTransactionError(w, method, err)
|
writeTransactionError(w, method, err)
|
||||||
return
|
return
|
||||||
|
@ -141,6 +142,8 @@ func DeleteAttachment(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeAttachmentDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -217,6 +220,8 @@ func AddAttachments(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeAttachmentAdd)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
|
|
@ -90,7 +90,6 @@ func Authenticate(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
org, err := p.GetOrganizationByDomain(domain)
|
org, err := p.GetOrganizationByDomain(domain)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeUnauthorizedError(w)
|
writeUnauthorizedError(w)
|
||||||
return
|
return
|
||||||
|
@ -111,7 +110,6 @@ func Authenticate(w http.ResponseWriter, r *http.Request) {
|
||||||
authModel.User = user
|
authModel.User = user
|
||||||
|
|
||||||
json, err := json.Marshal(authModel)
|
json, err := json.Marshal(authModel)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJSONMarshalError(w, method, "user", err)
|
writeJSONMarshalError(w, method, "user", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -245,6 +245,8 @@ func processDocument(p request.Persister, filename, job, folderID string, fileRe
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeCreated})
|
ActivityType: entity.ActivityTypeCreated})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeDocumentUpload)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -65,6 +65,8 @@ func SearchDocuments(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSearch)
|
||||||
|
|
||||||
writeSuccessBytes(w, data)
|
writeSuccessBytes(w, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,17 +112,13 @@ func GetDocument(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = p.RecordUserActivity(entity.UserActivity{
|
_ = p.RecordUserActivity(entity.UserActivity{
|
||||||
LabelID: document.LabelID,
|
LabelID: document.LabelID,
|
||||||
SourceID: document.RefID,
|
SourceID: document.RefID,
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeRead})
|
ActivityType: entity.ActivityTypeRead})
|
||||||
|
|
||||||
if err != nil {
|
p.RecordEvent(entity.EventTypeDocumentView)
|
||||||
log.IfErr(p.Context.Transaction.Rollback())
|
|
||||||
log.Error("Cannot record user activity", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.IfErr(p.Context.Transaction.Commit())
|
log.IfErr(p.Context.Transaction.Commit())
|
||||||
|
|
||||||
|
@ -301,6 +299,8 @@ func DeleteDocument(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeDeleted})
|
ActivityType: entity.ActivityTypeDeleted})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeDocumentDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -435,6 +435,8 @@ func UpdateDocument(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeDocumentUpdate)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
|
|
@ -18,9 +18,11 @@ import (
|
||||||
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/documize/community/core/api/entity"
|
||||||
"github.com/documize/community/core/api/request"
|
"github.com/documize/community/core/api/request"
|
||||||
"github.com/documize/community/core/api/util"
|
"github.com/documize/community/core/api/util"
|
||||||
"github.com/documize/community/core/event"
|
"github.com/documize/community/core/event"
|
||||||
|
"github.com/documize/community/core/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetSMTPConfig returns installation-wide SMTP settings
|
// GetSMTPConfig returns installation-wide SMTP settings
|
||||||
|
@ -160,6 +162,15 @@ func SaveLicense(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
event.Handler().Publish(string(event.TypeSystemLicenseChange))
|
event.Handler().Publish(string(event.TypeSystemLicenseChange))
|
||||||
|
|
||||||
|
p.Context.Transaction, err = request.Db.Beginx()
|
||||||
|
if err != nil {
|
||||||
|
writeTransactionError(w, method, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSystemLicense)
|
||||||
|
log.IfErr(p.Context.Transaction.Commit())
|
||||||
|
|
||||||
util.WriteSuccessEmptyJSON(w)
|
util.WriteSuccessEmptyJSON(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +238,8 @@ func SaveAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSystemAuth)
|
||||||
|
|
||||||
p.Context.Transaction.Commit()
|
p.Context.Transaction.Commit()
|
||||||
|
|
||||||
util.WriteSuccessEmptyJSON(w)
|
util.WriteSuccessEmptyJSON(w)
|
||||||
|
|
|
@ -81,6 +81,8 @@ func AddFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpaceAdd)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
folder, _ = p.GetLabel(id)
|
folder, _ = p.GetLabel(id)
|
||||||
|
@ -254,6 +256,8 @@ func UpdateFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpaceUpdate)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
json, err := json.Marshal(folder)
|
json, err := json.Marshal(folder)
|
||||||
|
@ -336,6 +340,8 @@ func RemoveFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpaceDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessString(w, "{}")
|
writeSuccessString(w, "{}")
|
||||||
|
@ -394,6 +400,8 @@ func DeleteFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpaceDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessString(w, "{}")
|
writeSuccessString(w, "{}")
|
||||||
|
@ -554,6 +562,8 @@ func SetFolderPermissions(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
log.Error("p.UpdateLabel()", p.UpdateLabel(label))
|
log.Error("p.UpdateLabel()", p.UpdateLabel(label))
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpacePermission)
|
||||||
|
|
||||||
log.Error("tx.Commit()", tx.Commit())
|
log.Error("tx.Commit()", tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -685,10 +695,11 @@ func AcceptSharedFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpaceJoin)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
data, err := json.Marshal(user)
|
data, err := json.Marshal(user)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJSONMarshalError(w, method, "user", err)
|
writeJSONMarshalError(w, method, "user", err)
|
||||||
return
|
return
|
||||||
|
@ -849,6 +860,8 @@ func InviteToFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSpaceInvite)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
_, err = w.Write([]byte("{}"))
|
_, err = w.Write([]byte("{}"))
|
||||||
|
|
|
@ -127,6 +127,8 @@ func AddDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeCreated})
|
ActivityType: entity.ActivityTypeCreated})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionAdd)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
newPage, _ := p.GetPage(pageID)
|
newPage, _ := p.GetPage(pageID)
|
||||||
|
@ -357,6 +359,8 @@ func DeleteDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeDeleted})
|
ActivityType: entity.ActivityTypeDeleted})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -439,6 +443,8 @@ func DeleteDocumentPages(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeDeleted})
|
ActivityType: entity.ActivityTypeDeleted})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -541,12 +547,13 @@ func UpdateDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeEdited})
|
ActivityType: entity.ActivityTypeEdited})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionUpdate)
|
||||||
|
|
||||||
log.IfErr(p.Context.Transaction.Commit())
|
log.IfErr(p.Context.Transaction.Commit())
|
||||||
|
|
||||||
updatedPage, err := p.GetPage(pageID)
|
updatedPage, err := p.GetPage(pageID)
|
||||||
|
|
||||||
json, err := json.Marshal(updatedPage)
|
json, err := json.Marshal(updatedPage)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJSONMarshalError(w, method, "page", err)
|
writeJSONMarshalError(w, method, "page", err)
|
||||||
return
|
return
|
||||||
|
@ -613,6 +620,8 @@ func ChangeDocumentPageSequence(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionResequence)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -676,6 +685,8 @@ func ChangeDocumentPageLevel(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionResequence)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -801,6 +812,8 @@ func GetDocumentRevisions(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeDocumentRevisions)
|
||||||
|
|
||||||
writeSuccessBytes(w, payload)
|
writeSuccessBytes(w, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1015,6 +1028,8 @@ func RollbackDocumentPage(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeReverted})
|
ActivityType: entity.ActivityTypeReverted})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionRollback)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
payload, err := json.Marshal(page)
|
payload, err := json.Marshal(page)
|
||||||
|
@ -1126,6 +1141,8 @@ func CopyPage(w http.ResponseWriter, r *http.Request) {
|
||||||
SourceType: entity.ActivitySourceTypeDocument,
|
SourceType: entity.ActivitySourceTypeDocument,
|
||||||
ActivityType: entity.ActivityTypeEdited})
|
ActivityType: entity.ActivityTypeEdited})
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeSectionCopy)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
newPage, _ := p.GetPage(pageID)
|
newPage, _ := p.GetPage(pageID)
|
||||||
|
|
|
@ -85,6 +85,8 @@ func AddPin(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypePinAdd)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
newPin, err := p.GetPin(pin.RefID)
|
newPin, err := p.GetPin(pin.RefID)
|
||||||
|
@ -178,6 +180,8 @@ func DeleteUserPin(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypePinDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
util.WriteSuccessEmptyJSON(w)
|
util.WriteSuccessEmptyJSON(w)
|
||||||
|
@ -238,6 +242,8 @@ func UpdatePinSequence(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypePinResequence)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
newPins, err := p.GetUserPins(userID)
|
newPins, err := p.GetUserPins(userID)
|
||||||
|
|
|
@ -234,6 +234,8 @@ func AddBlock(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeBlockAdd)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
b, err = p.GetBlock(b.RefID)
|
b, err = p.GetBlock(b.RefID)
|
||||||
|
@ -363,6 +365,8 @@ func UpdateBlock(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeBlockUpdate)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
@ -403,6 +407,8 @@ func DeleteBlock(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeBlockDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
writeSuccessEmptyJSON(w)
|
writeSuccessEmptyJSON(w)
|
||||||
|
|
|
@ -34,8 +34,8 @@ var Product core.ProdInfo
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Product.Major = "1"
|
Product.Major = "1"
|
||||||
Product.Minor = "46"
|
Product.Minor = "47"
|
||||||
Product.Patch = "2"
|
Product.Patch = "0"
|
||||||
Product.Version = fmt.Sprintf("%s.%s.%s", Product.Major, Product.Minor, Product.Patch)
|
Product.Version = fmt.Sprintf("%s.%s.%s", Product.Major, Product.Minor, Product.Patch)
|
||||||
Product.Edition = "Community"
|
Product.Edition = "Community"
|
||||||
Product.Title = fmt.Sprintf("%s Edition", Product.Edition)
|
Product.Title = fmt.Sprintf("%s Edition", Product.Edition)
|
||||||
|
|
|
@ -169,6 +169,8 @@ func SaveAsTemplate(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeTemplateAdd)
|
||||||
|
|
||||||
// Commit and return new document template
|
// Commit and return new document template
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
|
@ -180,7 +182,6 @@ func SaveAsTemplate(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
d, err := json.Marshal(doc)
|
d, err := json.Marshal(doc)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeJSONMarshalError(w, method, "document", err)
|
writeJSONMarshalError(w, method, "document", err)
|
||||||
return
|
return
|
||||||
|
@ -452,6 +453,8 @@ func StartDocumentFromSavedTemplate(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeTemplateUse)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
newDocument, err := p.GetDocument(documentID)
|
newDocument, err := p.GetDocument(documentID)
|
||||||
|
|
|
@ -163,6 +163,16 @@ func AddUser(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if addUser {
|
||||||
|
event.Handler().Publish(string(event.TypeAddUser))
|
||||||
|
p.RecordEvent(entity.EventTypeUserAdd)
|
||||||
|
}
|
||||||
|
|
||||||
|
if addAccount {
|
||||||
|
event.Handler().Publish(string(event.TypeAddAccount))
|
||||||
|
p.RecordEvent(entity.EventTypeAccountAdd)
|
||||||
|
}
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
// If we did not add user or give them access (account) then we error back
|
// If we did not add user or give them access (account) then we error back
|
||||||
|
@ -175,14 +185,6 @@ func AddUser(w http.ResponseWriter, r *http.Request) {
|
||||||
inviter, err := p.GetUser(p.Context.UserID)
|
inviter, err := p.GetUser(p.Context.UserID)
|
||||||
log.IfErr(err)
|
log.IfErr(err)
|
||||||
|
|
||||||
if addUser {
|
|
||||||
event.Handler().Publish(string(event.TypeAddUser))
|
|
||||||
}
|
|
||||||
|
|
||||||
if addAccount {
|
|
||||||
event.Handler().Publish(string(event.TypeAddAccount))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare invitation email (that contains SSO link)
|
// Prepare invitation email (that contains SSO link)
|
||||||
if addUser && addAccount {
|
if addUser && addAccount {
|
||||||
size := len(requestedPassword)
|
size := len(requestedPassword)
|
||||||
|
@ -393,6 +395,8 @@ func DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||||
err = p.ChangeLabelOwner(userID, p.Context.UserID)
|
err = p.ChangeLabelOwner(userID, p.Context.UserID)
|
||||||
log.IfErr(err)
|
log.IfErr(err)
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeUserDelete)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
event.Handler().Publish(string(event.TypeRemoveUser))
|
event.Handler().Publish(string(event.TypeRemoveUser))
|
||||||
|
@ -485,6 +489,8 @@ func UpdateUser(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeUserUpdate)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
json, err := json.Marshal(user)
|
json, err := json.Marshal(user)
|
||||||
|
@ -701,6 +707,8 @@ func ResetUserPassword(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.RecordEvent(entity.EventTypeUserPasswordReset)
|
||||||
|
|
||||||
log.IfErr(tx.Commit())
|
log.IfErr(tx.Commit())
|
||||||
|
|
||||||
_, err = w.Write([]byte("{}"))
|
_, err = w.Write([]byte("{}"))
|
||||||
|
|
|
@ -508,3 +508,57 @@ const (
|
||||||
// ActivityTypeFeedback records user providing document feedback
|
// ActivityTypeFeedback records user providing document feedback
|
||||||
ActivityTypeFeedback ActivityType = 10
|
ActivityTypeFeedback ActivityType = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AppEvent represents an event initiated by a user.
|
||||||
|
type AppEvent struct {
|
||||||
|
ID uint64 `json:"-"`
|
||||||
|
OrgID string `json:"orgId"`
|
||||||
|
UserID string `json:"userId"`
|
||||||
|
Type string `json:"eventType"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventType defines valid event entry types
|
||||||
|
type EventType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EventTypeDocumentAdd EventType = "added-document"
|
||||||
|
EventTypeDocumentUpload EventType = "uploaded-document"
|
||||||
|
EventTypeDocumentView EventType = "viewed-document"
|
||||||
|
EventTypeDocumentUpdate EventType = "updated-document"
|
||||||
|
EventTypeDocumentDelete EventType = "removed-document"
|
||||||
|
EventTypeDocumentRevisions EventType = "viewed-document-revisions"
|
||||||
|
EventTypeSpaceAdd EventType = "added-space"
|
||||||
|
EventTypeSpaceView EventType = "viewed-space"
|
||||||
|
EventTypeSpaceUpdate EventType = "updated-space"
|
||||||
|
EventTypeSpaceDelete EventType = "removed-space"
|
||||||
|
EventTypeSpacePermission EventType = "changed-space-permissions"
|
||||||
|
EventTypeSpaceJoin EventType = "joined-space"
|
||||||
|
EventTypeSpaceInvite EventType = "invited-space"
|
||||||
|
EventTypeSectionAdd EventType = "added-document-section"
|
||||||
|
EventTypeSectionUpdate EventType = "updated-document-section"
|
||||||
|
EventTypeSectionDelete EventType = "removed-document-section"
|
||||||
|
EventTypeSectionRollback EventType = "rolled-back-document-section"
|
||||||
|
EventTypeSectionResequence EventType = "resequenced-document-section"
|
||||||
|
EventTypeSectionCopy EventType = "copied-document-section"
|
||||||
|
EventTypeAttachmentAdd EventType = "added-attachment"
|
||||||
|
EventTypeAttachmentDownload EventType = "downloaded-attachment"
|
||||||
|
EventTypeAttachmentDelete EventType = "removed-attachment"
|
||||||
|
EventTypePinAdd EventType = "added-pin"
|
||||||
|
EventTypePinDelete EventType = "removed-pin"
|
||||||
|
EventTypePinResequence EventType = "resequenced-pin"
|
||||||
|
EventTypeBlockAdd EventType = "added-reusable-block"
|
||||||
|
EventTypeBlockUpdate EventType = "updated-reusable-block"
|
||||||
|
EventTypeBlockDelete EventType = "removed-reusable-block"
|
||||||
|
EventTypeTemplateAdd EventType = "added-document-template"
|
||||||
|
EventTypeTemplateUse EventType = "used-document-template"
|
||||||
|
EventTypeUserAdd EventType = "added-user"
|
||||||
|
EventTypeUserUpdate EventType = "updated-user"
|
||||||
|
EventTypeUserDelete EventType = "removed-user"
|
||||||
|
EventTypeUserPasswordReset EventType = "reset-user-password"
|
||||||
|
EventTypeAccountAdd EventType = "added-account"
|
||||||
|
EventTypeSystemLicense EventType = "changed-license"
|
||||||
|
EventTypeSystemAuth EventType = "changed-auth-config"
|
||||||
|
EventTypeSessionStart EventType = "started-session"
|
||||||
|
EventTypeSearch EventType = "searched"
|
||||||
|
)
|
||||||
|
|
58
core/api/request/event.go
Normal file
58
core/api/request/event.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||||
|
//
|
||||||
|
// This software (Documize Community Edition) is licensed under
|
||||||
|
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
//
|
||||||
|
// You can operate outside the AGPL restrictions by purchasing
|
||||||
|
// Documize Enterprise Edition and obtaining a commercial license
|
||||||
|
// by contacting <sales@documize.com>.
|
||||||
|
//
|
||||||
|
// https://documize.com
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/documize/community/core/api/entity"
|
||||||
|
"github.com/documize/community/core/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecordEvent adds event entry for specified user.
|
||||||
|
func (p *Persister) RecordEvent(t entity.EventType) {
|
||||||
|
e := entity.AppEvent{}
|
||||||
|
e.OrgID = p.Context.OrgID
|
||||||
|
e.UserID = p.Context.UserID
|
||||||
|
e.Created = time.Now().UTC()
|
||||||
|
e.Type = string(t)
|
||||||
|
|
||||||
|
if e.OrgID == "" || e.UserID == "" {
|
||||||
|
log.Info("Missing OrgID/UserID for event record " + e.Type)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := Db.Beginx()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to prepare insert RecordEvent", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt, err := tx.Preparex("INSERT INTO userevent (orgid, userid, eventtype, created) VALUES (?, ?, ?, ?)")
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
log.Error("Unable to prepare insert RecordEvent", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = stmt.Exec(e.OrgID, e.UserID, e.Type, e.Created)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to execute insert RecordEvent", err)
|
||||||
|
tx.Rollback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.Close()
|
||||||
|
tx.Commit()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
15
core/database/scripts/autobuild/db_00013.sql
Normal file
15
core/database/scripts/autobuild/db_00013.sql
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/* community edition */
|
||||||
|
DROP TABLE IF EXISTS `userevent`;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `userevent` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`orgid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`userid` CHAR(16) NOT NULL COLLATE utf8_bin,
|
||||||
|
`eventtype` VARCHAR(100) NOT NULL DEFAULT '',
|
||||||
|
`created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
CONSTRAINT pk_id PRIMARY KEY (id),
|
||||||
|
INDEX `idx_userevent_orgid` (`orgid` ASC),
|
||||||
|
INDEX `idx_userevent_userid` (`userid` ASC),
|
||||||
|
INDEX `idx_userevent_eventtype` (`eventtype` ASC))
|
||||||
|
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci
|
||||||
|
ENGINE = InnoDB;
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue