1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-08-02 20:15:26 +02:00

moved emberjs to gui folder

This commit is contained in:
Harvey Kandola 2017-07-19 14:48:33 +01:00
parent 6a18d18f91
commit dc49dbbeff
999 changed files with 677 additions and 651 deletions

53
gui/app/services/ajax.js Normal file
View file

@ -0,0 +1,53 @@
// 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 AjaxService from 'ember-ajax/services/ajax';
import config from '../config/environment';
const {
computed,
inject: { service }
} = Ember;
export default AjaxService.extend({
session: service(),
host: config.apiHost,
namespace: config.apiNamespace,
headers: computed('session.session.content.authenticated.token', {
get() {
let headers = {};
const token = this.get('session.session.content.authenticated.token');
if (token) {
headers['authorization'] = token;
}
return headers;
}
}),
handleResponse(status, headers /*, payload*/) {
try {
let user = this.get('session.session.content.authenticated.user');
let userUpdate = headers['x-documize-status'];
if (is.not.empty(userUpdate)) {
let latest = JSON.parse(userUpdate);
if (!latest.active || user.editor !== latest.editor || user.admin !== latest.admin) {
window.location.href = 'auth/login';
}
}
} catch(e){} // eslint-disable-line no-empty
return this._super(...arguments);
}
});

View file

@ -0,0 +1,89 @@
// 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 config from '../config/environment';
import constants from '../utils/constants';
const {
String: { htmlSafe },
RSVP: { resolve },
inject: { service }
} = Ember;
export default Ember.Service.extend({
ajax: service(),
localStorage: service(),
kcAuth: service(),
apiHost: `${config.apiHost}`,
endpoint: `${config.apiHost}/${config.apiNamespace}`,
conversionEndpoint: '',
orgId: '',
title: '',
version: '',
message: '',
edition: 'Community',
valid: true,
allowAnonymousAccess: false,
authProvider: constants.AuthProvider.Documize,
authConfig: null,
setupMode: false,
invalidLicense() {
return this.valid === false;
},
getBaseUrl(endpoint) {
return [this.get('endpoint'), endpoint].join('/');
},
boot(requestedRoute, requestedUrl) { // eslint-disable-line no-unused-vars
let dbhash;
if (is.not.null(document.head.querySelector("[property=dbhash]"))) {
dbhash = document.head.querySelector("[property=dbhash]").content;
}
let isInSetupMode = dbhash && dbhash !== "{{.DBhash}}";
if (isInSetupMode) {
this.setProperties({
title: htmlSafe("Documize Setup"),
allowAnonymousAccess: true,
setupMode: true
});
this.get('localStorage').clearAll();
return resolve(this);
}
if (requestedRoute === 'secure') {
this.setProperties({
title: htmlSafe("Secure document viewing"),
allowAnonymousAccess: true,
setupMode: true
});
this.get('localStorage').clearAll();
return resolve(this);
}
return this.get('ajax').request('public/meta').then((response) => {
this.setProperties(response);
if (is.not.include(requestedUrl, '/auth/')) {
this.get('localStorage').storeSessionItem('entryUrl', requestedUrl);
}
return response;
});
}
});

36
gui/app/services/base.js Normal file
View file

@ -0,0 +1,36 @@
// 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';
export default Ember.Service.extend({
interval(func, wait, times) {
var interv = function(w, t) {
return function() {
if (typeof t === "undefined" || t-- > 0) {
setTimeout(interv, w);
try {
func.call(null);
} catch (e) {
t = 0;
throw e.toString();
}
}
};
}(wait, times);
setTimeout(interv, wait);
},
showNotification(msg) {
this.get('eventBus').publish('notifyUser', msg);
}
});

View file

@ -0,0 +1,46 @@
// 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';
export default Ember.Service.extend({
sessionService: Ember.inject.service('session'),
init() {
this.setMetaDescription();
},
setTitle(title) {
document.title = title + " | " + this.get('sessionService.appMeta.title');
},
setTitleReverse(title) {
document.title = this.get('sessionService.appMeta.title') + " | " + title;
},
setTitleAsPhrase(title) {
document.title = this.get('sessionService.appMeta.title') + " " + title;
},
setTitleWithoutSuffix(title) {
document.title = title;
},
setMetaDescription(description) {
$('meta[name=description]').remove();
if (is.null(description) || is.undefined(description)) {
description = this.get('sessionService.appMeta.message');
}
$('head').append('<meta name="description" content="' + description + '">');
}
});

View file

@ -0,0 +1,353 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
store: service(),
// Returns document model for specified document id.
getDocument(documentId) {
return this.get('ajax').request(`documents/${documentId}`, {
method: "GET"
}).then((response) => {
let data = this.get('store').normalize('document', response);
return this.get('store').push(data);
}).catch((error) => {
this.get('router').transitionTo('/not-found');
return error;
});
},
// Returns all documents for specified folder.
getAllByFolder(folderId) {
return this.get('ajax').request(`documents?folder=${folderId}`, {
method: "GET"
}).then((response) => {
let documents = Ember.ArrayProxy.create({
content: Ember.A([])
});
if (isObject(response)) {
return documents;
}
documents = response.map((doc) => {
let data = this.get('store').normalize('document', doc);
return this.get('store').push(data);
});
return documents;
});
},
// getDocumentsByTag returns all documents for specified tag (not folder!).
getAllByTag(tag) {
return this.get('ajax').request(`documents?filter=tag&tag=${tag}`, {
method: "GET"
}).then((response) => {
let documents = Ember.ArrayProxy.create({
content: Ember.A([])
});
documents = response.map((doc) => {
let data = this.get('store').normalize('document', doc);
return this.get('store').push(data);
});
return documents;
});
},
// saveDocument updates an existing document record.
save(doc) {
let id = doc.get('id');
return this.get('ajax').request(`documents/${id}`, {
method: 'PUT',
data: JSON.stringify(doc)
});
},
getBatchedPages: function (documentId, payload) {
let url = `documents/${documentId}/pages/batch`;
return this.get('ajax').request(url, {
method: 'POST',
data: payload
}).then((pages) => {
if (is.not.array(pages)) {
pages = [];
}
return pages;
});
},
changePageSequence: function (documentId, payload) {
let url = `documents/${documentId}/pages/sequence`;
return this.get('ajax').post(url, {
data: JSON.stringify(payload),
contentType: 'json'
});
},
changePageLevel(documentId, payload) {
let url = `documents/${documentId}/pages/level`;
return this.get('ajax').post(url, {
data: JSON.stringify(payload),
contentType: 'json'
});
},
deleteDocument: function (documentId) {
let url = `documents/${documentId}`;
return this.get('ajax').request(url, {
method: 'DELETE'
});
},
updatePage(documentId, pageId, payload, skipRevision) {
var revision = skipRevision ? "?r=true" : "?r=false";
let url = `documents/${documentId}/pages/${pageId}${revision}`;
Ember.set(payload.meta, 'id', parseInt(payload.meta.id));
return this.get('ajax').request(url, {
method: 'PUT',
data: JSON.stringify(payload),
contentType: 'json'
}).then((response) => {
let data = this.get('store').normalize('page', response);
return this.get('store').push(data);
});
},
// addPage inserts new page to an existing document.
addPage: function (documentId, payload) {
let url = `documents/${documentId}/pages`;
return this.get('ajax').post(url, {
data: JSON.stringify(payload),
contentType: 'json'
});
},
// Nukes multiple pages from the document.
deletePages: function (documentId, pageId, payload) {
let url = `documents/${documentId}/pages`;
return this.get('ajax').request(url, {
data: JSON.stringify(payload),
contentType: 'json',
method: 'DELETE'
});
},
// Nukes a single page from the document.
deletePage: function (documentId, pageId) {
let url = `documents/${documentId}/pages/${pageId}`;
return this.get('ajax').request(url, {
method: 'DELETE'
});
},
getDocumentRevisions(documentId) {
let url = `documents/${documentId}/revisions`;
return this.get('ajax').request(url, {
method: "GET"
});
},
getPageRevisions(documentId, pageId) {
let url = `documents/${documentId}/pages/${pageId}/revisions`;
return this.get('ajax').request(url, {
method: "GET"
});
},
getPageRevisionDiff(documentId, pageId, revisionId) {
let url = `documents/${documentId}/pages/${pageId}/revisions/${revisionId}`;
return this.get('ajax').request(url, {
method: "GET",
dataType: 'text'
}).then((response) => {
return response;
}).catch(() => {
return "";
});
},
rollbackPage(documentId, pageId, revisionId) {
let url = `documents/${documentId}/pages/${pageId}/revisions/${revisionId}`;
return this.get('ajax').request(url, {
method: "POST"
});
},
// document meta referes to number of views, edits, approvals, etc.
getActivity(documentId) {
return this.get('ajax').request(`documents/${documentId}/activity`, {
method: "GET"
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('documentActivity', obj);
return this.get('store').push(data);
});
return data;
}).catch(() => {
return [];
});
},
// Returns all pages without the content
getTableOfContents(documentId) {
return this.get('ajax').request(`documents/${documentId}/pages?content=0`, {
method: 'GET'
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('page', obj);
return this.get('store').push(data);
});
return data;
});
},
// Returns all document pages with content
getPages(documentId) {
return this.get('ajax').request(`documents/${documentId}/pages`, {
method: 'GET'
}).then((response) => {
let pages = [];
pages = response.map((page) => {
let data = this.get('store').normalize('page', page);
return this.get('store').push(data);
});
return pages;
});
},
// Returns document page with content
getPage(documentId, pageId) {
return this.get('ajax').request(`documents/${documentId}/pages/${pageId}`, {
method: 'GET'
}).then((response) => {
let data = this.get('store').normalize('page', response);
return this.get('store').push(data);
});
},
// Returns document page meta object
getPageMeta(documentId, pageId) {
return this.get('ajax').request(`documents/${documentId}/pages/${pageId}/meta`, {
method: 'GET'
}).then((response) => {
let data = this.get('store').normalize('page-meta', response);
return this.get('store').push(data);
}).catch(() => {
});
},
// document attachments without the actual content
getAttachments(documentId) {
return this.get('ajax').request(`documents/${documentId}/attachments`, {
method: 'GET'
}).then((response) => {
let data = [];
if (isObject(response)) {
return data;
}
data = response.map((obj) => {
let data = this.get('store').normalize('attachment', obj);
return this.get('store').push(data);
});
return data;
});
},
// nuke an attachment
deleteAttachment(documentId, attachmentId) {
return this.get('ajax').request(`documents/${documentId}/attachments/${attachmentId}`, {
method: 'DELETE'
});
},
//**************************************************
// Page Move Copy
//**************************************************
// Return list of documents that can accept a page.
getPageMoveCopyTargets() {
return this.get('ajax').request(`sections/targets`, {
method: 'GET'
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('document', obj);
return this.get('store').push(data);
});
return data;
});
},
// Copy existing page to same or different document.
copyPage(documentId, pageId, targetDocumentId) {
return this.get('ajax').request(`documents/${documentId}/pages/${pageId}/copy/${targetDocumentId}`, {
method: 'POST'
}).then((response) => {
let data = this.get('store').normalize('page', response);
return this.get('store').push(data);
});
},
// Move existing page to different document.
movePage(documentId, pageId, targetDocumentId) {
return this.get('ajax').request(`documents/${documentId}/pages/${pageId}/move/${targetDocumentId}`, {
method: 'POST'
}).then((response) => {
let data = this.get('store').normalize('page', response);
return this.get('store').push(data);
});
}
});
function isObject(a) {
return (!!a) && (a.constructor === Object);
}

View file

@ -0,0 +1,39 @@
// 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';
export default Ember.Service.extend(Ember.Evented, {
init() {
this._super(...arguments);
let _this = this;
window.addEventListener("scroll", _.throttle(function() {
_this.publish('scrolled', null);
}, 100));
window.addEventListener("resize", _.debounce(function() {
_this.publish('resized', null);
}, 100));
},
publish: function() {
return this.trigger.apply(this, arguments);
},
subscribe: function() {
return this.on.apply(this, arguments);
},
unsubscribe: function() {
return this.off.apply(this, arguments);
}
});

220
gui/app/services/folder.js Normal file
View file

@ -0,0 +1,220 @@
// 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 BaseService from '../services/base';
const {
get,
RSVP,
inject: { service }
} = Ember;
export default BaseService.extend({
sessionService: service('session'),
ajax: service(),
localStorage: service(),
store: service(),
// selected folder
currentFolder: null,
canEditCurrentFolder: false,
// Add a new folder.
add(folder) {
return this.get('ajax').post(`folders`, {
contentType: 'json',
data: JSON.stringify(folder)
}).then((folder) => {
let data = this.get('store').normalize('folder', folder);
return this.get('store').push(data);
});
},
// Returns folder model for specified folder id.
getFolder(id) {
return this.get('ajax').request(`folders/${id}`, {
method: 'GET'
}).then((folder) => {
let data = this.get('store').normalize('folder', folder);
return this.get('store').push(data);
}).catch((error) => {
this.get('router').transitionTo('/not-found');
return error;
});
},
// Returns all folders that user can see.
getAll() {
let folders = this.get('folders');
if (folders != null) {
return new RSVP.resolve(folders);
}
return this.reload();
},
// Updates an existing folder record.
save(folder) {
let id = folder.get('id');
return this.get('ajax').request(`folders/${id}`, {
method: 'PUT',
contentType: 'json',
data: JSON.stringify(folder)
});
},
remove(folderId, moveToId) {
let url = `folders/${folderId}/move/${moveToId}`;
return this.get('ajax').request(url, {
method: 'DELETE'
});
},
delete(folderId) {
return this.get('ajax').request(`folders/${folderId}`, {
method: 'DELETE'
});
},
onboard(folderId, payload) {
let url = `public/share/${folderId}`;
return this.get('ajax').post(url, {
contentType: "application/json",
data: payload
});
},
// getProtectedFolderInfo returns non-private folders and who has access to them.
getProtectedFolderInfo() {
return this.get('ajax').request(`folders?filter=viewers`, {
method: "GET"
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('protected-folder-participant', obj);
return this.get('store').push(data);
});
return data;
});
},
// reloads and caches folders.
reload() {
return this.get('ajax').request(`folders`, {
method: "GET"
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('folder', obj);
return this.get('store').push(data);
});
return data;
});
},
// so who can see/edit this folder?
getPermissions(folderId) {
return this.get('ajax').request(`folders/${folderId}/permissions`, {
method: "GET"
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('folder-permission', obj);
return this.get('store').push(data);
});
return data;
});
},
// persist folder permissions
savePermissions(folderId, payload) {
return this.get('ajax').request(`folders/${folderId}/permissions`, {
method: 'PUT',
contentType: 'json',
data: JSON.stringify(payload)
});
},
// share this folder with new users!
share(folderId, invitation) {
return this.get('ajax').post(`folders/${folderId}/invitation`, {
contentType: 'json',
data: JSON.stringify(invitation)
});
},
// Current folder caching
setCurrentFolder(folder) {
if (is.undefined(folder) || is.null(folder)) {
return;
}
this.set('currentFolder', folder);
this.get('localStorage').storeSessionItem("folder", get(folder, 'id'));
this.set('canEditCurrentFolder', false);
let userId = this.get('sessionService.user.id');
if (userId === "") {
userId = "0";
}
let url = `users/${userId}/permissions`;
return this.get('ajax').request(url).then((folderPermissions) => {
// safety check
this.set('canEditCurrentFolder', false);
if (folderPermissions.length === 0) {
return;
}
let result = [];
let folderId = folder.get('id');
folderPermissions.forEach((item) => {
if (item.folderId === folderId) {
result.push(item);
}
});
let canEdit = false;
result.forEach((permission) => {
if (permission.userId === userId) {
canEdit = permission.canEdit;
}
if (permission.userId === "" && !canEdit) {
canEdit = permission.canEdit;
}
});
Ember.run(() => {
this.set('canEditCurrentFolder', canEdit && this.get('sessionService.authenticated'));
});
});
},
});

100
gui/app/services/global.js Normal file
View file

@ -0,0 +1,100 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
appMeta: service(),
store: service(),
// Returns SMTP configuration.
getSMTPConfig() {
if(this.get('sessionService.isGlobalAdmin')) {
return this.get('ajax').request(`global/smtp`, {
method: 'GET'
}).then((response) => {
return response;
});
}
},
// Saves SMTP configuration.
saveSMTPConfig(config) {
if(this.get('sessionService.isGlobalAdmin')) {
return this.get('ajax').request(`global/smtp`, {
method: 'PUT',
data: JSON.stringify(config)
});
}
},
// Returns product license.
getLicense() {
if(this.get('sessionService.isGlobalAdmin')) {
return this.get('ajax').request(`global/license`, {
method: 'GET',
dataType: "text"
}).then((response) => {
return response;
});
}
},
// Saves product license.
saveLicense(license) {
if(this.get('sessionService.isGlobalAdmin')) {
return this.get('ajax').request(`global/license`, {
method: 'PUT',
dataType: 'text',
data: license
});
}
},
// Returns auth config for Documize instance.
getAuthConfig() {
if(this.get('sessionService.isGlobalAdmin')) {
return this.get('ajax').request(`global/auth`, {
method: 'GET'
}).then((response) => {
return response;
});
}
},
// Saves auth config for Documize instance.
saveAuthConfig(config) {
if(this.get('sessionService.isGlobalAdmin')) {
return this.get('ajax').request(`global/auth`, {
method: 'PUT',
data: JSON.stringify(config)
});
}
},
syncExternalUsers() {
if(this.get('sessionService.isAdmin')) {
return this.get('ajax').request(`users/sync`, {
method: 'GET'
}).then((response) => {
return response;
}).catch((error) => {
return error;
});
}
},
});

104
gui/app/services/kc-auth.js Normal file
View file

@ -0,0 +1,104 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
appMeta: service(),
keycloak: null,
config: {},
boot() {
return new Ember.RSVP.Promise((resolve, reject) => {
if (is.not.undefined(this.get('keycloak')) && is.not.null(this.get('keycloak')) ) {
resolve(this.get('keycloak'));
return;
}
let keycloak = new Keycloak(JSON.parse(this.get('appMeta.authConfig')));
this.set('keycloak', keycloak);
// keycloak.onTokenExpired = function () {
// keycloak.clearToken();
// };
// keycloak.onAuthRefreshError = function () {
// keycloak.clearToken();
// };
this.get('keycloak').init().success(() => {
resolve(this.get('keycloak'));
}).error((err) => {
reject(err);
});
});
},
login() {
return new Ember.RSVP.Promise((resolve, reject) => {
this.boot().then((keycloak) => {
let url = netUtil.getAppUrl(netUtil.getSubdomain()) + '/auth/keycloak?mode=login';
keycloak.login({redirectUri: url}).success(() => {
return resolve();
}).error(() => {
return reject(new Error('login failed'));
});
});
});
},
logout() {
return new Ember.RSVP.Promise((resolve, reject) => {
this.boot().then((keycloak) => {
keycloak.logout(JSON.parse(this.get('appMeta.authConfig'))).success(() => {
this.get('keycloak').clearToken();
resolve();
}).error((error) => {
this.get('keycloak').clearToken();
reject(error);
});
});
});
},
fetchProfile() {
return new Ember.RSVP.Promise((resolve, reject) => {
this.boot().then((keycloak) => {
keycloak.loadUserProfile().success((profile) => {
resolve(profile);
}).error((err) => {
reject(err);
});
});
});
},
mapProfile(profile) {
return {
domain: '',
token: this.get('keycloak').token,
remoteId: is.null(profile.id) || is.undefined(profile.id) ? profile.email: profile.id,
email: is.null(profile.email) || is.undefined(profile.email) ? '': profile.email,
username: is.null(profile.username) || is.undefined(profile.username) ? '': profile.username,
firstname: is.null(profile.firstName) || is.undefined(profile.firstName) ? profile.username: profile.firstName,
lastname: is.null(profile.lastName) || is.undefined(profile.lastName) ? profile.username: profile.lastName,
enabled: is.null(profile.enabled) || is.undefined(profile.enabled) ? true: profile.enabled
};
}
});

134
gui/app/services/link.js Normal file
View file

@ -0,0 +1,134 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
appMeta: service(),
store: service(),
// Returns links within specified document
getDocumentLinks(documentId) {
return this.get('ajax').request(`documents/${documentId}/links`, {
method: "GET"
});
},
// Returns candidate links using provided parameters
getCandidates(folderId, documentId, pageId) {
return this.get('ajax').request(`links/${folderId}/${documentId}/${pageId}`, {
method: 'GET'
}).then((response) => {
return response;
});
},
// Returns keyword-based candidates
searchCandidates(keywords) {
let url = "links?keywords=" + encodeURIComponent(keywords);
return this.get('ajax').request(url, {
method: 'GET'
}).then((response) => {
return response;
});
},
// getUsers returns all users for organization.
find(keywords) {
let url = "search?keywords=" + encodeURIComponent(keywords);
return this.get('ajax').request(url, {
method: "GET"
});
},
buildLink(link) {
let result = "";
let href = "";
let endpoint = this.get('appMeta').get('endpoint');
let orgId = this.get('appMeta').get('orgId');
if (link.linkType === "section" || link.linkType === "tab" || link.linkType === "document") {
href = `/link/${link.linkType}/${link.id}`;
result = `<a data-documize='true' data-link-space-id='${link.folderId}' data-link-id='${link.id}' data-link-target-document-id='${link.documentId}' data-link-target-id='${link.targetId}' data-link-type='${link.linkType}' href='${href}'>${link.title}</a>`;
}
if (link.linkType === "file") {
href = `${endpoint}/public/attachments/${orgId}/${link.targetId}`;
result = `<a data-documize='true' data-link-space-id='${link.folderId}' data-link-id='${link.id}' data-link-target-document-id='${link.documentId}' data-link-target-id='${link.targetId}' data-link-type='${link.linkType}' href='${href}'>${link.title}</a>`;
}
return result;
},
getLinkObject(outboundLinks, a) {
let link = {
linkId: a.attributes["data-link-id"].value,
linkType: a.attributes["data-link-type"].value,
documentId: a.attributes["data-link-target-document-id"].value,
folderId: a.attributes["data-link-space-id"].value,
targetId: a.attributes["data-link-target-id"].value,
url: a.attributes["href"].value,
orphan: false
};
link.orphan = _.isEmpty(link.linkId) || _.isEmpty(link.documentId) || _.isEmpty(link.folderId) || _.isEmpty(link.targetId);
// we check latest state of link using database data
let existing = outboundLinks.findBy('id', link.linkId);
if (_.isUndefined(existing)) {
link.orphan = true;
} else {
link.orphan = existing.orphan;
}
return link;
},
linkClick(doc, link) {
if (link.orphan) {
return;
}
let router = this.get('router');
let targetFolder = this.get('store').peekRecord('folder', link.folderId);
let targetDocument = this.get('store').peekRecord('document', link.documentId);
let folderSlug = is.null(targetFolder) ? "s" : targetFolder.get('slug');
let documentSlug = is.null(targetDocument) ? "d" : targetDocument.get('slug');
// handle section link
if (link.linkType === "section" || link.linkType === "tab") {
let options = {};
options['pageId'] = link.targetId;
router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug, { queryParams: options });
return;
}
// handle document link
if (link.linkType === "document") {
router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug);
return;
}
// handle attachment links
if (link.linkType === "file") {
window.location.href = link.url;
return;
}
}
});

View file

@ -0,0 +1,30 @@
// 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';
export default Ember.Service.extend({
storeSessionItem: function (key, data) {
localStorage[key] = data;
},
getSessionItem: function (key) {
return localStorage[key];
},
clearSessionItem: function (key) {
delete localStorage[key];
},
clearAll() {
localStorage.clear();
}
});

View file

@ -0,0 +1,26 @@
// 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';
export default Ember.Service.extend({
action: function(entry) {
console.log(entry); // eslint-disable-line no-console
},
error: function(entry) {
console.log(entry); // eslint-disable-line no-console
},
info: function(entry) {
console.log(entry); // eslint-disable-line no-console
}
});

View file

@ -0,0 +1,49 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
appMeta: service(),
store: service(),
// Returns attributes for specified org id.
getOrg(id) {
return this.get('ajax').request(`organizations/${id}`, {
method: 'GET'
}).then((response) => {
let data = this.get('store').normalize('organization', response);
return this.get('store').push(data);
});
},
// Updates an existing organization record.
save(org) {
let id = org.id;
this.get('appMeta').setProperties({
message: org.get('message'),
title: org.get('title'),
conversionEndpoint: org.get('conversionEndpoint')
});
return this.get('ajax').request(`organizations/${id}`, {
method: 'PUT',
data: JSON.stringify(org)
});
}
});

148
gui/app/services/pinned.js Normal file
View file

@ -0,0 +1,148 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
session: service('session'),
ajax: service(),
appMeta: service(),
store: service(),
pins: [],
initialized: false,
getUserPins() {
let userId = this.get('session.user.id');
return this.get('ajax').request(`pin/${userId}`, {
method: 'GET'
}).then((response) => {
if (is.not.array(response)) {
response = [];
}
let pins = Ember.ArrayProxy.create({
content: Ember.A([])
});
pins = response.map((pin) => {
let data = this.get('store').normalize('pin', pin);
return this.get('store').push(data);
});
this.set('pins', pins);
this.set('initialized', true);
return pins;
});
},
// Pin an item.
pinItem(data) {
let userId = this.get('session.user.id');
if(this.get('session.authenticated')) {
return this.get('ajax').request(`pin/${userId}`, {
method: 'POST',
data: JSON.stringify(data)
}).then((response) => {
let data = this.get('store').normalize('pin', response);
return this.get('store').push(data);
});
}
},
// Unpin an item.
unpinItem(pinId) {
let userId = this.get('session.user.id');
if(this.get('session.authenticated')) {
return this.get('ajax').request(`pin/${userId}/${pinId}`, {
method: 'DELETE'
});
}
},
// updateSequence persists order after use drag-drop sorting.
updateSequence(data) {
let userId = this.get('session.user.id');
if(this.get('session.authenticated')) {
return this.get('ajax').request(`pin/${userId}/sequence`, {
method: 'POST',
data: JSON.stringify(data)
}).then((response) => {
if (is.not.array(response)) {
response = [];
}
let pins = Ember.ArrayProxy.create({
content: Ember.A([])
});
pins = response.map((pin) => {
let data = this.get('store').normalize('pin', pin);
return this.get('store').push(data);
});
this.set('pins', pins);
return pins;
});
}
},
isDocumentPinned(documentId) {
let userId = this.get('session.user.id');
if (this.get('initialized') === false) {
this.getUserPins().then(() => {
let pins = this.get('pins');
let pinId = '';
pins.forEach((pin) => {
if (pin.get('userId') === userId && pin.get('documentId') === documentId) {
pinId = pin.get('id');
}
});
return pinId;
});
} else {
let pins = this.get('pins');
let pinId = '';
pins.forEach((pin) => {
if (pin.get('userId') === userId && pin.get('documentId') === documentId) {
pinId = pin.get('id');
}
});
return pinId;
}
},
isSpacePinned(spaceId) {
let userId = this.get('session.user.id');
let pins = this.get('pins');
let pinId = '';
pins.forEach((pin) => {
if (pin.get('userId') === userId && pin.get('documentId') === '' && pin.get('folderId') === spaceId) {
pinId = pin.get('id');
}
});
return pinId;
}
});

View file

@ -0,0 +1,30 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
// getUsers returns all users for organization.
find(keywords) {
let url = "search?keywords=" + encodeURIComponent(keywords);
return this.get('ajax').request(url, {
method: "GET"
});
},
});

135
gui/app/services/section.js Normal file
View file

@ -0,0 +1,135 @@
// 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 BaseService from '../services/base';
const {
inject: { service }
} = Ember;
export default BaseService.extend({
sessionService: service('session'),
ajax: service(),
store: service(),
// Returns all available sections.
getAll() {
return this.get('ajax').request(`sections`, {
method: 'GET'
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('section', obj);
return this.get('store').push(data);
});
return data;
});
},
// Requests data from the specified section handler, passing the method and document ID
// and POST payload.
fetch(page, method, data) {
let documentId = page.get('documentId');
let section = page.get('contentType');
let url = `sections?documentID=${documentId}&section=${section}&method=${method}`;
return this.get('ajax').post(url, {
data: JSON.stringify(data),
contentType: "application/json"
});
},
// Did any dynamic sections change? Fetch and send up for rendering?
refresh(documentId) {
let url = `sections/refresh?documentID=${documentId}`;
return this.get('ajax').request(url, {
method: 'GET'
}).then((response) => {
let pages = [];
if (is.not.null(response) && is.array(response) && response.length > 0) {
pages = response.map((page) => {
let data = this.get('store').normalize('page', page);
return this.get('store').push(data);
});
}
return pages;
}).catch((/*error*/) => {
// we ignore any error to cater for anon users who don't
// have permissions to perform refresh
});
},
/**************************************************
* Reusable Content Blocks
**************************************************/
// Save new reusable content block.
addBlock(payload) {
let url = `sections/blocks`;
return this.get('ajax').post(url, {
data: JSON.stringify(payload),
contentType: 'json'
}).then((response) => {
let data = this.get('store').normalize('block', response);
return this.get('store').push(data);
});
},
// Returns reusable content block.
getBlock(blockId) {
return this.get('ajax').request(`sections/blocks/${blockId}`, {
method: 'GET'
}).then((response) => {
let data = this.get('store').normalize('block', response);
return this.get('store').push(data);
});
},
// Returns all available reusable content block for section.
getSpaceBlocks(folderId) {
return this.get('ajax').request(`sections/blocks/space/${folderId}`, {
method: 'GET'
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('block', obj);
return this.get('store').push(data);
});
return data;
});
},
// Returns reusable content block.
updateBlock(block) {
return this.get('ajax').request(`sections/blocks/${block.id}`, {
method: 'PUT',
data: JSON.stringify(block)
});
},
// Removes specified reusable content block.
deleteBlock: function (blockId) {
let url = `sections/blocks/${blockId}`;
return this.get('ajax').request(url, {
method: 'DELETE'
});
}
});

View file

@ -0,0 +1,71 @@
// 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 SimpleAuthSession from 'ember-simple-auth/services/session';
const {
inject: { service },
computed
} = Ember;
export default SimpleAuthSession.extend({
ajax: service(),
appMeta: service(),
store: service(),
localStorage: service(),
folderPermissions: null,
currentFolder: null,
isMac: false,
isMobile: false,
hasAccounts: computed('isAuthenticated', 'session.content.authenticated.user', function() {
return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.accounts').length > 0;
}),
accounts: computed('hasAccounts', function() {
return this.get('session.content.authenticated.user.accounts');
}),
user: computed('isAuthenticated', 'session.content.authenticated.user', function () {
if (this.get('isAuthenticated')) {
let user = this.get('session.content.authenticated.user') || { id: '0' };
let data = this.get('store').normalize('user', user);
return this.get('store').push(data);
}
}),
authenticated: computed('session.content.authenticated.user', function () {
return this.get('session.authenticator') !== 'authenticator:anonymous' && this.get('session.content.authenticated.user.id') !== '0';
}),
isAdmin: computed('session.content.authenticated.user', function () {
return this.get('session.authenticator') !== 'authenticator:anonymous' &&
this.get('session.content.authenticated.user.id') !== '0' &&
this.get('session.content.authenticated.user.admin') === true;
}),
isEditor: computed('session.content.authenticated.user', function () {
return this.get('session.authenticator') !== 'authenticator:anonymous' &&
this.get('session.content.authenticated.user.id') !== '0' &&
this.get('session.content.authenticated.user.editor') === true;
}),
isGlobalAdmin: computed('session.content.authenticated.user', function () {
return this.get('session.authenticator') !== 'authenticator:anonymous' &&
this.get('session.content.authenticated.user.id') !== '0' &&
this.get('session.content.authenticated.user.global') === true;
}),
init() {
this._super(...arguments);
this.set('isMac', is.mac());
this.set('isMobile', is.mobile());
},
logout() {
this.get('localStorage').clearAll();
}
});

View file

@ -0,0 +1,81 @@
// 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';
const {
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
store: service(),
importStockTemplate: function (folderId, templateId) {
let url = `templates/${templateId}/folder/${folderId}?type=stock`;
return this.get('ajax').request(url, {
method: "POST"
});
},
importSavedTemplate: function (folderId, templateId, docName) {
let url = `templates/${templateId}/folder/${folderId}?type=saved`;
return this.get('ajax').request(url, {
method: 'POST',
data: docName
}).then((doc) => {
let data = this.get('store').normalize('document', doc);
return this.get('store').push(data);
});
},
getSavedTemplates() {
return this.get('ajax').request(`templates`, {
method: 'GET'
}).then((response) => {
if (is.not.array(response)) {
response = [];
}
let templates = Ember.ArrayProxy.create({
content: Ember.A([])
});
templates = response.map((template) => {
let data = this.get('store').normalize('template', template);
return this.get('store').push(data);
});
return templates;
});
},
getStockTemplates() {
return this.get('ajax').request(`templates/stock`, {
method: 'GET'
});
},
saveAsTemplate(documentId, name, excerpt) {
let payload = {
DocumentID: documentId,
Name: name,
Excerpt: excerpt
};
return this.get('ajax').request(`templates`, {
method: 'POST',
data: JSON.stringify(payload)
}).then(() => {});
}
});

View file

@ -0,0 +1,33 @@
// 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';
/**
* This is a work around problems that tether introduces into testing.
* TODO: remove this code and refactor in favour of ember-tether
*/
export default Ember.Service.extend({
createDrop() {
if (Ember.testing) {
return;
}
return new Drop(...arguments);
},
createTooltip() {
if (Ember.testing) {
return;
}
return new Tooltip(...arguments);
}
});

153
gui/app/services/user.js Normal file
View file

@ -0,0 +1,153 @@
// 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';
const {
isEmpty,
RSVP,
inject: { service }
} = Ember;
export default Ember.Service.extend({
sessionService: service('session'),
ajax: service(),
store: service(),
// Adds a new user.
add(user) {
return this.get('ajax').request(`users`, {
type: 'POST',
data: JSON.stringify(user),
contentType: 'json'
}).then((response) => {
let data = this.get('store').normalize('user', response);
return this.get('store').push(data);
});
},
// Returns user model for specified user id.
getUser(userId) {
let url = `users/${userId}`;
return this.get('ajax').request(url, {
type: 'GET'
}).then((response) => {
let data = this.get('store').normalize('user', response);
return this.get('store').push(data);
});
},
// Returns all active users for organization.
getAll() {
return this.get('ajax').request(`users?active=1`).then((response) => {
return response.map((obj) => {
let data = this.get('store').normalize('user', obj);
return this.get('store').push(data);
});
});
},
// Returns all active and inactive users for organization.
getComplete() {
return this.get('ajax').request(`users?active=0`).then((response) => {
return response.map((obj) => {
let data = this.get('store').normalize('user', obj);
return this.get('store').push(data);
});
});
},
// Returns all users that can see folder.
getFolderUsers(folderId) {
let url = `users/folder/${folderId}`;
return this.get('ajax').request(url, {
method: "GET"
}).then((response) => {
let data = [];
data = response.map((obj) => {
let data = this.get('store').normalize('user', obj);
return this.get('store').push(data);
});
return data;
});
},
// Updates an existing user record.
save(user) {
let userId = user.id;
let url = `users/${userId}`;
return this.get('ajax').request(url, {
type: 'PUT',
data: JSON.stringify(user),
contentType: 'json'
});
},
// updatePassword changes the password for the specified user.
updatePassword(userId, password) {
let url = `users/${userId}/password`;
return this.get('ajax').post(url, {
data: password
});
},
// Removes the specified user.
remove(userId) {
let url = `users/${userId}`;
return this.get('ajax').request(url, {
method: 'DELETE'
}).then(() => {
let user = this.get('store').peekRecord('user', `${userId}`);
return user.deleteRecord();
});
},
// Request password reset.
forgotPassword(email) {
let url = `public/forgot`;
if (isEmpty(email)) {
return RSVP.reject("invalid");
}
let data = JSON.stringify({
email: email
});
return this.get('ajax').request(url, {
method: 'POST',
dataType: 'json',
data: data
});
},
// Set new password.
resetPassword(token, password) {
var url = `public/reset/${token}`;
if (isEmpty(token) || isEmpty(password)) {
return RSVP.reject("invalid");
}
return this.get('ajax').request(url, {
method: "POST",
data: password
});
}
});